Do not report undefined property in isset/empty/?? for types without class names#5673
Closed
phpstan-bot wants to merge 1 commit into
Closed
Do not report undefined property in isset/empty/?? for types without class names#5673phpstan-bot wants to merge 1 commit into
phpstan-bot wants to merge 1 commit into
Conversation
…class names When checkDynamicProperties is enabled, PHPStan incorrectly reported "Access to an undefined property" for chained isset() checks on mixed types. After the first isset() narrows mixed to object&hasProperty(foo), the second isset($tmp->bar) was being flagged because pickProperty returned null for the intersection type that has no concrete class names. The fix skips the dynamic property check when the type has no class names (bare object or object&hasProperty), since we cannot know what properties such a type might have. Closes phpstan/phpstan#13539
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.
Closes phpstan/phpstan#13539
When
checkDynamicPropertiesis enabled (e.g. via phpstan-strict-rules), PHPStan incorrectly reported "Access to an undefined property" for chainedisset()checks on mixed types.The scenario:
The first
isset($tmp->foo)narrowsmixedtoobject&hasProperty(foo). In the falsey branch (where we evaluate the right side of||), the secondisset($tmp->bar)triggersAccessPropertiesCheckwhich callspickPropertyon anIntersectionType(ObjectWithoutClassType, HasPropertyType(foo)). Since this type has no concrete class names,pickPropertyreturnsnull, and the code treated that as "property definitely doesn't exist" — reporting a false positive.The fix adds a check: when the type has no class names (bare
object,object&hasProperty(...)) we skip the dynamic property check in isset/empty/?? context, since we cannot know what properties such a type might have. For concrete classes, the existing behavior is preserved.This also fixes the related bug #13529 which had a test expecting the buggy behavior.
!isset($tmp->foo) || !isset($tmp->bar)isset($tmp->foo, $tmp->bar)isset($tmp->foo) && isset($tmp->bar)$tmp->bar ?? nullafter issetempty($tmp->bar)after isset#[AllowDynamicProperties]