Skip to content

Commit 5deffe3

Browse files
Michael Thomasfacebook-github-bot
authored andcommitted
Move reason construction to inference env
Summary: When we solve a type variable we record this fact in the provenance of the type letting us keep track of both where the type variable originally came from and the flow of the type through typing. This diff moves the place where we modify the reason from `Typing_env` to `Typing_inference_env` since `get_type` is the fundamental function in which we are getting solutions for type variables and moving the logic there eliminates the possibility of subtle provenance bugs Reviewed By: andrewjkennedy Differential Revision: D63749779 fbshipit-source-id: a7170046f6e21aea8632abc13f51a85120d3d182
1 parent ede6355 commit 5deffe3

File tree

11 files changed

+35
-43
lines changed

11 files changed

+35
-43
lines changed

hphp/hack/src/typing/env/typing_env.ml

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -91,23 +91,6 @@ let log_env_change name ?(level = 1) old_env new_env =
9191

9292
let expand_var env r v =
9393
let (inference_env, ty_solution) = Inf.expand_var env.inference_env r v in
94-
(* When we have a concrete solution r, record the flow of that solution as a
95-
prefix to the original type variables's reason; when we linearize the
96-
path, we should then see the path of the relevant uppper / lower bounds
97-
as the prefix for any flow through typing.
98-
We don't record the flow when we are pointing at another tyvar on the
99-
heap since we would end up with a chain of flows representing unification
100-
*)
101-
let ty_solution =
102-
if
103-
(not (is_tyvar ty_solution))
104-
&& TypecheckerOptions.using_extended_reasons env.genv.tcopt
105-
then
106-
map_reason ty_solution ~f:(fun solution ->
107-
Typing_reason.(solved v ~solution ~in_:r))
108-
else
109-
ty_solution
110-
in
11194
({ env with inference_env }, ty_solution)
11295

11396
let fresh_type_reason ?variance env p r =
@@ -268,10 +251,7 @@ let get_type env r var =
268251
let expand_type env ty =
269252
match deref ty with
270253
| (reason, Tvar tvid) -> expand_var env reason tvid
271-
| _ ->
272-
(* If this expansion was applied to a concrete type, don't modify the
273-
reason *)
274-
(env, ty)
254+
| _ -> (env, ty)
275255

276256
let expand_internal_type env ty =
277257
match ty with

hphp/hack/src/typing/typing_inference_env.ml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ let add env ?(tyvar_pos = Pos.none) v ty =
292292
let env = update_tyvar_occurrences env v ty in
293293
env
294294

295-
let get_type env r v =
295+
let get_type env reason_in tvid_in =
296296
let rec get r v aliases =
297297
let shorten_paths () =
298298
Tvid.Set.fold (fun v' env -> add env v' (mk (r, Tvar v))) aliases env
@@ -307,6 +307,16 @@ let get_type env r v =
307307
"Two type variables are aliasing each other!";
308308
get r v' (Tvid.Set.add v aliases)
309309
| _ ->
310+
(* When we have a concrete solution r, record the flow of that solution as a
311+
prefix to the original type variables's reason; when report in an error
312+
we should then see the path of the relevant uppper / lower bounds
313+
as the prefix for any flow through typing.
314+
We don't record the flow when we are pointing at another tyvar on the
315+
heap since we would end up with a chain of flows representing unification *)
316+
let ty =
317+
map_reason ty ~f:(fun solution ->
318+
Typing_reason.(solved tvid_in ~solution ~in_:reason_in))
319+
in
310320
let env = shorten_paths () in
311321
(env, ty)
312322
end
@@ -315,7 +325,7 @@ let get_type env r v =
315325
let env = shorten_paths () in
316326
(env, mk (r, Tvar v))
317327
in
318-
get r v Tvid.Set.empty
328+
get reason_in tvid_in Tvid.Set.empty
319329

320330
let create_tyvar_constraints variance =
321331
let (appears_covariantly, appears_contravariantly) =

