diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index 86f616953b..78ca2620a2 100644 --- a/src/Analyser/NodeScopeResolver.php +++ b/src/Analyser/NodeScopeResolver.php @@ -4334,7 +4334,9 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto ExpressionContext::createTopLevel(), ); $armScope = $armResult->getScope(); - $armBodyScopes[] = $armScope; + if (!$armResult->isAlwaysTerminating()) { + $armBodyScopes[] = $armScope; + } $hasYield = $hasYield || $armResult->hasYield(); $throwPoints = array_merge($throwPoints, $armResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $armResult->getImpurePoints()); @@ -4371,7 +4373,9 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto $hasYield = $hasYield || $armResult->hasYield(); $throwPoints = array_merge($throwPoints, $armResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $armResult->getImpurePoints()); - $armBodyScopes[] = $matchScope; + if (!$armResult->isAlwaysTerminating()) { + $armBodyScopes[] = $matchScope; + } continue; } @@ -4415,7 +4419,9 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto ExpressionContext::createTopLevel(), ); $armScope = $armResult->getScope(); - $armBodyScopes[] = $armScope; + if (!$armResult->isAlwaysTerminating()) { + $armBodyScopes[] = $armScope; + } $hasYield = $hasYield || $armResult->hasYield(); $throwPoints = array_merge($throwPoints, $armResult->getThrowPoints()); $impurePoints = array_merge($impurePoints, $armResult->getImpurePoints()); @@ -4476,7 +4482,7 @@ function (MutatingScope $scope) use ($stmt, $expr, $nodeCallback, $context, $sto $result = $this->processExprNode($stmt, $expr->expr, $scope, $storage, $nodeCallback, ExpressionContext::createDeep()); $throwPoints = $result->getThrowPoints(); $impurePoints = $result->getImpurePoints(); - $isAlwaysTerminating = $result->isAlwaysTerminating(); + $isAlwaysTerminating = true; $throwPoints[] = InternalThrowPoint::createExplicit($scope, $scope->getType($expr->expr), $expr, false); } elseif ($expr instanceof FunctionCallableNode) { $throwPoints = []; diff --git a/tests/PHPStan/Analyser/nsrt/bug-9601.php b/tests/PHPStan/Analyser/nsrt/bug-9601.php new file mode 100644 index 0000000000..952e76bb78 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-9601.php @@ -0,0 +1,31 @@ += 8.0 + +declare(strict_types = 1); + +namespace Bug9601; + +use function PHPStan\Testing\assertType; + +class HelloWorld +{ + public string $message = ''; +} + +class HelloWorld2 +{ + public string $message = ''; +} + +/** + * @param mixed $object + */ +function test($object): void +{ + $objectName = match (true) { + $object instanceof HelloWorld => $object::class, + $object instanceof HelloWorld2 => $object::class, + default => throw new \LogicException(), + }; + + assertType('Bug9601\HelloWorld|Bug9601\HelloWorld2', $object); +} diff --git a/tests/PHPStan/Rules/ScopeFunctionCallStackRuleTest.php b/tests/PHPStan/Rules/ScopeFunctionCallStackRuleTest.php index 6f652f9312..c08898e1cc 100644 --- a/tests/PHPStan/Rules/ScopeFunctionCallStackRuleTest.php +++ b/tests/PHPStan/Rules/ScopeFunctionCallStackRuleTest.php @@ -24,14 +24,6 @@ public function testRule(): void "var_dump\nprint_r\nsleep", 7, ], - [ - "var_dump\nprint_r\nsleep", - 10, - ], - [ - "var_dump\nprint_r\nsleep", - 13, - ], [ 'ScopeFunctionCallStack\NamedArgumentTest::testMethod', 31, diff --git a/tests/PHPStan/Rules/ScopeFunctionCallStackWithParametersRuleTest.php b/tests/PHPStan/Rules/ScopeFunctionCallStackWithParametersRuleTest.php index 25cb212ccb..da2f15e8d0 100644 --- a/tests/PHPStan/Rules/ScopeFunctionCallStackWithParametersRuleTest.php +++ b/tests/PHPStan/Rules/ScopeFunctionCallStackWithParametersRuleTest.php @@ -24,14 +24,6 @@ public function testRule(): void "var_dump (\$value)\nprint_r (\$value)\nsleep (\$seconds)", 7, ], - [ - "var_dump (\$value)\nprint_r (\$value)\nsleep (\$seconds)", - 10, - ], - [ - "var_dump (\$value)\nprint_r (\$value)\nsleep (\$seconds)", - 13, - ], [ // Named argument test - should report $notImmediate, not $immediate 'ScopeFunctionCallStack\NamedArgumentTest::testMethod ($notImmediate)',