Skip to content

Commit 393d656

Browse files
committed
Fix missing detection of dead code in closures
1 parent 1f150cc commit 393d656

File tree

3 files changed

+13
-2
lines changed

3 files changed

+13
-2
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4690,7 +4690,7 @@ private function processClosureNode(
46904690
array_merge($statementResult->getImpurePoints(), $closureImpurePoints),
46914691
), $closureScope);
46924692

4693-
return new ProcessClosureResult($scope, $statementResult->getThrowPoints(), $statementResult->getImpurePoints(), $invalidateExpressions);
4693+
return new ProcessClosureResult($scope, $statementResult->getThrowPoints(), $statementResult->getImpurePoints(), $invalidateExpressions, $statementResult->isAlwaysTerminating());
46944694
}
46954695

46964696
$count = 0;
@@ -4736,7 +4736,7 @@ private function processClosureNode(
47364736
array_merge($statementResult->getImpurePoints(), $closureImpurePoints),
47374737
), $closureScope);
47384738

4739-
return new ProcessClosureResult($scope->processClosureScope($closureResultScope, null, $byRefUses), $statementResult->getThrowPoints(), $statementResult->getImpurePoints(), $invalidateExpressions);
4739+
return new ProcessClosureResult($scope->processClosureScope($closureResultScope, null, $byRefUses), $statementResult->getThrowPoints(), $statementResult->getImpurePoints(), $invalidateExpressions, $statementResult->isAlwaysTerminating());
47404740
}
47414741

47424742
/**
@@ -5174,6 +5174,7 @@ private function processArgs(
51745174
if ($callCallbackImmediately) {
51755175
$throwPoints = array_merge($throwPoints, array_map(static fn (ThrowPoint $throwPoint) => $throwPoint->isExplicit() ? ThrowPoint::createExplicit($scope, $throwPoint->getType(), $arg->value, $throwPoint->canContainAnyThrowable()) : ThrowPoint::createImplicit($scope, $arg->value), $closureResult->getThrowPoints()));
51765176
$impurePoints = array_merge($impurePoints, $closureResult->getImpurePoints());
5177+
$isAlwaysTerminating = $isAlwaysTerminating || $closureResult->isAlwaysTerminating();
51775178
}
51785179

51795180
$uses = [];

src/Analyser/ProcessClosureResult.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public function __construct(
1717
private array $throwPoints,
1818
private array $impurePoints,
1919
private array $invalidateExpressions,
20+
private bool $isAlwaysTerminating,
2021
)
2122
{
2223
}
@@ -50,4 +51,9 @@ public function getInvalidateExpressions(): array
5051
return $this->invalidateExpressions;
5152
}
5253

54+
public function isAlwaysTerminating(): bool
55+
{
56+
return $this->isAlwaysTerminating;
57+
}
58+
5359
}

tests/PHPStan/Analyser/ExpressionResultTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ public static function dataIsAlwaysTerminating(): array
9999
'exit() ?? $x;',
100100
true,
101101
],
102+
[
103+
'call_user_func(function() { exit(); });',
104+
true,
105+
],
102106
[
103107
'var_dump(1+exit());',
104108
true,

0 commit comments

Comments
 (0)