Destructuring of unions of tuples
Summary:
Currently we have a type hole associated with union types and tuple destructuring.
For example, Hack accepts the following:
```
function foo(bool $b): int {
if ($b) {
$a = tuple(42, 1);
} else {
$a = tuple('bar', 2);
}
list($x, $y) = $a;
return $x;
}
```
Just before the `list` assignment, `$a` has type `(int,int) | (string,int)`. So
Hack should infer type `int | string` for `$x` but currently gives it the "any"
type.
The fix is to generate fresh type variables `v1` ... `vn` for the types of the
elements of the tuple, and then force a subtype `ty <: tuple(v1, ..., vn)` where
`ty` is the type of the expression on the right-hand side of the assignment.
This works for ordinary tuples (but changes some error messages slightly) as well
as unions such as in the above example. (By the way, the above example is now
legal if the return type is set to `arraykey`.)
Reviewed By: dlreeves
Differential Revision:
D4014944
fbshipit-source-id:
14eed43f989b1db1b78553d649cfe07334b185ba