Skip to content

Commit 1eb6eb9

Browse files
committed
Fix phpstan/phpstan#14369: Null coalescing assignment with throw not always terminating
- Fixed AssignOpHandler to not propagate isAlwaysTerminating from the RHS of ??= - The RHS of ??= only executes when the LHS is null, so the expression cannot always terminate - Added NSRT regression test verifying type narrowing after ??= throw - Added UnreachableStatementRule test verifying no false positive unreachable code
1 parent cfba43c commit 1eb6eb9

4 files changed

Lines changed: 36 additions & 1 deletion

File tree

src/Analyser/ExprHandler/AssignOpHandler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $contex
6969
return new ExpressionResult(
7070
$exprResult->getScope()->mergeWith($originalScope),
7171
$exprResult->hasYield(),
72-
$exprResult->isAlwaysTerminating(),
72+
false,
7373
$exprResult->getThrowPoints(),
7474
$exprResult->getImpurePoints(),
7575
);
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php // lint >= 8.0
2+
3+
declare(strict_types = 1);
4+
5+
namespace Bug14369;
6+
7+
use Exception;
8+
use function PHPStan\Testing\assertType;
9+
10+
function test(string|null $test): void
11+
{
12+
$test ??= throw new Exception();
13+
14+
assertType('string', $test);
15+
}

tests/PHPStan/Rules/DeadCode/UnreachableStatementRuleTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,4 +397,10 @@ public function testBug14328(): void
397397
]);
398398
}
399399

400+
public function testBug14369(): void
401+
{
402+
$this->treatPhpDocTypesAsCertain = true;
403+
$this->analyse([__DIR__ . '/data/bug-14369.php'], []);
404+
}
405+
400406
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php // lint >= 8.0
2+
3+
declare(strict_types = 1);
4+
5+
namespace Bug14369DeadCode;
6+
7+
use Exception;
8+
9+
function test(string|null $test): void
10+
{
11+
$test ??= throw new Exception();
12+
13+
echo $test;
14+
}

0 commit comments

Comments
 (0)