Skip to content

Commit a57dfd6

Browse files
Michael Thomasfacebook-github-bot
authored andcommitted
Reverse top-level Flows in supertype
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
1 parent 6cdb6c9 commit a57dfd6

8 files changed

+44
-69
lines changed

hphp/hack/src/typing/typing_error_utils.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5821,7 +5821,8 @@ end = struct
58215821
(ty_super_descr, ty_sub_descr)
58225822
in
58235823
let left =
5824-
Typing_reason.to_string ("Expected " ^ ty_super_descr) r_super
5824+
Typing_reason.to_string ("Expected " ^ ty_super_descr)
5825+
@@ Typing_reason.reverse_flow r_super
58255826
in
58265827
let right = Typing_reason.to_string ("But got " ^ ty_sub_descr) r_sub in
58275828
let reasons = left @ right in

hphp/hack/src/typing/typing_reason.ml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2063,6 +2063,14 @@ let rec flow_contains_tyvar = function
20632063
| Flow { into; _ } -> flow_contains_tyvar into
20642064
| _ -> false
20652065

2066+
let reverse_flow t =
2067+
let rec aux ~k = function
2068+
| Flow { from; into; kind } ->
2069+
aux into ~k:(fun into -> k @@ Flow { from = into; into = from; kind })
2070+
| t -> k t
2071+
in
2072+
aux ~k:(fun r -> r) t
2073+
20662074
(* Translate a reason to a (pos, string) list, suitable for error_l. This
20672075
* previously returned a string, however the need to return multiple lines with
20682076
* multiple locations meant that it needed to more than convert to a string *)

hphp/hack/src/typing/typing_reason.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ type decl_t = decl_phase t_
8080

8181
val localize : decl_t -> t
8282

83+
val reverse_flow : t -> t
84+
8385
(** Translate a reason to a (pos, string) list, suitable for error_l. This
8486
previously returned a string, however the need to return multiple lines with
8587
multiple locations meant that it needed to more than convert to a string *)

hphp/hack/test/extended_reasons/bad_inout_lvalue9.php.debug.exp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,14 @@ File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:
135135
6 | f(inout »tuple($x, $y)«);
136136
7 | }
137137

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

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

142-
3 | function f(inout varray<int> »$a«): void {}
142+
3 | function f(inout varray<int> $a): void {}
143143
4 |
144144
5 | function test(int $x, int $y): void {
145-
6 | f(inout tuple($x, $y));
145+
6 | f(inout »tuple($x, $y)«);
146146
7 | }
147147

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

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

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

292-
3 | function f(inout varray<int> »$a«): void {}
292+
3 | function f(inout varray<int> $a): void {}
293293
4 |
294294
5 | function test(int $x, int $y): void {
295-
6 | f(inout tuple($x, $y));
295+
6 | f(inout »tuple($x, $y)«);
296296
7 | }
297297

298298
But got `dynamic` because the type of this inout parameter is implicitly a like-type
Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +0,0 @@
1-
--- control
2-
3-
+++ test
4-
5-
@@ -20,20 +20,20 @@
6-
7-
7 | }
8-
9-
error: Typing[4110] Invalid argument to an inout parameter [1]
10-
--> Expected (int, int) [1]
11-
--> But got vec<int> [2]
12-
+-> Expected (int, int) because the type of this inout parameter is implicitly a like-type [2]
13-
+-> But got vec<int> [3]
14-
15-
hphp/hack/test/extended_reasons/bad_inout_lvalue9.php:6:11
16-
- 1 | <?hh
17-
- 2 |
18-
-[2] 3 | function f(inout varray<int> $a): void {}
19-
- 4 |
20-
- 5 | function test(int $x, int $y): void {
21-
-[1] 6 | f(inout tuple($x, $y));
22-
- 7 | }
23-
+ 1 | <?hh
24-
+ 2 |
25-
+[2,3] 3 | function f(inout varray<int> $a): void {}
26-
+ 4 |
27-
+ 5 | function test(int $x, int $y): void {
28-
+[1] 6 | f(inout tuple($x, $y));
29-
+ 7 | }
30-
31-
error: Typing[4110] Invalid argument to an inout parameter [1]
32-
--> Expected (int, int) [1]
33-
+-> Expected (int, int) because the type of this inout parameter is implicitly a like-type [2]
34-
-> But got dynamic because the type of this inout parameter is implicitly a like-type [2]
35-
36-
hphp/hack/test/extended_reasons/bad_inout_lvalue9.php:6:11

hphp/hack/test/extended_reasons/bad_inout_lvalue9.php.exp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,14 @@ File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:
106106
6 | f(inout »tuple($x, $y)«);
107107
7 | }
108108

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

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

113-
3 | function f(inout varray<int> »$a«): void {}
113+
3 | function f(inout varray<int> $a): void {}
114114
4 |
115115
5 | function test(int $x, int $y): void {
116-
6 | f(inout tuple($x, $y));
116+
6 | f(inout »tuple($x, $y)«);
117117
7 | }
118118

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

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

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

212-
3 | function f(inout varray<int> »$a«): void {}
212+
3 | function f(inout varray<int> $a): void {}
213213
4 |
214214
5 | function test(int $x, int $y): void {
215-
6 | f(inout tuple($x, $y));
215+
6 | f(inout »tuple($x, $y)«);
216216
7 | }
217217

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

hphp/hack/test/extended_reasons/bad_inout_lvalue9.php.terse.exp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,14 @@ File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:
9797
6 | f(inout »tuple($x, $y)«);
9898
7 | }
9999

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

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

104-
3 | function f(inout varray<int> »$a«): void {}
104+
3 | function f(inout varray<int> $a): void {}
105105
4 |
106106
5 | function test(int $x, int $y): void {
107-
6 | f(inout tuple($x, $y));
107+
6 | f(inout »tuple($x, $y)«);
108108
7 | }
109109

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

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

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

194-
3 | function f(inout varray<int> »$a«): void {}
194+
3 | function f(inout varray<int> $a): void {}
195195
4 |
196196
5 | function test(int $x, int $y): void {
197-
6 | f(inout tuple($x, $y));
197+
6 | f(inout »tuple($x, $y)«);
198198
7 | }
199199

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

hphp/hack/test/extended_reasons/bad_inout_lvalue9.php.verbose.exp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,14 @@ File "bad_inout_lvalue9.php", line 6, character 11 - line 6, character 23:
106106
6 | f(inout »tuple($x, $y)«);
107107
7 | }
108108

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

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

113-
3 | function f(inout varray<int> »$a«): void {}
113+
3 | function f(inout varray<int> $a): void {}
114114
4 |
115115
5 | function test(int $x, int $y): void {
116-
6 | f(inout tuple($x, $y));
116+
6 | f(inout »tuple($x, $y)«);
117117
7 | }
118118

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

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

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

212-
3 | function f(inout varray<int> »$a«): void {}
212+
3 | function f(inout varray<int> $a): void {}
213213
4 |
214214
5 | function test(int $x, int $y): void {
215-
6 | f(inout tuple($x, $y));
215+
6 | f(inout »tuple($x, $y)«);
216216
7 | }
217217

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

0 commit comments

Comments
 (0)