Skip to content

Fix #5290: "Cannot use [] for reading." false positives#5059

Open
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-8uta713
Open

Fix #5290: "Cannot use [] for reading." false positives#5059
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-8uta713

Conversation

@phpstan-bot
Copy link
Collaborator

Summary

PHPStan incorrectly reported "Cannot use [] for reading." when $array[] was passed as an argument to a function/method parameter declared as by-reference. This is a valid PHP pattern — $array[] in a by-reference context creates a new array element and passes the reference to it, rather than reading.

Changes

  • Modified src/Analyser/NodeScopeResolver.php in processArgs(): when processing a by-reference argument that is an ArrayDimFetch with null dim ($array[]), enter expression assign context before processing and exit it afterward. This tells the OffsetAccessWithoutDimForReadingRule that the expression is in a write context.
  • Added regression test tests/PHPStan/Rules/Arrays/data/bug-5290.php covering named functions, immediately invoked closures with by-ref params, and method calls.
  • Uncommented a previously disabled test case in tests/PHPStan/Rules/Arrays/data/offset-access-without-dim-for-reading.php (line 18: (function (&$ref) {})($array[]) which was marked as "Should work but doesn't").

Root cause

The OffsetAccessWithoutDimForReadingRule checks whether an ArrayDimFetch with null dim is in an expression assign context via $scope->isInExpressionAssign(). However, NodeScopeResolver::processArgs() did not enter expression assign context when processing by-reference arguments, so $array[] passed to a &$param was treated as a read rather than a write.

The fix is targeted to only affect ArrayDimFetch nodes with null dim (the $array[] syntax), avoiding broader side effects on other rules like DefinedVariableRule or UnusedPrivatePropertyRule that also check isInExpressionAssign.

Test

Added tests/PHPStan/Rules/Arrays/data/bug-5290.php with three scenarios that all previously produced false positives:

  1. set($array[]) — named function with &$value parameter
  2. (function (&$ref) {})($array[]) — immediately invoked closure with by-ref parameter
  3. $foo->bar($array[]) — method call with &$value parameter

All three expect no errors.

Fixes phpstan/phpstan#5290

- Enter expression assign context for ArrayDimFetch with null dim when passed as a by-reference argument in NodeScopeResolver::processArgs()
- Exit expression assign after processing to prevent scope leakage
- Add regression test in tests/PHPStan/Rules/Arrays/data/bug-5290.php
- Uncomment previously disabled test case for by-ref closure in existing test data

Closes phpstan/phpstan#5290
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant