Skip to content

Commit 1483deb

Browse files
SamChou19815meta-codesync[bot]
authored andcommitted
[flow] Suppress errors discovered during non-generic EvalT coming from type sig
Summary: For non-generic `EvalT`s coming from type sig, we should already have an corresponding error emitted while checking that file, since all non-generic `EvalT` annotations are eagarly evaluated. Therefore, we can just suppress these errors during checking. Later, when we move more generic EvalTs into the stuck eval system like D84003226, we can remove the non-generic EvalT check. It should be able to completely fix the misplaced error problem for `EvalT`, except for those `EvalT` that has issues exposed only after substitution. Changelog: [internal] Reviewed By: panagosg7 Differential Revision: D84390135 fbshipit-source-id: 9037db7a6ee0b89d3cedf43fd2336daee4136c74
1 parent efc80db commit 1483deb

8 files changed

Lines changed: 74 additions & 73 deletions

File tree

src/typing/flow_js.ml

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6309,21 +6309,47 @@ struct
63096309

63106310
and mk_type_destructor cx ~trace use_op reason t d id =
63116311
let evaluated = Context.evaluated cx in
6312-
let result =
6313-
match Eval.Map.find_opt id evaluated with
6314-
| Some cached_t -> cached_t
6315-
| None ->
6316-
Tvar.mk_no_wrap_where cx reason (fun tvar ->
6317-
Context.set_evaluated cx (Eval.Map.add id (OpenT tvar) evaluated);
6318-
evaluate_type_destructor cx ~trace use_op reason t d tvar
6319-
)
6320-
in
63216312
if
6322-
(not (Flow_js_utils.TvarVisitors.has_unresolved_tvars cx t))
6323-
&& not (Flow_js_utils.TvarVisitors.has_unresolved_tvars_in_destructors cx d)
6324-
then
6325-
Tvar_resolver.resolve cx result;
6326-
result
6313+
Eval.from_type_sig id
6314+
&& Subst_name.Set.is_empty
6315+
(Type_subst.free_var_finder
6316+
cx
6317+
(EvalT { type_ = t; defer_use_t = TypeDestructorT (use_op, reason, d); id })
6318+
)
6319+
then (
6320+
let result =
6321+
match Eval.Map.find_opt id evaluated with
6322+
| Some cached_t -> cached_t
6323+
| None ->
6324+
let trace = DepthTrace.dummy_trace in
6325+
Flow_js_utils.map_on_resolved_type cx reason t (fun t ->
6326+
Tvar_resolver.mk_tvar_and_fully_resolve_no_wrap_where cx reason (fun tvar ->
6327+
let errors = Context.errors cx in
6328+
let cache_snapshot = Context.take_cache_snapshot cx in
6329+
evaluate_type_destructor cx ~trace use_op reason t d tvar;
6330+
Context.restore_cache_snapshot cx cache_snapshot;
6331+
Context.reset_errors cx errors
6332+
)
6333+
)
6334+
in
6335+
Context.set_evaluated cx (Eval.Map.add id result evaluated);
6336+
result
6337+
) else
6338+
let result =
6339+
match Eval.Map.find_opt id evaluated with
6340+
| Some cached_t -> cached_t
6341+
| None ->
6342+
Tvar.mk_no_wrap_where cx reason (fun tvar ->
6343+
Context.set_evaluated cx (Eval.Map.add id (OpenT tvar) evaluated);
6344+
evaluate_type_destructor cx ~trace use_op reason t d tvar
6345+
)
6346+
in
6347+
if
6348+
(not (Flow_js_utils.TvarVisitors.has_unresolved_tvars cx t))
6349+
&& not (Flow_js_utils.TvarVisitors.has_unresolved_tvars_in_destructors cx d)
6350+
then
6351+
Tvar_resolver.resolve cx result;
6352+
result
63276353

63286354
and eval_destructor cx ~trace use_op reason t d tout =
63296355
match d with

src/typing/source_or_generated_id.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ let generate_id () = Generated (Reason.mk_id ())
5454

5555
let id_of_aloc_id ~type_sig aloc_id = Source { loc = aloc_id; type_sig }
5656

57+
let from_type_sig = function
58+
| Source { loc = _; type_sig } -> type_sig
59+
| Generated _ -> false
60+
5761
let string_of_id = function
5862
| Generated id -> string_of_int id
5963
| Source { type_sig; loc = id } ->

src/typing/source_or_generated_id.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ val equal_id : id -> id -> bool
1313

1414
val id_of_aloc_id : type_sig:bool -> ALoc.id -> id
1515

16+
val from_type_sig : id -> bool
17+
1618
val string_of_id : id -> string
1719

1820
val stable_string_of_id : id -> string

src/typing/type.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2266,6 +2266,8 @@ and Eval : sig
22662266

22672267
val id_of_aloc_id : type_sig:bool -> ALoc.id -> id
22682268

2269+
val from_type_sig : id -> bool
2270+
22692271
val string_of_id : id -> string
22702272

22712273
val generate_id : unit -> id

tests/incremental_eval_diff/incremental_eval_diff.exp

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,6 @@ References:
1313
^ [1]
1414

1515

