Fix phpstan/phpstan#9455: Bug: False report Cannot call method getId() on A|null#5447
Open
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
Open
Fix phpstan/phpstan#9455: Bug: False report Cannot call method getId() on A|null#5447phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
Cannot call method getId() on A|null#5447phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
Conversation
…d boolean variable for method calls - Added MethodCall and StaticCall to allowed expression types in processSureTypesForConditionalExpressionsAfterAssign and processSureNotTypesForConditionalExpressionsAfterAssign - New regression test in tests/PHPStan/Analyser/nsrt/bug-9455.php - The root cause was that conditional expression holders were not created for method call results when assigned to a boolean variable
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.
Summary
When a null check on a method call result was stored in a boolean variable (e.g.,
$hasA = $b->getA() !== null), and that variable was later used in anifcondition, PHPStan failed to narrow the type of$b->getA()inside the branch. The inline equivalent (if ($b->getA() !== null)) worked correctly.Changes
MethodCallandExpr\StaticCallto the allowed expression types inprocessSureTypesForConditionalExpressionsAfterAssign()andprocessSureNotTypesForConditionalExpressionsAfterAssign()insrc/Analyser/ExprHandler/AssignHandler.phptests/PHPStan/Analyser/nsrt/bug-9455.phpRoot cause
When PHPStan processes an assignment like
$hasA = $b->getA() !== null, it createsConditionalExpressionHolderobjects that record type narrowing to apply when the assigned variable is later used in a condition. However, the methodsprocessSureTypesForConditionalExpressionsAfterAssignandprocessSureNotTypesForConditionalExpressionsAfterAssignonly allowedVariable,PropertyFetch,ArrayDimFetch, andFuncCallexpressions to create these holders —MethodCallandStaticCallwere filtered out. This meant that type narrowing from method call null checks (like$b->getA() !== null) was never stored and thus never applied when the boolean variable was checked.Test
The regression test verifies that
$b->getA()is correctly narrowed toBug9455\A(notBug9455\A|null) inside anif ($hasA)block where$hasA = $b->getA() !== null.Fixes phpstan/phpstan#9455