Skip to content

Commit 44e40f0

Browse files
committed
Fix match of union of enums
1 parent 2301b8b commit 44e40f0

File tree

3 files changed

+46
-8
lines changed

3 files changed

+46
-8
lines changed

src/Analyser/NodeScopeResolver.php

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3446,14 +3446,20 @@ static function (Node $node, Scope $scope) use ($nodeCallback): void {
34463446
$expr->cond,
34473447
$enumCase,
34483448
);
3449-
} elseif (count($unusedIndexedEnumCases[$loweredFetchedClassName]) === 1) {
3450-
$hasAlwaysTrueCond = true;
3451-
3452-
// force "always true"
3453-
$armConditionScope = $armConditionScope->addTypeToExpression(
3454-
$expr->cond,
3455-
$enumCase,
3456-
);
3449+
} else {
3450+
$unusedCasesCount = 0;
3451+
foreach ($unusedIndexedEnumCases as $cases) {
3452+
$unusedCasesCount += count($cases);
3453+
}
3454+
if ($unusedCasesCount === 1) {
3455+
$hasAlwaysTrueCond = true;
3456+
3457+
// force "always true"
3458+
$armConditionScope = $armConditionScope->addTypeToExpression(
3459+
$expr->cond,
3460+
$enumCase,
3461+
);
3462+
}
34573463
}
34583464

34593465
$this->processExprNode($stmt, $cond, $armConditionScope, $nodeCallback, $deepContext);

tests/PHPStan/Rules/Comparison/MatchExpressionRuleTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,4 +581,13 @@ public function testBug9879(): void
581581
$this->analyse([__DIR__ . '/data/bug-9879.php'], []);
582582
}
583583

584+
public function testBug11313(): void
585+
{
586+
if (PHP_VERSION_ID < 80100) {
587+
$this->markTestSkipped('Test requires PHP 8.1.');
588+
}
589+
590+
$this->analyse([__DIR__ . '/data/bug-11313.php'], []);
591+
}
592+
584593
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php // lint >= 8.1
2+
3+
namespace Bug11313;
4+
5+
enum Foo: string
6+
{
7+
case CaseOne = 'one';
8+
case CaseTwo = 'two';
9+
}
10+
11+
enum Bar: string
12+
{
13+
case CaseThree = 'Three';
14+
}
15+
16+
function test(Foo|Bar $union): bool
17+
{
18+
return match ($union) {
19+
Bar::CaseThree,
20+
Foo::CaseOne => true,
21+
Foo::CaseTwo => false,
22+
};
23+
}

0 commit comments

Comments
 (0)