Skip to content

Do not let type narrowing define a certainly-undefined variable - #6130

Merged
ondrejmirtes merged 1 commit into
2.2.xfrom
narrowing-undefined-variables
Jul 28, 2026
Merged

Do not let type narrowing define a certainly-undefined variable#6130
ondrejmirtes merged 1 commit into
2.2.xfrom
narrowing-undefined-variables

Conversation

@ondrejmirtes

Copy link
Copy Markdown
Member

Extracted from the resolve-type-rewrite-2 branch (follows #6125 and #6129).

filterBySpecifiedTypes() created a type holder for a variable the scope knows is certainly undefined, making isset()-style narrowing "define" it — the classic false negative where only the first use of an undefined variable in a loop was reported. A sureNot specification now skips certainly-undefined variables; sure specifications still apply, since a condition like is_string($a) can only hold for a defined variable (one error at the test site, no cascade).

Verified test-first: the regression test fails on 2.2.x with the line-9 Undefined variable error missing and line 15 degraded to "might not be defined"; passes with the fix. Full test suite green (17757 tests), self-analysis clean, no other expectation changes.

Closes phpstan/phpstan#2032

🤖 Generated with Claude Code

https://claude.ai/code/session_019wqGgaD7iqL44t1KgpJS7b

Removing a type from a certainly-undefined variable proves nothing
about its definedness, so a sureNot specification must not create a
holder for it. A sure specification (e.g. is_string($a)) still can -
the condition can only hold for a defined variable, so it makes the
variable defined inside the branch: one error at the test site, no
cascade.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019wqGgaD7iqL44t1KgpJS7b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Confusing messaging for undefined variables in loops

1 participant