Record variable definedness as conditional expressions - #6384
Open
ondrejmirtes wants to merge 4 commits into
Open
Record variable definedness as conditional expressions#6384ondrejmirtes wants to merge 4 commits into
ondrejmirtes wants to merge 4 commits into
Conversation
…l on the assigned boolean When a boolean && / || RHS contains an assignment inside an operand, a truthy && (or falsey ||) result guarantees every short-circuit operand was evaluated. Diff the RHS walk's truthy/falsey continuation scope against the merged after-RHS scope for variables whose certainty is Yes there but only Maybe after the merge, and record conditional expression holders so that narrowing the assigned variable later restores the certainty and type. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CGhnJQpUWRRpg6H5LuWJkA
…g undefined At a try/catch join where the catch variable is untracked on the non-catch path and certainly defined at the end of the catch body, its later definedness tells the joined paths apart. Record conditional expression holders with a certainty-No (and, for scopes where any variable can exist, a maybe-defined-null) condition on the catch variable, restoring the non-catch certainty and type of variables the join demoted to maybe-defined. To let such holders fire, the isset()-style falsey specification in MutatingScope::applySpecifiedTypes() now publishes the certainty change into the specified-expressions batch - rescuing the waiting holders around unsetExpression()'s invalidation, which would otherwise drop them at the very specification they wait for. A second catch clause merging into the join drops the holders via the conditional-expressions intersection, so multi-catch stays conservative. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CGhnJQpUWRRpg6H5LuWJkA
The definedness-holder changes added three `(string)` casts on array keys documented as strings - load-bearing under strict_types because numeric-string keys become ints at runtime. Suppress them inline like ScopeOps does instead of growing the baseline counts. Also sort the TryCatchHandler imports. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CGhnJQpUWRRpg6H5LuWJkA
`$var .= '<single constant string>'` used to invalidate every conditional-expression holder mentioning $var, so a format string built across `if (!empty($target))` lost its correlation with $target and a later `empty($target)` re-check could not select the matching string. Appending a fixed suffix is injective, so holders whose target or condition on $var is a single constant string are remapped through the append instead; everything else still falls back to invalidation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CGhnJQpUWRRpg6H5LuWJkA
Collaborator
|
You've opened the pull request against the latest branch 2.3.x. PHPStan 2.3 is not going to be released for months. If your code is relevant on 2.2.x and you want it to be released sooner, please rebase your pull request and change its target to 2.2.x. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Records variable definedness — not only type — as conditional expressions in three cases:
if ($bool)later restores the variable's certainty.!isset($e)restores them.$s .= '<constant>'now remaps the holders that target$sthrough the concatenation instead of invalidating them.Regression tests added; the full
NodeScopeResolverTeststays green and a local issue-bot run confirms the three fixes with no regressions.Closes phpstan/phpstan#11109
Closes phpstan/phpstan#6608
Closes phpstan/phpstan#9854
🤖 Generated with Claude Code