hphp/hack/src/typing/typing_reason.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2233,8 +2233,8 @@ let rec to_string : type a. string -> a t_ -> (Pos_or_decl.t * string) list =
22332233
^ (strip_ns class_name |> Markdown_lite.md_codify)
22342234
^ " must match exactly (it is invariant)" );
22352235
]
2236-
(* If type originated with an unannotated lambda parameter with type variable type,
2237-
* suggested annotating the lambda parameter. Otherwise defer to original reason. *)
2236+
(* If type originated with an unannotated lambda parameter with type variable type,
2237+
* suggested annotating the lambda parameter. Otherwise defer to original reason. *)
22382238
| Lambda_param
22392239
( _,
22402240
( From_witness_decl (Solve_fail _)

hphp/hack/test/typecheck/aktuple/unify_error1.php.exp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ ERROR: File "unify_error1.php", line 13, characters 12-16:
22
Invalid argument (Typing[4110])
33
File "unify_error1.php", line 3, characters 19-21:
44
Expected `int`
5-
File "unify_error1.php", line 8, characters 14-14:
5+
File "unify_error1.php", line 10, characters 14-17:
66
But got `num`
77
ERROR: File "unify_error1.php", line 13, characters 12-16:
88
Invalid argument (Typing[4110])

hphp/hack/test/typecheck/aktuple/unify_error2.php.exp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ ERROR: File "unify_error2.php", line 13, characters 14-18:
22
Invalid argument (Typing[4110])
33
File "unify_error2.php", line 3, characters 21-25:
44
Expected `float`
5-
File "unify_error2.php", line 8, characters 14-14:
5+
File "unify_error2.php", line 10, characters 14-17:
66
But got `num`
77
ERROR: File "unify_error2.php", line 13, characters 14-18:
88
Invalid argument (Typing[4110])

hphp/hack/test/typecheck/aktuple/unify_error3.php.exp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ ERROR: File "unify_error3.php", line 13, characters 12-16:
22
Invalid argument (Typing[4110])
33
File "unify_error3.php", line 3, characters 19-21:
44
Expected `int`
5-
File "unify_error3.php", line 8, characters 14-14:
5+
File "unify_error3.php", line 10, characters 14-17:
66
But got `num`
77
ERROR: File "unify_error3.php", line 13, characters 12-16:
88
Invalid argument (Typing[4110])

hphp/hack/test/typecheck/aktuple/unify_ok.php.exp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ ERROR: File "unify_ok.php", line 15, characters 15-19:
88
Invalid argument (Typing[4110])
99
File "unify_ok.php", line 4, characters 22-27:
1010
Expected `string`
11-
File "unify_ok.php", line 9, characters 14-14:
11+
File "unify_ok.php", line 11, characters 14-17:
1212
But got `num`

hphp/hack/test/typecheck/constraints/classmeth_constraints_bad.php.exp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
ERROR: File "classmeth_constraints_bad.php", line 11, characters 6-6:
2-
Invalid argument (Typing[4323])
3-
File "classmeth_constraints_bad.php", line 6, characters 34-34:
4-
`T` is a constrained type parameter
5-
File "classmeth_constraints_bad.php", line 6, characters 39-42:
6-
This type constraint is violated
2+
Invalid argument (Typing[4110])
73
File "classmeth_constraints_bad.php", line 6, characters 39-42:
84
Expected `Base`
95
File "classmeth_constraints_bad.php", line 11, characters 6-6:

hphp/hack/test/typecheck/new_inference/eager_solve/stack_overflow_array.php.exp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,55 @@ File "stack_overflow_array.php", line 25, characters 3-13:
22
dict<int, (bool | dict<string, dict<int, dict<(string | _ | _ | _), (_ | _ | _ | (nonnull & (_ | _)) | dict<nothing, nothing>)>>>)>
33
ERROR: File "stack_overflow_array.php", line 15, characters 3-13:
44
This is not an object of type `KeyedContainer`, this is a bool or an object of type dict<nothing, nothing> (Typing[4324])
5-
File "stack_overflow_array.php", line 12, characters 17-21:
5+
File "stack_overflow_array.php", line 14, characters 14-19:
66
Definition is here
77
ERROR: File "stack_overflow_array.php", line 15, characters 3-24:
88
This is not an object of type `KeyedContainer`, this is a bool (Typing[4370])
99
File "stack_overflow_array.php", line 12, characters 17-21:
1010
Definition is here
1111
ERROR: File "stack_overflow_array.php", line 16, characters 3-13:
1212
This is not an object of type `KeyedContainer`, this is a bool or an object of type dict<string, ((_ & nonnull) | dict<nothing, nothing>)> (Typing[4324])
13-
File "stack_overflow_array.php", line 12, characters 17-21:
13+
File "stack_overflow_array.php", line 14, characters 14-19:
1414
Definition is here
1515
ERROR: File "stack_overflow_array.php", line 16, characters 3-28:
1616
This is not an object of type `KeyedContainer`, this is a bool (Typing[4370])
1717
File "stack_overflow_array.php", line 12, characters 17-21:
1818
Definition is here
1919
ERROR: File "stack_overflow_array.php", line 17, characters 3-13:
2020
This is not an object of type `KeyedContainer`, this is a bool or an object of type dict<string, dict<int, ((_ & nonnull) | dict<nothing, nothing>)>> (Typing[4324])
21-
File "stack_overflow_array.php", line 12, characters 17-21:
21+
File "stack_overflow_array.php", line 14, characters 14-19:
2222
Definition is here
2323
ERROR: File "stack_overflow_array.php", line 17, characters 3-13:
2424
This is not an object of type `KeyedContainer`, this is a bool or an object of type dict<string, dict<int, dict<nothing, nothing>>> (Typing[4324])
25-
File "stack_overflow_array.php", line 12, characters 17-21:
25+
File "stack_overflow_array.php", line 14, characters 14-19:
2626
Definition is here
2727
ERROR: File "stack_overflow_array.php", line 17, characters 3-33:
2828
This is not an object of type `KeyedContainer`, this is a bool (Typing[4370])
2929
File "stack_overflow_array.php", line 12, characters 17-21:
3030
Definition is here
3131
ERROR: File "stack_overflow_array.php", line 20, characters 3-13:
3232
This is not an object of type `KeyedContainer`, this is a bool or an object of type dict<string, dict<int, dict<(string | _), (_ | (_ & nonnull) | dict<nothing, nothing>)>>> (Typing[4324])
33-
File "stack_overflow_array.php", line 12, characters 17-21:
33+
File "stack_overflow_array.php", line 14, characters 14-19:
3434
Definition is here
3535
ERROR: File "stack_overflow_array.php", line 20, characters 3-24:
3636
This is not an object of type `KeyedContainer`, this is a bool (Typing[4370])
3737
File "stack_overflow_array.php", line 12, characters 17-21:
3838
Definition is here
3939
ERROR: File "stack_overflow_array.php", line 21, characters 3-13:
4040
This is not an object of type `KeyedContainer`, this is a bool or an object of type dict<string, ((nonnull & _) | dict<int, dict<(string | _), (_ | (_ & nonnull) | dict<nothing, nothing>)>>)> (Typing[4324])
41-
File "stack_overflow_array.php", line 12, characters 17-21:
41+
File "stack_overflow_array.php", line 14, characters 14-19:
4242
Definition is here
4343
ERROR: File "stack_overflow_array.php", line 21, characters 3-28:
4444
This is not an object of type `KeyedContainer`, this is a bool (Typing[4370])
4545
File "stack_overflow_array.php", line 12, characters 17-21:
4646
Definition is here
4747
ERROR: File "stack_overflow_array.php", line 22, characters 3-13:
4848
This is not an object of type `KeyedContainer`, this is a bool or an object of type dict<string, dict<int, ((_ & nonnull) | dict<(string | _), (_ | (_ & nonnull) | dict<nothing, nothing>)>)>> (Typing[4324])
49-
File "stack_overflow_array.php", line 12, characters 17-21:
49+
File "stack_overflow_array.php", line 14, characters 14-19:
5050
Definition is here
5151
ERROR: File "stack_overflow_array.php", line 22, characters 3-13:
5252
This is not an object of type `KeyedContainer`, this is a bool or an object of type dict<string, dict<int, ((dict<_, _> & nonnull) | dict<(string | _), (_ | (_ & nonnull) | dict<nothing, nothing>)>)>> (Typing[4324])
53-
File "stack_overflow_array.php", line 12, characters 17-21:
53+
File "stack_overflow_array.php", line 14, characters 14-19:
5454
Definition is here
5555
ERROR: File "stack_overflow_array.php", line 22, characters 3-33:
5656
This is not an object of type `KeyedContainer`, this is a bool (Typing[4370])

hphp/hack/test/typecheck/readonly/call.php.exp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ This function is readonly, so it must be marked readonly at declaration time to
99
ERROR: File "call.php", line 29, characters 4-12:
1010
This function is readonly, so it must be marked readonly at declaration time to be called. (Typing[4428])
1111
File "call.php", line 4, characters 10-27:
12-
Did you mean to annotate this typehint as a (readonly function(): void)?
12+
Did you mean to declaring this as a `readonly` function?

0 commit comments

Comments
 (0)