Instantiate constructor tparams if they exist
commit339be3b821b87699bcc86ce9f60c93a83166d62f
authorVassil Mladenov <vmladenov@fb.com>
Mon, 21 Dec 2020 13:08:06 +0000 (21 05:08 -0800)
committerFacebook GitHub Bot <facebook-github-bot@users.noreply.github.com>
Mon, 21 Dec 2020 13:09:49 +0000 (21 05:09 -0800)
tree32a143d26ca0553067ee7086042d461e2365002c
parente940c9dbcf799f71904212d198cd539cd86799c9
Instantiate constructor tparams if they exist

Summary:
Rewriting for effect polymorphism introduces non-denotable type parameters on functions. Type parameters are currently banned on constructor definitions, because the type argument list in a `new` expression is used to parametrize the class.

I've loosened the restriction to allow type parameters that start with `T$` (i.e. non-denotable) and create fresh type variables for them. Then the constructor call is checked as any other function call. Here's a minor visualization of what's happening.

```
class C<T as A> {
  public function __construct(T $a)[$a::C]: void {}
}

== rewrite ==>

class C<T as A> {
  public function __construct<T$a@C>(T $a)[$a::C]: void where T$a@C = T::C {}
}

== elsewhere ==>

new C<B>($b);

== interpreted as ==>

new C<B><_>($b);

    ^^^^    (class targs)

        ^^^ (constructor targs)
```

Reviewed By: DavidSnider, losvald

Differential Revision: D25632044

fbshipit-source-id: 55b890787dcf0997f6b48d031d2b991ec82b1ff0
hphp/hack/src/parser/lowerer/lowerer.rs
hphp/hack/src/parser/rust_parser_errors.rs
hphp/hack/src/typing/typing.ml
hphp/hack/test/typecheck/coeffects/poly_var_constructor.php [new file with mode: 0644]
hphp/hack/test/typecheck/coeffects/poly_var_constructor.php.exp [new file with mode: 0644]
hphp/hack/test/typecheck/generic_constructor.php.exp