Commit bdf955d
Fix ErrorType leaking from array_key_exists with union key types in loops
When array_key_exists() was called with a union constant key type (e.g.,
'c1'|'c2') on an empty array inside a loop, the NonEmptyArrayType
narrowing was skipped due to a count(getConstantScalarTypes()) <= 1
guard. This caused the isIterableAtLeastOnce()->no() early return to
produce empty SpecifiedTypes, leaving the array typed as array{} even
in the true branch. Subsequent access to $arr[$key] on the empty array
type produced ErrorType, which propagated through loop iterations and
eventually caused false "Unable to resolve template type" errors when
the array was passed to generic functions like array_values().
The fix removes the <= 1 guard so NonEmptyArrayType narrowing always
applies when array_key_exists returns true, which is semantically
correct regardless of key type.
Closes phpstan/phpstan#144891 parent 77a3244 commit bdf955d
3 files changed
Lines changed: 56 additions & 12 deletions
File tree
- src/Type/Php
- tests/PHPStan
- Analyser/nsrt
- Rules/Arrays
Lines changed: 9 additions & 11 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
89 | | - | |
90 | | - | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
91 | 89 | | |
92 | 90 | | |
93 | 91 | | |
| |||
| 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 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
419 | 419 | | |
420 | 420 | | |
421 | 421 | | |
422 | | - | |
| 422 | + | |
423 | 423 | | |
424 | 424 | | |
425 | 425 | | |
| |||
0 commit comments