Skip to content

Commit 85d67ac

Browse files
committed
Fix closure inferred return type with nested closures and anonymous classes
1 parent 72ce1e5 commit 85d67ac

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

src/Analyser/MutatingScope.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
use PHPStan\Reflection\Php\PhpMethodFromParserNodeReflection;
4141
use PHPStan\Reflection\PropertyReflection;
4242
use PHPStan\Reflection\ReflectionProvider;
43+
use PHPStan\Reflection\TrivialParametersAcceptor;
4344
use PHPStan\Rules\Properties\PropertyReflectionFinder;
4445
use PHPStan\TrinaryLogic;
4546
use PHPStan\Type\ArrayType;
@@ -1326,7 +1327,11 @@ private function resolveType(Expr $node): Type
13261327
$closureScope = $this->enterAnonymousFunctionWithoutReflection($node);
13271328
$closureReturnStatements = [];
13281329
$closureYieldStatements = [];
1329-
$this->nodeScopeResolver->processStmtNodes($node, $node->stmts, $closureScope, static function (Node $node, Scope $scope) use (&$closureReturnStatements, &$closureYieldStatements): void {
1330+
$this->nodeScopeResolver->processStmtNodes($node, $node->stmts, $closureScope, static function (Node $node, Scope $scope) use ($closureScope, &$closureReturnStatements, &$closureYieldStatements): void {
1331+
if ($scope->getAnonymousFunctionReflection() !== $closureScope->getAnonymousFunctionReflection()) {
1332+
return;
1333+
}
1334+
13301335
if ($node instanceof Node\Stmt\Return_) {
13311336
$closureReturnStatements[] = [$node, $scope];
13321337
}
@@ -2895,7 +2900,7 @@ private function enterAnonymousFunctionWithoutReflection(
28952900
$moreSpecificTypes,
28962901
[],
28972902
$this->inClosureBindScopeClass,
2898-
null,
2903+
new TrivialParametersAcceptor(),
28992904
true,
29002905
[],
29012906
$nativeTypes,

tests/PHPStan/Analyser/data/closure-return-type.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,4 +75,27 @@ public function doFoo(int $i): void
7575
assertType('Generator<int, 1, mixed, 2>', $h());
7676
}
7777

78+
public function doBar(): void
79+
{
80+
$f = function () {
81+
if (rand(0, 1)) {
82+
return 1;
83+
}
84+
85+
function () {
86+
return 'foo';
87+
};
88+
89+
$c = new class() {
90+
public function doFoo() {
91+
return 2.0;
92+
}
93+
};
94+
95+
return 2;
96+
};
97+
98+
assertType('1|2', $f());
99+
}
100+
78101
}

0 commit comments

Comments
 (0)