diff --git a/rules/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector.php b/rules/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector.php index 52d5cfe5e89..82cbcd94b46 100644 --- a/rules/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector.php +++ b/rules/Php81/Rector/FuncCall/NullToStrictStringFuncCallArgRector.php @@ -7,7 +7,6 @@ use PhpParser\Node; use PhpParser\Node\Arg; use PhpParser\Node\Expr; -use PhpParser\Node\Expr\ArrayDimFetch; use PhpParser\Node\Expr\Cast\String_ as CastString_; use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; @@ -17,7 +16,10 @@ use PhpParser\Node\Scalar\String_; use PHPStan\Analyser\Scope; use PHPStan\Reflection\ClassReflection; +use PHPStan\Reflection\FunctionReflection; use PHPStan\Reflection\Native\NativeFunctionReflection; +use PHPStan\Reflection\Native\NativeParameterWithPhpDocsReflection; +use PHPStan\Reflection\ParametersAcceptor; use PHPStan\Type\ErrorType; use PHPStan\Type\MixedType; use PHPStan\Type\NullType; @@ -113,9 +115,23 @@ public function refactor(Node $node): ?Node $classReflection = $scope->getClassReflection(); $isTrait = $classReflection instanceof ClassReflection && $classReflection->isTrait(); + $functionReflection = $this->reflectionResolver->resolveFunctionLikeReflectionFromCall($node); + if (! $functionReflection instanceof FunctionReflection) { + return null; + } + + $parametersAcceptor = ParametersAcceptorSelectorVariantsWrapper::select($functionReflection, $node, $scope); $isChanged = false; + foreach ($positions as $position) { - $result = $this->processNullToStrictStringOnNodePosition($node, $args, $position, $isTrait, $scope); + $result = $this->processNullToStrictStringOnNodePosition( + $node, + $args, + $position, + $isTrait, + $scope, + $parametersAcceptor + ); if ($result instanceof Node) { $node = $result; $isChanged = true; @@ -167,7 +183,8 @@ private function processNullToStrictStringOnNodePosition( array $args, int|string $position, bool $isTrait, - Scope $scope + Scope $scope, + ParametersAcceptor $parametersAcceptor ): ?FuncCall { if (! isset($args[$position])) { return null; @@ -208,8 +225,12 @@ private function processNullToStrictStringOnNodePosition( return null; } - if ($type instanceof MixedType && $args[$position]->value instanceof ArrayDimFetch) { - return null; + $parameter = $parametersAcceptor->getParameters()[$position] ?? null; + if ($parameter instanceof NativeParameterWithPhpDocsReflection && $parameter->getType() instanceof UnionType) { + $parameterType = $parameter->getType(); + if (! $this->isValidUnionType($parameterType)) { + return null; + } } $args[$position]->value = new CastString_($argValue);