diff --git a/src/Analyser/NodeScopeResolver.php b/src/Analyser/NodeScopeResolver.php index 2216db1a6b..26a056877a 100644 --- a/src/Analyser/NodeScopeResolver.php +++ b/src/Analyser/NodeScopeResolver.php @@ -3446,14 +3446,20 @@ static function (Node $node, Scope $scope) use ($nodeCallback): void { $expr->cond, $enumCase, ); - } elseif (count($unusedIndexedEnumCases[$loweredFetchedClassName]) === 1) { - $hasAlwaysTrueCond = true; - - // force "always true" - $armConditionScope = $armConditionScope->addTypeToExpression( - $expr->cond, - $enumCase, - ); + } else { + $unusedCasesCount = 0; + foreach ($unusedIndexedEnumCases as $cases) { + $unusedCasesCount += count($cases); + } + if ($unusedCasesCount === 1) { + $hasAlwaysTrueCond = true; + + // force "always true" + $armConditionScope = $armConditionScope->addTypeToExpression( + $expr->cond, + $enumCase, + ); + } } $this->processExprNode($stmt, $cond, $armConditionScope, $nodeCallback, $deepContext); diff --git a/tests/PHPStan/Rules/Comparison/MatchExpressionRuleTest.php b/tests/PHPStan/Rules/Comparison/MatchExpressionRuleTest.php index cb973a9609..9ffaa5eb4b 100644 --- a/tests/PHPStan/Rules/Comparison/MatchExpressionRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/MatchExpressionRuleTest.php @@ -581,4 +581,13 @@ public function testBug9879(): void $this->analyse([__DIR__ . '/data/bug-9879.php'], []); } + public function testBug11313(): void + { + if (PHP_VERSION_ID < 80100) { + $this->markTestSkipped('Test requires PHP 8.1.'); + } + + $this->analyse([__DIR__ . '/data/bug-11313.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Comparison/data/bug-11313.php b/tests/PHPStan/Rules/Comparison/data/bug-11313.php new file mode 100644 index 0000000000..84375ca499 --- /dev/null +++ b/tests/PHPStan/Rules/Comparison/data/bug-11313.php @@ -0,0 +1,23 @@ += 8.1 + +namespace Bug11313; + +enum Foo: string +{ + case CaseOne = 'one'; + case CaseTwo = 'two'; +} + +enum Bar: string +{ + case CaseThree = 'Three'; +} + +function test(Foo|Bar $union): bool +{ + return match ($union) { + Bar::CaseThree, + Foo::CaseOne => true, + Foo::CaseTwo => false, + }; +}