Refinement with `instanceof` and generic unions is unsound
- Dominant language
- Rust
- Stars
- 22.3k
- Forks
- 1.9k
- PR merge metrics
- No merged PRs in 30d
Description
If `x: T | MyClass`, then Flow infers from `x instanceof MyClass`
that `x: MyClass`. This is unsound: `T` could be `MyClass` for
some other `U`, so that in fact `x: MyClass>`.
[Here is an example of how this can go wrong:][1]
```js
// @flow
class Box {
+field: T;
constructor(x) {
this.field = x;
}
}
function asBox(x: T | Box): Box {
if (x instanceof Box) {
// Here, `x` is refined to be `Box`. This is unsound: `T` could
// well be `Box` for some other `U`. Example below.
return x;
} else {
// whatever
return new Box(x);
}
}
const stringStringBox: Box> = asBox(new Box("wat")); // unsound!
stringStringBox.field.field.substr(0); // runtime error
```
[1]: https://flow.org/try/#0PTAEAEDMBsHsHcBQBjaBDAzh0AhWAPAHgBUA+UAb0VFAGpIBLAU2gBMAuUYgbmtGVgA7DABcATgFdkI2GIAU+AJSU+NEQAsGGAHSMWrUAF5Q+XjQC+iS4kgTB0hkNCY8RMgs7FQAH1wESpIqcrgEqNAyQoAqgDMIiaPZMsJGuylQ0NCCgABJMYkwANKAABvjFMdj5jIJMBjKgAEZMJSFkxdpcmthaoHYYsHYcJcTlAhJsqqBZ8CzQjc3FIQCqpOWQsqD9ALbNsBp5JUvtoACi+GhbAA7QzU1w8NqT+SISYoImZqDmoCwYzekZabqNAiJgANzyTyYLzeoBq8D8+AUik+lmsAjim3EsQA5gBlbGCHGuYL+EKiMS40jkYwuAhyeGIuQAIngIOZihRmTAfQGglYAEJEBTcQTKUTXLpmGwpfptBgJA0KXIAAxcqZgSSCEQMHY-MRiWSIIA
Contributor guide
Assessment
This issue has not been assessed yet.