diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnDirectArrayRector/Fixture/skip_multi_types_return.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnDirectArrayRector/Fixture/skip_multi_types_return.php.inc new file mode 100644 index 00000000000..0f1d3618a77 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/ReturnTypeFromReturnDirectArrayRector/Fixture/skip_multi_types_return.php.inc @@ -0,0 +1,19 @@ +returnTypeInferer->inferFunctionLike($node); + if (! $type->isArray()->yes()) { + return null; + } + $node->returnType = new Identifier('array'); return $node; diff --git a/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer.php b/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer.php index 1be9e83a804..78c24133eef 100644 --- a/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer.php +++ b/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer.php @@ -6,6 +6,7 @@ use PhpParser\Node; use PhpParser\Node\Expr; +use PhpParser\Node\Expr\ArrowFunction; use PhpParser\Node\Expr\Closure; use PhpParser\Node\FunctionLike; use PhpParser\Node\Stmt\Class_; @@ -52,7 +53,7 @@ public function __construct( ) { } - public function inferFunctionLike(ClassMethod|Function_|Closure $functionLike): Type + public function inferFunctionLike(ClassMethod|Function_|Closure|ArrowFunction $functionLike): Type { $isSupportedStaticReturnType = $this->phpVersionProvider->isAtLeastPhpVersion( PhpVersionFeature::STATIC_RETURN_TYPE @@ -120,9 +121,15 @@ public function verifyThisType(Type $type, FunctionLike $functionLike): ?Type return new MixedType(); } - private function resolveTypeWithVoidHandling(ClassMethod|Function_|Closure $functionLike, Type $resolvedType): Type - { + private function resolveTypeWithVoidHandling( + ClassMethod|Function_|Closure|ArrowFunction $functionLike, + Type $resolvedType + ): Type { if ($resolvedType instanceof VoidType) { + if ($functionLike instanceof ArrowFunction) { + return new MixedType(); + } + $hasReturnValue = (bool) $this->betterNodeFinder->findFirstInFunctionLikeScoped( $functionLike, static function (Node $subNode): bool { @@ -150,7 +157,7 @@ static function (Node $subNode): bool { } private function resolveBenevolentUnionTypeInteger( - ClassMethod|Function_|Closure $functionLike, + ClassMethod|Function_|Closure|ArrowFunction $functionLike, UnionType $unionType ): UnionType|IntegerType { $types = $unionType->getTypes(); @@ -164,8 +171,16 @@ private function resolveBenevolentUnionTypeInteger( return $unionType; } - $returns = $this->betterNodeFinder->findInstancesOfInFunctionLikeScoped($functionLike, Return_::class); - $returnsWithExpr = array_filter($returns, static fn (Return_ $return): bool => $return->expr instanceof Expr); + if (! $functionLike instanceof ArrowFunction) { + $returns = $this->betterNodeFinder->findInstancesOfInFunctionLikeScoped($functionLike, Return_::class); + $returnsWithExpr = array_filter( + $returns, + static fn (Return_ $return): bool => $return->expr instanceof Expr + ); + } else { + $returns = $functionLike->getStmts(); + $returnsWithExpr = $returns; + } if ($returns !== $returnsWithExpr) { return $unionType;