diff --git a/src/Parser/ArrowFunctionArgVisitor.php b/src/Parser/ArrowFunctionArgVisitor.php index f8149dad21..93cce45dd9 100644 --- a/src/Parser/ArrowFunctionArgVisitor.php +++ b/src/Parser/ArrowFunctionArgVisitor.php @@ -13,13 +13,28 @@ final class ArrowFunctionArgVisitor extends NodeVisitorAbstract public function enterNode(Node $node): ?Node { - if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Expr\ArrowFunction && !$node->isFirstClassCallable()) { - $args = $node->getArgs(); + if (!$node instanceof Node\Expr\FuncCall) { + return null; + } + + if ($node->isFirstClassCallable()) { + return null; + } - if (count($args) > 0) { - $node->name->setAttribute(self::ATTRIBUTE_NAME, $args); - } + if ($node->name instanceof Node\Expr\Assign && $node->name->expr instanceof Node\Expr\ArrowFunction) { + $arrow = $node->name->expr; + } elseif ($node->name instanceof Node\Expr\ArrowFunction) { + $arrow = $node->name; + } else { + return null; } + + $args = $node->getArgs(); + + if (count($args) > 0) { + $arrow->setAttribute(self::ATTRIBUTE_NAME, $args); + } + return null; } diff --git a/src/Parser/ClosureArgVisitor.php b/src/Parser/ClosureArgVisitor.php index 58d53a808e..c9435f826e 100644 --- a/src/Parser/ClosureArgVisitor.php +++ b/src/Parser/ClosureArgVisitor.php @@ -13,13 +13,28 @@ final class ClosureArgVisitor extends NodeVisitorAbstract public function enterNode(Node $node): ?Node { - if ($node instanceof Node\Expr\FuncCall && $node->name instanceof Node\Expr\Closure && !$node->isFirstClassCallable()) { - $args = $node->getArgs(); + if (!$node instanceof Node\Expr\FuncCall) { + return null; + } + + if ($node->isFirstClassCallable()) { + return null; + } - if (count($args) > 0) { - $node->name->setAttribute(self::ATTRIBUTE_NAME, $args); - } + if ($node->name instanceof Node\Expr\Assign && $node->name->expr instanceof Node\Expr\Closure) { + $closure = $node->name->expr; + } elseif ($node->name instanceof Node\Expr\Closure) { + $closure = $node->name; + } else { + return null; } + + $args = $node->getArgs(); + + if (count($args) > 0) { + $closure->setAttribute(self::ATTRIBUTE_NAME, $args); + } + return null; } diff --git a/tests/PHPStan/Analyser/nsrt/arrow-function-argument-type.php b/tests/PHPStan/Analyser/nsrt/arrow-function-argument-type.php index 3e1448e6ff..a508035d19 100644 --- a/tests/PHPStan/Analyser/nsrt/arrow-function-argument-type.php +++ b/tests/PHPStan/Analyser/nsrt/arrow-function-argument-type.php @@ -21,6 +21,8 @@ public function doFoo(int $integer, array $array, ?string $nullableString) (fn($a, $b, $c) => assertType('array{int, array{a: int}, string|null}', [$a, $b, $c]))($integer, $array, $nullableString); (fn($a, $b, $c = null) => assertType('array{int, array{a: int}, mixed}', [$a, $b, $c]))($integer, $array); + + ($callback = fn($context) => assertType('int', $context))($integer); } } diff --git a/tests/PHPStan/Analyser/nsrt/closure-argument-type.php b/tests/PHPStan/Analyser/nsrt/closure-argument-type.php index 6fd537211d..b24570b298 100644 --- a/tests/PHPStan/Analyser/nsrt/closure-argument-type.php +++ b/tests/PHPStan/Analyser/nsrt/closure-argument-type.php @@ -35,6 +35,10 @@ public function doFoo(int $integer, array $array, ?string $nullableString) assertType('array{a: int}', $context2); assertType('mixed', $context3); })($integer, $array); + + ($callback = function($context) { + assertType('int', $context); + })($integer); } }