Bug report
array_walk function https://www.php.net/manual/en/function.array-walk.php iterates over the array and passes each item to the closure by-ref.
PHPStan does not see the changes made to the array made by the closure, see the snippet.
PHPStan could use technique similar to detecting wrong parameter by-ref type:
* https://phpstan.org/error-identifiers/parameterByRef.type
See: VariableAssignNode, ParameterOutAssignedTypeRule.
Basically: When array_walk call is analysed by NodeScopeResolver, run processClosureNode with custom callback similar to processVirtualAssign. Hook onto VariableAssignNode of the first by-ref closure parameter, remember the values and then apply them to the array parameter (first argument of array_walk). This type also has to be merged with all execution ends of the closure, to detect if the type is not always rewritten (in case of early return). Also add test for this.
We already rewrite array contents a similar way when we detect a foreach is rewriting the entire array. That was done here: phpstan/phpstan-src#4534
Code snippet that reproduces the problem
https://phpstan.org/r/367b49ba-2a49-48f6-9edf-53d3bf972b64
Expected output
No errors - type assertion passing.
Did PHPStan help you today? Did it make you happy in any way?
No response
Bug report
array_walk function https://www.php.net/manual/en/function.array-walk.php iterates over the array and passes each item to the closure by-ref.
PHPStan does not see the changes made to the array made by the closure, see the snippet.
PHPStan could use technique similar to detecting wrong parameter by-ref type:
* https://phpstan.org/error-identifiers/parameterByRef.type
See: VariableAssignNode, ParameterOutAssignedTypeRule.
Basically: When
array_walkcall is analysed by NodeScopeResolver, runprocessClosureNodewith custom callback similar to processVirtualAssign. Hook onto VariableAssignNode of the first by-ref closure parameter, remember the values and then apply them to the array parameter (first argument of array_walk). This type also has to be merged with all execution ends of the closure, to detect if the type is not always rewritten (in case of early return). Also add test for this.We already rewrite array contents a similar way when we detect a foreach is rewriting the entire array. That was done here: phpstan/phpstan-src#4534
Code snippet that reproduces the problem
https://phpstan.org/r/367b49ba-2a49-48f6-9edf-53d3bf972b64
Expected output
No errors - type assertion passing.
Did PHPStan help you today? Did it make you happy in any way?
No response