16-
Error -------------------------------------------------------------------------------------------------------- a.js:8:17
17-
18-
null or undefined [1] is not an object. (FLOW BUG: This is a misplaced error. The original error was raised in file
19-
`b.js`). [not-an-object]
20-
21-
a.js:8:17
22-
8| export type A = $Values<T>;
23-
^^^^^^^^^^
24-
25-
References:
26-
a.js:8:25
27-
8| export type A = $Values<T>;
28-
^ [1]
29-
30-
3116
Error --------------------------------------------------------------------------------------------------------- b.js:6:2
3217

3318
Cannot cast `a` to object type because number [1] is incompatible with object type [2]. [incompatible-type]
@@ -50,4 +35,4 @@ References:
5035

5136

5237

53-
Found 3 errors
38+
Found 2 errors

tests/rec/rec.exp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ Invalid trivially recursive definition of `$Values`. [recursive-definition]
3434
^
3535

3636

37+
Error ------------------------------------------------------------------------------------- exported_eval_values.js:4:36
38+
39+
Invalid trivially recursive definition of `$Values`. . (FLOW BUG: This is a misplaced error. The original error was
40+
raised in file `eval_values.js`) [recursive-definition]
41+
42+
v------------------------
43+
4| export opaque type Value: number = $Values< // error: cyclic
44+
5| typeof options,
45+
6| >;
46+
^
47+
48+
3749
Error ------------------------------------------------------------------------------------ exported_eval_values.js:14:22
3850

3951
Invalid trivially recursive definition of `$Values`. [recursive-definition]
@@ -562,4 +574,4 @@ Invalid trivially recursive definition of `T3`. [recursive-definition]
562574

563575

564576

565-
Found 34 errors
577+
Found 35 errors
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Bad, Obj2 } from "./exported_bad_evalt";
22

33
declare const bad: Bad;
4-
bad.get() as Obj2; // error: TODO should not error here, since annotation error should be non-speculative
5-
bad.get(1) as Obj2; // error: TODO spurious incompatible with empty
4+
bad.get() as Obj2; // only subtyping error
5+
bad.get(1) as Obj2; // ok

tests/speculation_errors/speculation_errors.exp

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,18 @@
1-
Error -------------------------------------------------------------------------------- bad_interaction_with_evalt.js:4:5
1+
Error -------------------------------------------------------------------------------- bad_interaction_with_evalt.js:4:1
22

3-
Cannot call `bad.get` because: [incompatible-type]
4-
- Either cannot access `Obj2` [1] with computed property using string [2].
5-
- Or function type [3] requires another argument from call of method `get` [4].
3+
Cannot cast `bad.get()` to `Obj2` because null [1] is incompatible with `Obj2` [2]. [incompatible-type]
64

7-
bad_interaction_with_evalt.js:4:5
8-
4| bad.get() as Obj2; // error: TODO should not error here, since annotation error should be non-speculative
9-
^^^
10-
11-
References:
12-
exported_bad_evalt.js:8:21
13-
8| export type Bad = C<Obj2[string]>;
14-
^^^^ [1]
15-
exported_bad_evalt.js:8:26
16-
8| export type Bad = C<Obj2[string]>;
17-
^^^^^^ [2]
18-
exported_bad_evalt.js:3:3
19-
3| get(v: T): T;
20-
^^^^^^^^^^^^ [3]
215
bad_interaction_with_evalt.js:4:1
22-
4| bad.get() as Obj2; // error: TODO should not error here, since annotation error should be non-speculative
23-
^^^^^^^^^ [4]
24-
25-
26-
Error -------------------------------------------------------------------------------- bad_interaction_with_evalt.js:5:5
27-
28-
Cannot call `bad.get` because: [incompatible-type]
29-
- Either number [1] is incompatible with empty [2].
30-
- Or no arguments are expected by function type [3].
31-
32-
bad_interaction_with_evalt.js:5:5
33-
5| bad.get(1) as Obj2; // error: TODO spurious incompatible with empty
34-
^^^
6+
4| bad.get() as Obj2; // only subtyping error
7+
^^^^^^^^^
358

369
References:
37-
bad_interaction_with_evalt.js:5:9
38-
5| bad.get(1) as Obj2; // error: TODO spurious incompatible with empty
39-
^ [1]
40-
exported_bad_evalt.js:8:21
41-
8| export type Bad = C<Obj2[string]>;
42-
^^^^^^^^^^^^ [2]
43-
exported_bad_evalt.js:2:3
10+
exported_bad_evalt.js:2:14
4411
2| get(): T | null;
45-
^^^^^^^^^^^^^^^ [3]
12+
^^^^ [1]
13+
bad_interaction_with_evalt.js:4:14
14+
4| bad.get() as Obj2; // only subtyping error
15+
^^^^ [2]
4616

4717

4818
Error ------------------------------------------------------------------------------------- errors_intersection.js:13:13
@@ -3942,7 +3912,7 @@ References:
39423912

39433913

39443914

3945-
Found 186 errors
3915+
Found 185 errors
39463916

39473917
Only showing the most relevant union/intersection branches.
39483918
To see all branches, re-run Flow with --show-all-branches

0 commit comments

Comments
 (0)