Skip to content

Commit 4968ec6

Browse files
staabmondrejmirtes
authored andcommitted
Error because unnecessary default-arm on match-expression with enums
1 parent b2a1743 commit 4968ec6

File tree

4 files changed

+75
-1
lines changed

4 files changed

+75
-1
lines changed

src/Reflection/InitializerExprTypeResolver.php

+17
Original file line numberDiff line numberDiff line change
@@ -1333,6 +1333,23 @@ public function resolveIdenticalType(Type $leftType, Type $rightType): BooleanTy
13331333
return new ConstantBooleanType($leftType->equals($rightType));
13341334
}
13351335

1336+
if ($leftType instanceof TypeWithClassName && $rightType instanceof EnumCaseObjectType) {
1337+
$classReflection = $leftType->getClassReflection();
1338+
if ($classReflection !== null && $classReflection->isEnum() && $classReflection->getName() === $rightType->getClassName()) {
1339+
if (count($classReflection->getEnumCases()) === 1) {
1340+
return new ConstantBooleanType(true);
1341+
}
1342+
}
1343+
}
1344+
if ($rightType instanceof TypeWithClassName && $leftType instanceof EnumCaseObjectType) {
1345+
$classReflection = $rightType->getClassReflection();
1346+
if ($classReflection !== null && $classReflection->isEnum() && $classReflection->getName() === $leftType->getClassName()) {
1347+
if (count($classReflection->getEnumCases()) === 1) {
1348+
return new ConstantBooleanType(true);
1349+
}
1350+
}
1351+
}
1352+
13361353
$isSuperset = $leftType->isSuperTypeOf($rightType);
13371354
if ($isSuperset->no()) {
13381355
return new ConstantBooleanType(false);

tests/PHPStan/Rules/Comparison/MatchExpressionRuleTest.php

+26
Original file line numberDiff line numberDiff line change
@@ -246,4 +246,30 @@ public function testBug7746(): void
246246
$this->analyse([__DIR__ . '/data/bug-7746.php'], []);
247247
}
248248

249+
public function testBug8240(): void
250+
{
251+
if (PHP_VERSION_ID < 80100) {
252+
$this->markTestSkipped('Test requires PHP 8.1.');
253+
}
254+
$this->treatPhpDocTypesAsCertain = true;
255+
$this->analyse([__DIR__ . '/data/bug-8240.php'], [
256+
[
257+
'Match arm comparison between Bug8240\Foo and Bug8240\Foo::BAR is always true.',
258+
13,
259+
],
260+
[
261+
'Match arm is unreachable because previous comparison is always true.',
262+
14,
263+
],
264+
[
265+
'Match arm comparison between Bug8240\Foo2::BAZ and Bug8240\Foo2::BAZ is always true.',
266+
28,
267+
],
268+
[
269+
'Match arm is unreachable because previous comparison is always true.',
270+
29,
271+
],
272+
]);
273+
}
274+
249275
}

tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -653,7 +653,7 @@ public function testBug8586(): void
653653
$this->checkAlwaysTrueStrictComparison = true;
654654
$this->analyse([__DIR__ . '/data/bug-8586.php'], []);
655655
}
656-
656+
657657
public function testBug4242(): void
658658
{
659659
if (PHP_VERSION_ID < 80100) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php // lint >= 8.1
2+
3+
namespace Bug8240;
4+
5+
enum Foo
6+
{
7+
case BAR;
8+
}
9+
10+
function doFoo(Foo $foo): int
11+
{
12+
return match ($foo) {
13+
Foo::BAR => 5,
14+
default => throw new \Exception('This will not be executed')
15+
};
16+
}
17+
18+
enum Foo2
19+
{
20+
case BAR;
21+
case BAZ;
22+
}
23+
24+
function doFoo2(Foo2 $foo): int
25+
{
26+
return match ($foo) {
27+
Foo2::BAR => 5,
28+
Foo2::BAZ => 15,
29+
default => throw new \Exception('This will not be executed')
30+
};
31+
}

0 commit comments

Comments
 (0)