diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 578b80f8df..9b57c1a5b1 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -2922,12 +2922,12 @@ 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]; - return $this->scopeFactory->create( + $functionScope = $this->scopeFactory->create( $this->context, $this->isDeclareStrictTypes(), $this->getFunction(), @@ -2945,6 +2945,12 @@ public function pushInFunctionCall($reflection, ?ParameterReflection $parameter) $this->parentScope, $this->nativeTypesPromoted, ); + + if ($rememberTypes) { + $functionScope->resolvedTypes = $this->resolvedTypes; + } + + return $functionScope; } public function popInFunctionCall(): self @@ -2952,7 +2958,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(), @@ -2970,6 +2976,10 @@ public function popInFunctionCall(): self $this->parentScope, $this->nativeTypesPromoted, ); + + $parentScope->resolvedTypes = $this->resolvedTypes; + + return $parentScope; } /** @api */ diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index 14bb1b7c40..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); + $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 ba5ed852cb..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); + $rememberTypes = !$originalArg->value instanceof Node\Expr\Closure && !$originalArg->value instanceof Node\Expr\ArrowFunction; + $scope = $scope->pushInFunctionCall(null, $parameter, $rememberTypes); } $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);