Commit 6297472
committed
fix(semantic): reuse branch-narrowed types in expression inference
Flow narrowing sometimes has to evaluate another expression that uses a
value narrowed earlier in the same branch. For example, after `key =
"foo"`, `t[key]` should be checked with `key` as `"foo"`, not with its
declared `"foo"|"bar"` type.
The old fallback avoided recursive flow analysis by evaluating those
expressions without flow. That kept the engine from re-entering itself,
but it also lost precision in assignment RHS expressions, equality
checks, field guards, dynamic table keys, and guarded call or callee
aliases.
This keeps the flow engine responsible for the ordering. It records work
that depends on another expression, resolves the branch-local values
first, then resumes the original expression with those values layered
over the normal no-flow inputs. Static caches and declared/member types
still apply, but temporary expression and call results do not leak into
the normal no-flow caches. Values that cannot be evaluated safely
without flow now return no answer instead of caching broad guesses.
Assignments are conservative. The RHS can still use branch-local values,
but the previous branch-narrowed source for the assignment target is
reused only when the new RHS is compatible with it. Otherwise the engine
falls back to the type before the current guard so stale branch
narrowing is dropped after overwrites.
The indexing changes share lookup data between normal index/table-field
lookup and `__index` fallback. Exact literal keys stay exact, broader
union/keyof/enum key types can expand to matching members, and broad
string or number keys still include nil when they may miss. Lookup paths
used for narrowing still avoid `__index`/operator fallback, so guards
only narrow through members that are present directly.
The call changes apply the same conservative rule to guarded calls and
callee aliases such as `rawget` and `pcall`. Non-string `require` paths
and `setmetatable` calls without real `__index`/custom metatable shapes
now decline in no-flow instead of guessing. Non-generic overloads keep
candidates alive when an argument cannot be evaluated without flow, but
such an argument cannot make an overload win unless the remaining
candidates return the same type.
Regression tests cover branch-narrowed dynamic keys in assignments,
initializers, comparisons, field truthiness, literal equality, stacked
guards, call/callee aliases, member lookup, `pcall`, and ambiguous
overload arguments. Existing assignment overwrite guardrails continue to
cover stale narrowing after overwrite.
Assisted-by: Codex1 parent 4ec26a1 commit 6297472
25 files changed
Lines changed: 2790 additions & 1416 deletions
File tree
- crates/emmylua_code_analysis/src
- compilation/test
- db_index/member
- semantic
- cache
- infer
- infer_call
- infer_index
- narrow
- condition_flow
- overload_resolve
Lines changed: 455 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 22 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
390 | 390 | | |
391 | 391 | | |
392 | 392 | | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
393 | 415 | | |
394 | 416 | | |
395 | 417 | | |
| |||
Lines changed: 25 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
176 | 176 | | |
177 | 177 | | |
178 | 178 | | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
179 | 204 | | |
180 | 205 | | |
181 | 206 | | |
| |||
Lines changed: 7 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
10 | 13 | | |
11 | 14 | | |
12 | 15 | | |
| |||
116 | 119 | | |
117 | 120 | | |
118 | 121 | | |
119 | | - | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
120 | 125 | | |
121 | 126 | | |
122 | 127 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
| 6 | + | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | 20 | | |
28 | 21 | | |
29 | 22 | | |
| |||
53 | 46 | | |
54 | 47 | | |
55 | 48 | | |
| 49 | + | |
56 | 50 | | |
| 51 | + | |
57 | 52 | | |
58 | 53 | | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
59 | 57 | | |
60 | 58 | | |
61 | 59 | | |
62 | 60 | | |
63 | | - | |
64 | 61 | | |
| 62 | + | |
65 | 63 | | |
66 | 64 | | |
67 | 65 | | |
| |||
72 | 70 | | |
73 | 71 | | |
74 | 72 | | |
| 73 | + | |
75 | 74 | | |
| 75 | + | |
76 | 76 | | |
| 77 | + | |
| 78 | + | |
77 | 79 | | |
78 | 80 | | |
79 | 81 | | |
80 | 82 | | |
81 | | - | |
82 | 83 | | |
| 84 | + | |
83 | 85 | | |
84 | 86 | | |
85 | 87 | | |
| |||
94 | 96 | | |
95 | 97 | | |
96 | 98 | | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
97 | 154 | | |
98 | 155 | | |
99 | 156 | | |
100 | 157 | | |
101 | 158 | | |
| 159 | + | |
102 | 160 | | |
| 161 | + | |
103 | 162 | | |
| 163 | + | |
| 164 | + | |
104 | 165 | | |
105 | 166 | | |
106 | 167 | | |
107 | 168 | | |
108 | | - | |
109 | 169 | | |
| 170 | + | |
110 | 171 | | |
111 | 172 | | |
| 173 | + | |
112 | 174 | | |
113 | 175 | | |
Lines changed: 7 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
17 | | - | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
18 | 23 | | |
19 | 24 | | |
20 | 25 | | |
| |||
Lines changed: 7 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
9 | | - | |
| 9 | + | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
25 | 31 | | |
26 | 32 | | |
27 | 33 | | |
| |||
Lines changed: 46 additions & 14 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
41 | | - | |
42 | | - | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
43 | 52 | | |
44 | | - | |
| 53 | + | |
45 | 54 | | |
46 | 55 | | |
47 | 56 | | |
48 | | - | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
49 | 64 | | |
50 | | - | |
51 | | - | |
52 | | - | |
| 65 | + | |
53 | 66 | | |
54 | 67 | | |
55 | 68 | | |
| |||
143 | 156 | | |
144 | 157 | | |
145 | 158 | | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
146 | 170 | | |
147 | | - | |
148 | | - | |
| 171 | + | |
| 172 | + | |
149 | 173 | | |
150 | 174 | | |
151 | | - | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
152 | 180 | | |
153 | 181 | | |
154 | | - | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
155 | 187 | | |
156 | 188 | | |
157 | 189 | | |
| |||
181 | 213 | | |
182 | 214 | | |
183 | 215 | | |
184 | | - | |
185 | 216 | | |
186 | 217 | | |
187 | 218 | | |
| |||
597 | 628 | | |
598 | 629 | | |
599 | 630 | | |
600 | | - | |
| 631 | + | |
601 | 632 | | |
602 | 633 | | |
603 | 634 | | |
| |||
721 | 752 | | |
722 | 753 | | |
723 | 754 | | |
724 | | - | |
| 755 | + | |
| 756 | + | |
725 | 757 | | |
726 | 758 | | |
727 | 759 | | |
| |||
0 commit comments