Skip to content

Use pre-args scope for value types in array_push/array_unshift#5579

Open
predictor2718 wants to merge 1 commit intophpstan:2.1.xfrom
predictor2718:fix-13510
Open

Use pre-args scope for value types in array_push/array_unshift#5579
predictor2718 wants to merge 1 commit intophpstan:2.1.xfrom
predictor2718:fix-13510

Conversation

@predictor2718
Copy link
Copy Markdown
Contributor

When array_unshift($arr, array_pop($arr)) is processed, processArgs evaluates the nested array_pop($arr) argument first, which mutates $arr's type in scope (e.g. non-empty-list<int>list<int>). Then getArrayFunctionAppendingType re-evaluates the value argument expressions in the already-mutated scope, causing array_pop($arr) to return int|null instead of int — and the resulting array type becomes non-empty-list<int|null> instead of non-empty-list<int>.

The fix captures the scope before processArgs and passes it as a separate $valuesScope to getArrayFunctionAppendingType. The array type (first arg) still uses the post-args scope (correctly reflecting the post-pop state), while the value types (remaining args) are evaluated using the pre-args scope (correctly reflecting what was actually passed).

Closes phpstan/phpstan#13510

}

private function getArrayFunctionAppendingType(FunctionReflection $functionReflection, Scope $scope, FuncCall $expr): Type
private function getArrayFunctionAppendingType(FunctionReflection $functionReflection, Scope $scope, Scope $valuesScope, FuncCall $expr): Type
Copy link
Copy Markdown
Contributor

@staabm staabm May 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please try whether we can just use a single Scope argument - meaning use scopeBeforeArgs for all calls in this method

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, simplified to pass $scopeBeforeArgs as the single scope argument.

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.

2 participants