Gate the change from
D15279318 by the new_inference flag
Summary:
Despite my effort to preserve the behavior in successful cases,
D15279318 led to new errors under the legacy inference in the code that previously would type check. For example:
```
<?hh // strict
// Copyright 2004-present Facebook. All Rights Reserved.
interface I {}
abstract class A<T as I> {
public function __construct(?T $_) {}
}
class B<T as I> extends A<T> {
<<__Override>>
public function __construct(?T $x = null) {
parent::__construct($x);
}
}
```
At some point, we need to check the constraint `(<expr#1> as ?T) <: ?v` where `v` is a fresh type variable used to instantiate `T` in the definition of `A`. This simplifies to `(?T <: ?v) | (<expr#1> as ?T) <: v`, which further simplifies to `(T <: v | I <: v) | (<expr#1> as ?T) <: v`. However, due to how the smart constructor for disjunction is implemented:
diffusion/FBS/browse/master/fbcode/hphp/hack/src/typing/typing_logic.ml;
fdaefe04b722d52573d2bd0ad2760a653dc85705$103-113
when this disjunction is flattened the disjuncts get rearranged and we end up with `(<expr#1> as ?T) <: v | T <: v | I <: v`, so that we first check `(<expr#1> as ?T) <: v`, which under the legacy inference succeeds and we commit to this choice, but it later (when we performed the delayed constraint check) causes type errors.
To avoid dealing with this now, I'm proposing to gate this change by the `new_inference` flag. This means that under the legacy inference the code that type checks continues to type check, but there are examples that fail to type check under the legacy but are accepted by the new inference.
Reviewed By: andrewjkennedy
Differential Revision:
D15295389
fbshipit-source-id:
6e06ee00ac0c97e41f95fddbb55ad16ae37271e3