Fix phpstan/phpstan#4560: Unexpected array shape error#5173
Open
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
Open
Fix phpstan/phpstan#4560: Unexpected array shape error#5173phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
Conversation
- When a mixed-typed variable has array offsets set (e.g. $data['token'] = value) and is later narrowed to an array type (e.g. via array_key_exists assert), the existing offset information from expression type holders is now incorporated into the narrowed array type - Added logic in MutatingScope::addTypeToExpression() to scan for existing ArrayDimFetch expression holders when a variable transitions from mixed to array - New regression test in tests/PHPStan/Analyser/nsrt/bug-4560.php Closes phpstan/phpstan#4560
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
mixed-typed variable (e.g. from$_POST) had array offsets explicitly set and was later narrowed to an array type via assertions likearray_key_exists, the offset information from the explicit assignments was lost. This caused PHPStan to report false positives about array shapes.Changes
MutatingScope::addTypeToExpression()insrc/Analyser/MutatingScope.phpto incorporate existing array offset expression type holders when a variable's type is narrowed frommixedto an array typetests/PHPStan/Analyser/nsrt/bug-4560.phpRoot cause
When
$dataismixedand$data['token'] = valueis executed,MixedType::setOffsetValueType()returnsmixedunchanged (by design, sincemixedcould be a string or other type). The offset information is tracked separately as an expression type holder for$data['token'].Later, when
assert(array_key_exists('password', $data))narrows$datafrommixedtoarray&hasOffset('password'), the narrowing did not check for existing expression type holders like$data['token']. So thehasOffset('token')information was lost from the final type.The fix adds a post-narrowing step in
addTypeToExpression(): when a variable transitions fromMixedTypeto an array type, it scans existing expression type holders forArrayDimFetchexpressions with constant keys on the same variable, and enriches the narrowed type withHasOffsetValueTypefor each found offset.Test
Added
tests/PHPStan/Analyser/nsrt/bug-4560.phpwhich reproduces the original issue: amixedvariable from$_POSTwith explicitly set['token']offset, then asserted viaarray_key_existsfor'password'and'email'keys. The test verifies that the resulting type includeshasOffsetValue('token', mixed)alongside thehasOffsettypes from the assertions.Fixes phpstan/phpstan#4560