From 3028428c0aa6b8408901725e14bfd35cd72c3253 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 21 Dec 2025 12:26:54 +0100 Subject: [PATCH 1/5] Remember resolved types after pushInFunctionCall --- src/Analyser/MutatingScope.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 578b80f8df..8c0023f8c4 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -2927,7 +2927,7 @@ public function pushInFunctionCall($reflection, ?ParameterReflection $parameter) $stack = $this->inFunctionCallsStack; $stack[] = [$reflection, $parameter]; - return $this->scopeFactory->create( + $functionScope = $this->scopeFactory->create( $this->context, $this->isDeclareStrictTypes(), $this->getFunction(), From e457bca434ab200485798a63a8eb786cf0d180d1 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 21 Dec 2025 12:27:03 +0100 Subject: [PATCH 2/5] Update MutatingScope.php --- src/Analyser/MutatingScope.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 8c0023f8c4..08cd75c4a4 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -2945,6 +2945,8 @@ public function pushInFunctionCall($reflection, ?ParameterReflection $parameter) $this->parentScope, $this->nativeTypesPromoted, ); + $functionScope->resolvedTypes = $this->resolvedTypes; + return $functionScope; } public function popInFunctionCall(): self From 2a9cdb1fc71e7403b37cc351ad4685385805a006 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 21 Dec 2025 12:34:23 +0100 Subject: [PATCH 3/5] Update MutatingScope.php --- src/Analyser/MutatingScope.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 08cd75c4a4..a69e42b745 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -2954,7 +2954,7 @@ public function popInFunctionCall(): self $stack = $this->inFunctionCallsStack; array_pop($stack); - return $this->scopeFactory->create( + $parentScope = $this->scopeFactory->create( $this->context, $this->isDeclareStrictTypes(), $this->getFunction(), @@ -2972,6 +2972,8 @@ public function popInFunctionCall(): self $this->parentScope, $this->nativeTypesPromoted, ); + $parentScope->resolvedTypes = $this->resolvedTypes; + return $parentScope; } /** @api */ From f409c7115415daa531a224ad44ea77227b1e738a Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Mon, 22 Dec 2025 09:24:52 +0100 Subject: [PATCH 4/5] fix --- src/Analyser/MutatingScope.php | 10 ++++++++-- src/Analyser/NodeScopeResolver.php | 2 +- src/Reflection/ParametersAcceptorSelector.php | 2 +- src/Rules/FunctionCallParametersCheck.php | 3 ++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index a69e42b745..9b57c1a5b1 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -2922,7 +2922,7 @@ public function hasExpressionType(Expr $node): TrinaryLogic /** * @param MethodReflection|FunctionReflection|null $reflection */ - public function pushInFunctionCall($reflection, ?ParameterReflection $parameter): self + public function pushInFunctionCall($reflection, ?ParameterReflection $parameter, bool $rememberTypes): self { $stack = $this->inFunctionCallsStack; $stack[] = [$reflection, $parameter]; @@ -2945,7 +2945,11 @@ public function pushInFunctionCall($reflection, ?ParameterReflection $parameter) $this->parentScope, $this->nativeTypesPromoted, ); - $functionScope->resolvedTypes = $this->resolvedTypes; + + if ($rememberTypes) { + $functionScope->resolvedTypes = $this->resolvedTypes; + } + return $functionScope; } @@ -2972,7 +2976,9 @@ public function popInFunctionCall(): self $this->parentScope, $this->nativeTypesPromoted, ); + $parentScope->resolvedTypes = $this->resolvedTypes; + return $parentScope; } diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index 14bb1b7c40..d080481769 100644 --- a/src/Analyser/NodeScopeResolver.php +++ b/src/Analyser/NodeScopeResolver.php @@ -5604,7 +5604,7 @@ private function processArgs( } if ($calleeReflection !== null) { - $scope = $scope->pushInFunctionCall($calleeReflection, $parameter); + $scope = $scope->pushInFunctionCall($calleeReflection, $parameter, true); } $originalArg = $arg->getAttribute(ArgumentsNormalizer::ORIGINAL_ARG_ATTRIBUTE) ?? $arg; diff --git a/src/Reflection/ParametersAcceptorSelector.php b/src/Reflection/ParametersAcceptorSelector.php index ba5ed852cb..c5d38fc372 100644 --- a/src/Reflection/ParametersAcceptorSelector.php +++ b/src/Reflection/ParametersAcceptorSelector.php @@ -499,7 +499,7 @@ public static function selectFromArgs( } if ($parameter !== null && $scope instanceof MutatingScope) { - $scope = $scope->pushInFunctionCall(null, $parameter); + $scope = $scope->pushInFunctionCall(null, $parameter, true); } $type = $scope->getType($originalArg->value); diff --git a/src/Rules/FunctionCallParametersCheck.php b/src/Rules/FunctionCallParametersCheck.php index 5cb8b48761..8e3d4b198d 100644 --- a/src/Rules/FunctionCallParametersCheck.php +++ b/src/Rules/FunctionCallParametersCheck.php @@ -319,7 +319,8 @@ public function check( if ($argumentValueType === null) { if ($scope instanceof MutatingScope) { - $scope = $scope->pushInFunctionCall(null, $parameter); + $rememberTypes = !$argumentValue instanceof Expr\Closure && !$argumentValue instanceof Expr\ArrowFunction; + $scope = $scope->pushInFunctionCall(null, $parameter, $rememberTypes); } $argumentValueType = $scope->getType($argumentValue); From 0e74664e50b128e50f60f638b7390ddcdbd5e8fe Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Mon, 22 Dec 2025 09:39:17 +0100 Subject: [PATCH 5/5] fix --- src/Analyser/NodeScopeResolver.php | 5 +++-- src/Reflection/ParametersAcceptorSelector.php | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index d080481769..ec0961b411 100644 --- a/src/Analyser/NodeScopeResolver.php +++ b/src/Analyser/NodeScopeResolver.php @@ -5603,11 +5603,12 @@ private function processArgs( } } + $originalArg = $arg->getAttribute(ArgumentsNormalizer::ORIGINAL_ARG_ATTRIBUTE) ?? $arg; if ($calleeReflection !== null) { - $scope = $scope->pushInFunctionCall($calleeReflection, $parameter, true); + $rememberTypes = !$originalArg->value instanceof Expr\Closure && !$originalArg->value instanceof Expr\ArrowFunction; + $scope = $scope->pushInFunctionCall($calleeReflection, $parameter, $rememberTypes); } - $originalArg = $arg->getAttribute(ArgumentsNormalizer::ORIGINAL_ARG_ATTRIBUTE) ?? $arg; $this->callNodeCallback($nodeCallback, $originalArg, $scope, $storage); $originalScope = $scope; diff --git a/src/Reflection/ParametersAcceptorSelector.php b/src/Reflection/ParametersAcceptorSelector.php index c5d38fc372..505b7f0015 100644 --- a/src/Reflection/ParametersAcceptorSelector.php +++ b/src/Reflection/ParametersAcceptorSelector.php @@ -499,7 +499,8 @@ public static function selectFromArgs( } if ($parameter !== null && $scope instanceof MutatingScope) { - $scope = $scope->pushInFunctionCall(null, $parameter, true); + $rememberTypes = !$originalArg->value instanceof Node\Expr\Closure && !$originalArg->value instanceof Node\Expr\ArrowFunction; + $scope = $scope->pushInFunctionCall(null, $parameter, $rememberTypes); } $type = $scope->getType($originalArg->value);