diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index ce853bd980..4b5c220c9a 100644 --- a/src/Analyser/NodeScopeResolver.php +++ b/src/Analyser/NodeScopeResolver.php @@ -3401,11 +3401,18 @@ public function processArgs( $this->storeBeforeScope($storage, $arg->value, $scopeToPass); } else { $exprType = $scope->getType($arg->value); + $enterExpressionAssignForByRef = $assignByReference && $arg->value instanceof ArrayDimFetch && $arg->value->dim === null; + if ($enterExpressionAssignForByRef) { + $scopeToPass = $scopeToPass->enterExpressionAssign($arg->value); + } $exprResult = $this->processExprNode($stmt, $arg->value, $scopeToPass, $storage, $nodeCallback, $context->enterDeep()); $throwPoints = array_merge($throwPoints, $exprResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $exprResult->getImpurePoints()); $isAlwaysTerminating = $isAlwaysTerminating || $exprResult->isAlwaysTerminating(); $scope = $exprResult->getScope(); + if ($enterExpressionAssignForByRef) { + $scope = $scope->exitExpressionAssign($arg->value); + } $hasYield = $hasYield || $exprResult->hasYield(); if ($exprType->isCallable()->yes()) { diff --git a/tests/PHPStan/Rules/Arrays/OffsetAccessWithoutDimForReadingRuleTest.php b/tests/PHPStan/Rules/Arrays/OffsetAccessWithoutDimForReadingRuleTest.php index db6846cfa0..6e109cc89b 100644 --- a/tests/PHPStan/Rules/Arrays/OffsetAccessWithoutDimForReadingRuleTest.php +++ b/tests/PHPStan/Rules/Arrays/OffsetAccessWithoutDimForReadingRuleTest.php @@ -16,6 +16,11 @@ protected function getRule(): Rule return new OffsetAccessWithoutDimForReadingRule(); } + public function testBug5290(): void + { + $this->analyse([__DIR__ . '/data/bug-5290.php'], []); + } + public function testOffsetAccessWithoutDimForReading(): void { $this->analyse( diff --git a/tests/PHPStan/Rules/Arrays/data/bug-5290.php b/tests/PHPStan/Rules/Arrays/data/bug-5290.php new file mode 100644 index 0000000000..9c57effc41 --- /dev/null +++ b/tests/PHPStan/Rules/Arrays/data/bug-5290.php @@ -0,0 +1,27 @@ +bar($array[]); + +// Nested array dim fetch with by-ref parameter +set($array[1][]); diff --git a/tests/PHPStan/Rules/Arrays/data/offset-access-without-dim-for-reading.php b/tests/PHPStan/Rules/Arrays/data/offset-access-without-dim-for-reading.php index 3ff679e20f..62910e04bc 100644 --- a/tests/PHPStan/Rules/Arrays/data/offset-access-without-dim-for-reading.php +++ b/tests/PHPStan/Rules/Arrays/data/offset-access-without-dim-for-reading.php @@ -15,7 +15,7 @@ $firstElement = &$array[]; (function ($ref) {})($array[]); -//(function (&$ref) {})($array[]); // Should work but doesn't +(function (&$ref) {})($array[]); // Technically works but makes no sense $array[] += 20;