Improve typing of assignments to properties of unresolved objects, v2
commitab853726889f1ea9c65b010f880a1468efe8b596
authorSasha Manzyuk <manzyuk@fb.com>
Mon, 23 Jul 2018 12:07:39 +0000 (23 05:07 -0700)
committerHhvm Bot <hhvm-bot@users.noreply.github.com>
Mon, 23 Jul 2018 12:12:18 +0000 (23 05:12 -0700)
treed20b1c3de7a2d6e8ce644b2b9c3d7c062238ac40
parent6bb1af975097fc541af6077a1534c6a5445e6dc5
Improve typing of assignments to properties of unresolved objects, v2

Summary:
When type-checking an assignment of the form
```
$obj->prop = $val;
```
we type-check the left hand side, and in the case it has an unresolved type `(t1 | ... | tn)` we check that the type of `$val` is a subtype of each `ti`.  This is required for soundness because one way in which `$obj->prop` can have an unresolved type is when `$obj` itself has an unresolved type, e.g., `(C1 | ... | Cn)`, where `C1`, ..., `Cn` are classes having property named `prop` of types `t1`, ..., `tn` respectively.  However, this is not the only way in which `$obj->prop` can have an unresolved type.  Here is another example, which at the moment fails to type-check:
```
<?hh // strict
// Copyright 2004-present Facebook. All Rights Reserved.

class C<T> {
  public function __construct(public T $value) {}
}

function test(bool $b, int $x, float $y, num $z): void {
  if ($b) {
    $xory = $x;
  } else {
    $xory = $y;
  }
  $c = new C($xory);
  $c->value = $z;
}
```
Here `$c->value` has type `(int | float)`, but this type arises as an instantiation of a generic type of a single property, not as union of the types of different properties.  The above code should be valid but it is rejected by the type-checker.  One practical case in which this problem manifests itself is when we try to make `void` be the type of `null`, so that `?t` becomes equivalent to `t | void`.

This diff attempts to fix this problem.  It is a more principled fix than the one proposed in D8633124, and is more in line with the formal specification of assignment to properties (D8801786).  See inline comments below for a discussion of technical details.

Reviewed By: CatherineGasnier

Differential Revision: D8821525

fbshipit-source-id: be2c35a6916a1800e8138661c0e8bc2ab951eb51
hphp/hack/src/typing/typing.ml
hphp/hack/test/typecheck/assign_unresolved.php [new file with mode: 0644]
hphp/hack/test/typecheck/assign_unresolved.php.exp [new file with mode: 0644]
hphp/hack/test/typecheck/assign_unresolved_class_get.php [new file with mode: 0644]
hphp/hack/test/typecheck/assign_unresolved_class_get.php.exp [new file with mode: 0644]
hphp/hack/test/typecheck/assign_unresolved_obj_get.php [new file with mode: 0644]
hphp/hack/test/typecheck/assign_unresolved_obj_get.php.exp [new file with mode: 0644]
hphp/hack/test/typecheck/class_prop_as_this.php.exp
hphp/hack/test/typecheck/this_member.php.exp