Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mixed refined to an array produces a read-only array, which breaks a lot of existing code. #7684

Closed
lxe opened this issue Apr 30, 2019 · 4 comments
Labels

Comments

@lxe
Copy link

lxe commented Apr 30, 2019

Flow version: 0.98

https://flow.org/try/#0GYVwdgxgLglg9mABMOcAUBDAXIgggJ3wwE8AeAWxgA8BTAEwD4BKRAb0QF8AoL0SWBIgBGGfGjg5KtOi1ZdEiGMERoCRYgDoYAZzUlxTWfIXJUBgNzHuHIA

function foo(a: Array<mixed>) { }

function bar(o: mixed) {
  if (Array.isArray(o)) { // There's no way to dynamically refine to a $ReadOnlyArray
    foo(o);
  }
}

Expected behavior

No Errors

Actual behavior

5:     foo(o);
           ^ Cannot call `foo` with `o` bound to `a` because read-only array type [1] is incompatible with array type [2].
References:
3: function bar(o: mixed) {
                   ^ [1]
1: function foo(a: Array<mixed>) { }
                   ^ [2]

What was the practical rationale behind this change?

@goodmind goodmind added regression Seems to have worked before, but is broken now (issue has mention of last working version) and removed needs triage labels May 1, 2019
@goodmind
Copy link
Contributor

goodmind commented May 1, 2019

5639532

@goodmind goodmind removed the regression Seems to have worked before, but is broken now (issue has mention of last working version) label May 1, 2019
@goodmind
Copy link
Contributor

goodmind commented May 1, 2019

@dsainati1

@dsainati1
Copy link
Contributor

dsainati1 commented May 1, 2019

This is the same logic behind #7685. Writing to an array refined from mixed is trivially unsound, as you can see in this example:

function bad(array: mixed) {
  if (Array.isArray(array)) {
    const problem: Array<mixed> = array;
    problem[1] = 0;
  }
}

bad((["3"] : Array<string>));

@lxe
Copy link
Author

lxe commented May 6, 2019

I don't really know what "unsound" means, but if I have a mixed the types of its properties should be understood at both reading (refinements) and writing (assignments).

If I'm doing let a:mixed = {}; a.foo = 'string' it should be fine, but then if later I do a.foo ++ flow should tell me that I'm wrong.

I think you're sacrificing practicality and usefulness of Flow in the name of "soundness"

lydell added a commit to lydell/tiny-decoders that referenced this issue Jun 7, 2019
See these Flow issues for explanation:

- facebook/flow#7684
- facebook/flow#7685

This is a breaking change.

Fixes #3.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants