Skip to content

Commit

Permalink
Reverse top-level Flows in supertype
Browse files Browse the repository at this point in the history
Summary:
Although we accumulate provenance on the subtype during subtyping, we actually record typing time provenance on both types so the supertype may be a `Flow`.  In this case we actually want the inner most element of the flow rather than the outer most (which is what we want for the subtype)

This diff adds a function to reverse top-level flows and applies it to the supertype when rendering a subtyping error.

Reviewed By: madgen

Differential Revision: D63900892

fbshipit-source-id: 2c2034476c2ae0b5e68c01622f18bb9de8ecf090
  • Loading branch information
Michael Thomas authored and facebook-github-bot committed Oct 7, 2024
1 parent 6cdb6c9 commit a57dfd6
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 69 deletions.
3 changes: 2 additions & 1 deletion hphp/hack/src/typing/typing_error_utils.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5821,7 +5821,8 @@ end = struct
(ty_super_descr, ty_sub_descr)
in
let left =
Typing_reason.to_string ("Expected " ^ ty_super_descr) r_super
Typing_reason.to_string ("Expected " ^ ty_super_descr)
@@ Typing_reason.reverse_flow r_super
in
let right = Typing_reason.to_string ("But got " ^ ty_sub_descr) r_sub in
let reasons = left @ right in
Expand Down
8 changes: 8 additions & 0 deletions hphp/hack/src/typing/typing_reason.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2063,6 +2063,14 @@ let rec flow_contains_tyvar = function
| Flow { into; _ } -> flow_contains_tyvar into
| _ -> false

let reverse_flow t =
let rec aux ~k = function
| Flow { from; into; kind } ->
aux into ~k:(fun into -> k @@ Flow { from = into; into = from; kind })
| t -> k t
in
aux ~k:(fun r -> r) t

(* Translate a reason to a (pos, string) list, suitable for error_l. This
* previously returned a string, however the need to return multiple lines with
* multiple locations meant that it needed to more than convert to a string *)
Expand Down
2 changes: 2 additions & 0 deletions hphp/hack/src/typing/typing_reason.mli
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ type decl_t = decl_phase t_

val localize : decl_t -> t

val reverse_flow : t -> t

(** Translate a reason to a (pos, string) list, suitable for error_l. This
previously returned a string, however the need to return multiple lines with
multiple locations meant that it needed to more than convert to a string *)
Expand Down
16 changes: 8 additions & 8 deletions hphp/hack/test/extended_reasons/bad_inout_lvalue9.php.debug.exp
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,14 @@ File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:
6 | f(inout »tuple($x, $y)«);
7 | }

Expected `(int, int)` because the type of this inout parameter is implicitly a like-type
Expected `(int, int)`

File "bad_inout_lvalue9.php", line 3, character 30 - line 3, character 31:
File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:

3 | function f(inout varray<int> »$a«): void {}
3 | function f(inout varray<int> $a): void {}
4 |
5 | function test(int $x, int $y): void {
6 | f(inout tuple($x, $y));
6 | f(inout »tuple($x, $y)«);
7 | }

But got `vec<int>`
Expand Down Expand Up @@ -285,14 +285,14 @@ File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:
6 | f(inout »tuple($x, $y)«);
7 | }

Expected `(int, int)` because the type of this inout parameter is implicitly a like-type
Expected `(int, int)`

File "bad_inout_lvalue9.php", line 3, character 30 - line 3, character 31:
File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:

3 | function f(inout varray<int> »$a«): void {}
3 | function f(inout varray<int> $a): void {}
4 |
5 | function test(int $x, int $y): void {
6 | f(inout tuple($x, $y));
6 | f(inout »tuple($x, $y)«);
7 | }

But got `dynamic` because the type of this inout parameter is implicitly a like-type
Expand Down
36 changes: 0 additions & 36 deletions hphp/hack/test/extended_reasons/bad_inout_lvalue9.php.diff.exp
Original file line number Diff line number Diff line change
@@ -1,36 +0,0 @@
--- control

+++ test

@@ -20,20 +20,20 @@

7 | }

error: Typing[4110] Invalid argument to an inout parameter [1]
--> Expected (int, int) [1]
--> But got vec<int> [2]
+-> Expected (int, int) because the type of this inout parameter is implicitly a like-type [2]
+-> But got vec<int> [3]

hphp/hack/test/extended_reasons/bad_inout_lvalue9.php:6:11
- 1 | <?hh
- 2 |
-[2] 3 | function f(inout varray<int> $a): void {}
- 4 |
- 5 | function test(int $x, int $y): void {
-[1] 6 | f(inout tuple($x, $y));
- 7 | }
+ 1 | <?hh
+ 2 |
+[2,3] 3 | function f(inout varray<int> $a): void {}
+ 4 |
+ 5 | function test(int $x, int $y): void {
+[1] 6 | f(inout tuple($x, $y));
+ 7 | }

error: Typing[4110] Invalid argument to an inout parameter [1]
--> Expected (int, int) [1]
+-> Expected (int, int) because the type of this inout parameter is implicitly a like-type [2]
-> But got dynamic because the type of this inout parameter is implicitly a like-type [2]

hphp/hack/test/extended_reasons/bad_inout_lvalue9.php:6:11
16 changes: 8 additions & 8 deletions hphp/hack/test/extended_reasons/bad_inout_lvalue9.php.exp
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,14 @@ File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:
6 | f(inout »tuple($x, $y)«);
7 | }

Expected `(int, int)` because the type of this inout parameter is implicitly a like-type
Expected `(int, int)`

File "bad_inout_lvalue9.php", line 3, character 30 - line 3, character 31:
File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:

3 | function f(inout varray<int> »$a«): void {}
3 | function f(inout varray<int> $a): void {}
4 |
5 | function test(int $x, int $y): void {
6 | f(inout tuple($x, $y));
6 | f(inout »tuple($x, $y)«);
7 | }

But got `vec<int>`
Expand Down Expand Up @@ -205,14 +205,14 @@ File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:
6 | f(inout »tuple($x, $y)«);
7 | }

Expected `(int, int)` because the type of this inout parameter is implicitly a like-type
Expected `(int, int)`

File "bad_inout_lvalue9.php", line 3, character 30 - line 3, character 31:
File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:

3 | function f(inout varray<int> »$a«): void {}
3 | function f(inout varray<int> $a): void {}
4 |
5 | function test(int $x, int $y): void {
6 | f(inout tuple($x, $y));
6 | f(inout »tuple($x, $y)«);
7 | }

But got `dynamic` because the type of this inout parameter is implicitly a like-type
Expand Down
16 changes: 8 additions & 8 deletions hphp/hack/test/extended_reasons/bad_inout_lvalue9.php.terse.exp
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,14 @@ File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:
6 | f(inout »tuple($x, $y)«);
7 | }

Expected `(int, int)` because the type of this inout parameter is implicitly a like-type
Expected `(int, int)`

File "bad_inout_lvalue9.php", line 3, character 30 - line 3, character 31:
File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:

3 | function f(inout varray<int> »$a«): void {}
3 | function f(inout varray<int> $a): void {}
4 |
5 | function test(int $x, int $y): void {
6 | f(inout tuple($x, $y));
6 | f(inout »tuple($x, $y)«);
7 | }

But got `vec<int>`
Expand Down Expand Up @@ -187,14 +187,14 @@ File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:
6 | f(inout »tuple($x, $y)«);
7 | }

Expected `(int, int)` because the type of this inout parameter is implicitly a like-type
Expected `(int, int)`

File "bad_inout_lvalue9.php", line 3, character 30 - line 3, character 31:
File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:

3 | function f(inout varray<int> »$a«): void {}
3 | function f(inout varray<int> $a): void {}
4 |
5 | function test(int $x, int $y): void {
6 | f(inout tuple($x, $y));
6 | f(inout »tuple($x, $y)«);
7 | }

But got `dynamic` because the type of this inout parameter is implicitly a like-type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,14 @@ File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:
6 | f(inout »tuple($x, $y)«);
7 | }

Expected `(int, int)` because the type of this inout parameter is implicitly a like-type
Expected `(int, int)`

File "bad_inout_lvalue9.php", line 3, character 30 - line 3, character 31:
File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:

3 | function f(inout varray<int> »$a«): void {}
3 | function f(inout varray<int> $a): void {}
4 |
5 | function test(int $x, int $y): void {
6 | f(inout tuple($x, $y));
6 | f(inout »tuple($x, $y)«);
7 | }

But got `vec<int>`
Expand Down Expand Up @@ -205,14 +205,14 @@ File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:
6 | f(inout »tuple($x, $y)«);
7 | }

Expected `(int, int)` because the type of this inout parameter is implicitly a like-type
Expected `(int, int)`

File "bad_inout_lvalue9.php", line 3, character 30 - line 3, character 31:
File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:

3 | function f(inout varray<int> »$a«): void {}
3 | function f(inout varray<int> $a): void {}
4 |
5 | function test(int $x, int $y): void {
6 | f(inout tuple($x, $y));
6 | f(inout »tuple($x, $y)«);
7 | }

But got `dynamic` because the type of this inout parameter is implicitly a like-type
Expand Down

0 comments on commit a57dfd6

Please sign in to comment.