Properly localize require ancestors in Typing_subtype
commita9dd4a70b482a91350439fc0b68f63b27b075830
authorDwayne Reeves <dreeves@fb.com>
Sat, 30 Jul 2016 17:32:53 +0000 (30 10:32 -0700)
committerHhvm Bot <hhvm-bot-bot@fb.com>
Sat, 30 Jul 2016 17:36:43 +0000 (30 10:36 -0700)
tree9bb2fbe034144f9804df29d7e633adf619469f6b
parent7a33eea2e9abe4b409c8c6ec57030dd0fc83ddf6
Properly localize require ancestors in Typing_subtype

Summary:
We did not properly substitute type parameters when upcasing to a required ancestor. This diff fixes this by making sure we create the `ety_env` the same for both branches of our upcasting algorithm. In order to avoid unnecessary error reporting I hade to make the creation of `ety_env` lazy.

The added test case shows how it arises.

```
abstract class Expression<Tresult> {}
abstract class Evaluator<T, Texpression as Expression<T>> {}

class LiteralEvaluator<T, Texpression as ILiteralExpression<T>>
  extends Evaluator<T, Texpression> {}

interface ILiteralExpression<TlitResult> {
  require extends Expression<TlitResult>;
}
```

Here when we are checking if `ILiteralExpression<T> <: Expression<T>` we utilize the require extends to upcast `ILiteralExpression` to `Expression`. Before the diff we would not instantiate the type parameter correctly so we would end up checking `Expression<TlitResult> <: Expression<T>` which would fail because `TlitResult` and `T` are different generics. Note taht if `TlitResult` was named `T` then it would pass because now the type parameters have the same name, even though the type parameter was not properly instantiated.

{D2613160} revealed this particular issue because now with scoping we can tell that `ILiteralExpression\T` is different than `LiteralEvaluator\T`.

Reviewed By: andrewjkennedy

Differential Revision: D3561665

fbshipit-source-id: 907ecaaabb9eff63a4e8e4d38bc01137ac023f4c
hphp/hack/src/typing/typing_subtype.ml
hphp/hack/test/typecheck/req_ancestor_with_generics.php [new file with mode: 0644]
hphp/hack/test/typecheck/req_ancestor_with_generics.php.exp [new file with mode: 0644]