Commit b0ee6d3
Fix phpstan/phpstan#12597: Variable might not be undefined after in_array check
When `in_array($type, [TYPE_1, TYPE_2], true)` narrows `$type` to a union
like `1|2` and a variable is assigned inside that block, a conditional
expression is created with guard type `1|2`. Later, when `$type === TYPE_1`
narrows to just `1`, the conditional didn't match because `equals()` requires
exact type equality.
Fix: In `filterBySpecifiedTypes`, allow conditional expression guards to match
when the specified type is a strict subtype of a finite union guard type. This
enables `$type = 1` to match the guard `$type = 1|2`, correctly resolving the
variable as defined.
The subtype matching is restricted to:
- Guards with >1 finite types (union of constants/literals)
- Both guard and specified having YES certainty
- The conditional's type holder having YES certainty (prevents matching stale
"undefined" conditionals from earlier scope merges)
- Matches don't cascade (not added to specifiedExpressions) to prevent mutual
conditional loops from corrupting type information1 parent fd42dc7 commit b0ee6d3
File tree
4 files changed
+59
-8
lines changed- src/Analyser
- tests/PHPStan
- Analyser/nsrt
- Rules/Variables
- data
4 files changed
+59
-8
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3217 | 3217 | | |
3218 | 3218 | | |
3219 | 3219 | | |
| 3220 | + | |
3220 | 3221 | | |
3221 | | - | |
| 3222 | + | |
3222 | 3223 | | |
3223 | 3224 | | |
| 3225 | + | |
| 3226 | + | |
| 3227 | + | |
| 3228 | + | |
| 3229 | + | |
| 3230 | + | |
| 3231 | + | |
| 3232 | + | |
| 3233 | + | |
| 3234 | + | |
| 3235 | + | |
| 3236 | + | |
| 3237 | + | |
| 3238 | + | |
| 3239 | + | |
3224 | 3240 | | |
3225 | 3241 | | |
3226 | 3242 | | |
| 3243 | + | |
| 3244 | + | |
| 3245 | + | |
| 3246 | + | |
3227 | 3247 | | |
3228 | 3248 | | |
3229 | 3249 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
63 | | - | |
| 63 | + | |
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
67 | | - | |
68 | | - | |
| 67 | + | |
| 68 | + | |
69 | 69 | | |
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
73 | 73 | | |
74 | 74 | | |
75 | | - | |
76 | | - | |
| 75 | + | |
| 76 | + | |
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
83 | | - | |
| 83 | + | |
84 | 84 | | |
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
88 | 88 | | |
89 | 89 | | |
90 | 90 | | |
91 | | - | |
| 91 | + | |
92 | 92 | | |
93 | 93 | | |
94 | 94 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1476 | 1476 | | |
1477 | 1477 | | |
1478 | 1478 | | |
| 1479 | + | |
| 1480 | + | |
| 1481 | + | |
| 1482 | + | |
| 1483 | + | |
| 1484 | + | |
| 1485 | + | |
| 1486 | + | |
| 1487 | + | |
1479 | 1488 | | |
1480 | 1489 | | |
1481 | 1490 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
0 commit comments