New inference: improved error message for unresolved type
commit27112678e649d527a28814bdcc9114402dbc0325
authorAndrew Kennedy <akenn@fb.com>
Tue, 14 May 2019 20:22:16 +0000 (14 13:22 -0700)
committerHhvm Bot <hhvm-bot@users.noreply.github.com>
Tue, 14 May 2019 20:28:02 +0000 (14 13:28 -0700)
treee73b5654fee9cc65401ee249fa80de1367a211e1
parent696fd10aea471c64f26f87ef3ac5147dc2eb1093
New inference: improved error message for unresolved type

Summary:
When Hack can't resolve a type for operations such as method invocation, it currently points the finger of blame at the use of a generic function or constructor that introduced the type variable. But often it's better to point the blame at an unannotated lambda. For example, with
```
function just_return_it<T>((function(T):void) $f):(function(T):void) { return $f; }

function break_it(string $ss):void {
  $g1 = just_return_it($y ==> $y->this_method_does_not_exist());
  $g2 = just_return_it($y ==> { $z = $y; $z->this_method_also_does_not_exist(); });
  $g1("hahahaha");
}
```
Instead of
```
Typing[4297] Was expecting an object but type is unknown
   --> lambda_tyvar.php
  4 | function just_return_it<T>((function(T):void) $f):(function(T):void) { return $f; }
    |                                      ^   via this generic T
  7 |   $g1 = just_return_it($y ==> $y->this_method_does_not_exist());
    |                               ^^
    |         ^^^^^^^^^^^^^^ It is unknown because type parameter T of just_return_it could not be determined. Please add type parameters to just_return_it.

Typing[4297] Was expecting an object but type is unknown
   --> lambda_tyvar.php
  4 | function just_return_it<T>((function(T):void) $f):(function(T):void) { return $f; }
    |                                      ^   via this generic T
  8 |   $g2 = just_return_it($y ==> { $z = $y; $z->this_method_also_does_not_exist(); });
    |                                          ^^
    |         ^^^^^^^^^^^^^^ It is unknown because type parameter T of just_return_it could not be determined. Please add type parameters to just_return_it.
```
we can produce the more useful
```
Typing[4297] Was expecting an object but type is unknown
   --> lambda_tyvar.php
  7 |   $g1 = just_return_it($y ==> $y->this_method_does_not_exist());
    |                               ^^
    |                        ^^ It is unknown because type of lambda parameter could not be determined. Please add type hint to parameter

Typing[4297] Was expecting an object but type is unknown
   --> lambda_tyvar.php
  8 |   $g2 = just_return_it($y ==> { $z = $y; $z->this_method_also_does_not_exist(); });
    |                                          ^^
    |                        ^^ It is unknown because type of lambda parameter could not be determined. Please add type hint to parameter
```
Also slightly improved the original message about type parameters.

Reviewed By: DavidSnider

Differential Revision: D15335592

fbshipit-source-id: d93cc1de7a951215339fb3c9f54179719997bac4
20 files changed:
hphp/hack/src/decl/decl_pos_utils.ml
hphp/hack/src/typing/typing.ml
hphp/hack/src/typing/typing_reason.ml
hphp/hack/test/typecheck/anon4.php.exp
hphp/hack/test/typecheck/functional_anon_fun.php.exp
hphp/hack/test/typecheck/lambda/lambda_legacy/lambda_two_uses.php.exp
hphp/hack/test/typecheck/lambda/new_map_lambda.php.exp
hphp/hack/test/typecheck/lambda/new_map_lambda.php.legacy.exp [new file with mode: 0644]
hphp/hack/test/typecheck/lambda/sort_by.php.exp
hphp/hack/test/typecheck/lambda/variadics/lambda_unpacked_parameters.php.exp
hphp/hack/test/typecheck/lambda/variadics/lambda_unpacked_parameters.php.legacy.exp
hphp/hack/test/typecheck/let/let_lambda_hof.php.exp
hphp/hack/test/typecheck/new_inference/eager_solve/function_apply_nothing.php.exp
hphp/hack/test/typecheck/new_inference/eager_solve/solve_nothing.php.exp
hphp/hack/test/typecheck/new_inference/expand_before_narrow.php.exp
hphp/hack/test/typecheck/new_inference/typehole/lambda_tyvar.php [new file with mode: 0644]
hphp/hack/test/typecheck/new_inference/typehole/lambda_tyvar.php.exp [new file with mode: 0644]
hphp/hack/test/typecheck/new_inference/typehole/lambda_tyvar.php.legacy.exp [new file with mode: 0644]
hphp/hack/test/typecheck/new_inference/typehole/lambda_with_invoke.php.exp
hphp/hack/test/typecheck/new_inference/unresolved_errors.php.exp