Skip to content

Commit

Permalink
Error because unnecessary default-arm on match-expression with enums
Browse files Browse the repository at this point in the history
  • Loading branch information
staabm authored and ondrejmirtes committed Jan 9, 2023
1 parent b2a1743 commit 4968ec6
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 1 deletion.
17 changes: 17 additions & 0 deletions src/Reflection/InitializerExprTypeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -1333,6 +1333,23 @@ public function resolveIdenticalType(Type $leftType, Type $rightType): BooleanTy
return new ConstantBooleanType($leftType->equals($rightType));
}

if ($leftType instanceof TypeWithClassName && $rightType instanceof EnumCaseObjectType) {
$classReflection = $leftType->getClassReflection();
if ($classReflection !== null && $classReflection->isEnum() && $classReflection->getName() === $rightType->getClassName()) {
if (count($classReflection->getEnumCases()) === 1) {
return new ConstantBooleanType(true);
}
}
}
if ($rightType instanceof TypeWithClassName && $leftType instanceof EnumCaseObjectType) {
$classReflection = $rightType->getClassReflection();
if ($classReflection !== null && $classReflection->isEnum() && $classReflection->getName() === $leftType->getClassName()) {
if (count($classReflection->getEnumCases()) === 1) {
return new ConstantBooleanType(true);
}
}
}

$isSuperset = $leftType->isSuperTypeOf($rightType);
if ($isSuperset->no()) {
return new ConstantBooleanType(false);
Expand Down
26 changes: 26 additions & 0 deletions tests/PHPStan/Rules/Comparison/MatchExpressionRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -246,4 +246,30 @@ public function testBug7746(): void
$this->analyse([__DIR__ . '/data/bug-7746.php'], []);
}

public function testBug8240(): void
{
if (PHP_VERSION_ID < 80100) {
$this->markTestSkipped('Test requires PHP 8.1.');
}
$this->treatPhpDocTypesAsCertain = true;
$this->analyse([__DIR__ . '/data/bug-8240.php'], [
[
'Match arm comparison between Bug8240\Foo and Bug8240\Foo::BAR is always true.',
13,
],
[
'Match arm is unreachable because previous comparison is always true.',
14,
],
[
'Match arm comparison between Bug8240\Foo2::BAZ and Bug8240\Foo2::BAZ is always true.',
28,
],
[
'Match arm is unreachable because previous comparison is always true.',
29,
],
]);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,7 @@ public function testBug8586(): void
$this->checkAlwaysTrueStrictComparison = true;
$this->analyse([__DIR__ . '/data/bug-8586.php'], []);
}

public function testBug4242(): void
{
if (PHP_VERSION_ID < 80100) {
Expand Down
31 changes: 31 additions & 0 deletions tests/PHPStan/Rules/Comparison/data/bug-8240.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php // lint >= 8.1

namespace Bug8240;

enum Foo
{
case BAR;
}

function doFoo(Foo $foo): int
{
return match ($foo) {
Foo::BAR => 5,
default => throw new \Exception('This will not be executed')
};
}

enum Foo2
{
case BAR;
case BAZ;
}

function doFoo2(Foo2 $foo): int
{
return match ($foo) {
Foo2::BAR => 5,
Foo2::BAZ => 15,
default => throw new \Exception('This will not be executed')
};
}

0 comments on commit 4968ec6

Please sign in to comment.