Fix #14124: Reassigning to array<string, list<T>> out parameter does not see the list<T> property during assignment#4999
Open
phpstan-bot wants to merge 1 commit into2.1.xfrom
Open
Conversation
- Pass correctly computed valueToWrite type to VariableAssignNode instead of the assignedPropertyExpr expression tree which loses list types on nested array dimension assignments - The assignedPropertyExpr uses setOffsetValueType for non-outermost dims, losing AccessoryArrayListType, while produceArrayDimFetchAssignValueToWrite correctly uses setExistingOffsetValueType via cross-paired dim fetch checks - New regression test in tests/PHPStan/Rules/Variables/data/bug-14124.php Closes phpstan/phpstan#14124
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 function has a
@param-out array<string, list<string>>parameter and reassigns values via nested array dimension assignment ($convert[$outerKey][$key] = strtoupper($val)), PHPStan incorrectly reported aparamOut.typeerror because it saw the type asnon-empty-array<string, array<int<0, max>, string>>instead of preserving thelist<string>inner type.Changes
VariableAssignNodecallback in theArrayDimFetchassignment handling ofsrc/Analyser/NodeScopeResolver.php(lines 6300, 6317) to passnew TypeExpr($valueToWrite)instead of$assignedPropertyExprtests/PHPStan/Rules/Variables/data/bug-14124.phpand test method intests/PHPStan/Rules/Variables/ParameterOutAssignedTypeRuleTest.phpRoot cause
When processing nested array dim assignments like
$convert[$outerKey][$key] = expr, two separate type computations occur:produceArrayDimFetchAssignValueToWrite— correctly uses cross-paired dim fetch expressions to determine when to callsetExistingOffsetValueTypevssetOffsetValueType, preserving list types$assignedPropertyExprexpression tree (built in the while loop) — only usesSetExistingOffsetValueTypeExprfor the outermost dim fetch ($var === $originalVar), falling back toSetOffsetValueTypeExprfor inner dimsThe
ParameterOutAssignedTypeRuleevaluates the$assignedPropertyExprtree via$scope->getType($node->getAssignedExpr()), which callssetOffsetValueTypeon the innerlist<string>with anint<0, max>key. This destroys theAccessoryArrayListType(sincesetOffsetValueTypereturnsErrorTypefor non-zero/non-null offsets).The fix passes the already-computed
$valueToWrite(fromproduceArrayDimFetchAssignValueToWrite) directly as aTypeExprto theVariableAssignNode, ensuring the rule sees the same correct type that gets assigned to the variable in scope.Test
Added a regression test with two functions: one using by-reference foreach (already working) and one using indexed assignment (
$convert[$outerKey][$key] = strtoupper($val)) which was the failing case. Both should analyze without errors.Fixes phpstan/phpstan#14124