Skip to content

Commit 8efca2a

Browse files
staabmondrejmirtes
authored andcommitted
Implement identical/equal comparisons on EnumCaseObjectType
1 parent 86115f1 commit 8efca2a

File tree

5 files changed

+112
-2
lines changed

5 files changed

+112
-2
lines changed

src/Reflection/InitializerExprTypeResolver.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1329,6 +1329,10 @@ public function resolveIdenticalType(Type $leftType, Type $rightType): BooleanTy
13291329
return new ConstantBooleanType($leftType->getValue() === $rightType->getValue());
13301330
}
13311331

1332+
if ($leftType instanceof EnumCaseObjectType && $rightType instanceof EnumCaseObjectType) {
1333+
return new ConstantBooleanType($leftType->equals($rightType));
1334+
}
1335+
13321336
$isSuperset = $leftType->isSuperTypeOf($rightType);
13331337
if ($isSuperset->no()) {
13341338
return new ConstantBooleanType(false);
@@ -1345,8 +1349,10 @@ public function resolveEqualType(Type $leftType, Type $rightType): BooleanType
13451349
{
13461350
$integerType = new IntegerType();
13471351
$floatType = new FloatType();
1352+
13481353
if (
1349-
($leftType->isString()->yes() && $rightType->isString()->yes())
1354+
($leftType instanceof EnumCaseObjectType && $rightType instanceof EnumCaseObjectType)
1355+
|| ($leftType->isString()->yes() && $rightType->isString()->yes())
13501356
|| ($integerType->isSuperTypeOf($leftType)->yes() && $integerType->isSuperTypeOf($rightType)->yes())
13511357
|| ($floatType->isSuperTypeOf($leftType)->yes() && $floatType->isSuperTypeOf($rightType)->yes())
13521358
) {

tests/PHPStan/Rules/Comparison/IfConstantConditionRuleTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PHPStan\Rules\Rule;
66
use PHPStan\Testing\RuleTestCase;
7+
use const PHP_VERSION_ID;
78

89
/**
910
* @extends RuleTestCase<IfConstantConditionRule>
@@ -129,4 +130,27 @@ public function testBug6902(): void
129130
$this->analyse([__DIR__ . '/data/bug-6902.php'], []);
130131
}
131132

133+
public function testBug8485(): void
134+
{
135+
if (PHP_VERSION_ID < 80100) {
136+
$this->markTestSkipped('Test requires PHP 8.1.');
137+
}
138+
139+
$this->treatPhpDocTypesAsCertain = true;
140+
$this->analyse([__DIR__ . '/data/bug-8485.php'], [
141+
[
142+
'If condition is always true.',
143+
19,
144+
],
145+
[
146+
'If condition is always false.',
147+
24,
148+
],
149+
[
150+
'If condition is always false.',
151+
29,
152+
],
153+
]);
154+
}
155+
132156
}

tests/PHPStan/Rules/Comparison/MatchExpressionRuleTest.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,11 @@ public function testEnums(): void
153153
56,
154154
],
155155
[
156-
'Match arm comparison between *NEVER* and MatchEnums\Foo is always false.',
156+
'Match arm comparison between MatchEnums\Foo::THREE and MatchEnums\Foo::THREE is always true.',
157+
76,
158+
],
159+
[
160+
'Match arm is unreachable because previous comparison is always true.',
157161
77,
158162
],
159163
]);

tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,37 @@ public function testBug8158(): void
607607
$this->analyse([__DIR__ . '/data/bug-8158.php'], []);
608608
}
609609

610+
public function testBug8485(): void
611+
{
612+
if (PHP_VERSION_ID < 80100) {
613+
$this->markTestSkipped('Test requires PHP 8.1.');
614+
}
615+
616+
$this->checkAlwaysTrueStrictComparison = true;
617+
$this->analyse([__DIR__ . '/data/bug-8485.php'], [
618+
[
619+
'Strict comparison using === between Bug8485\E::c and Bug8485\E::c will always evaluate to true.',
620+
17,
621+
],
622+
[
623+
'Strict comparison using === between Bug8485\F::c and Bug8485\E::c will always evaluate to false.',
624+
22,
625+
],
626+
[
627+
'Strict comparison using === between Bug8485\F::c and Bug8485\E::c will always evaluate to false.',
628+
27,
629+
],
630+
[
631+
'Strict comparison using === between Bug8485\F and Bug8485\E will always evaluate to false.',
632+
35,
633+
],
634+
[
635+
'Strict comparison using === between Bug8485\F and Bug8485\E::c will always evaluate to false.',
636+
40,
637+
],
638+
]);
639+
}
640+
610641
public function testPhpUnitIntegration(): void
611642
{
612643
$this->checkAlwaysTrueStrictComparison = true;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php // lint >= 8.1
2+
3+
namespace Bug8485;
4+
5+
enum E {
6+
case c;
7+
}
8+
9+
enum F {
10+
case c;
11+
}
12+
13+
function shouldError():void {
14+
$e = E::c;
15+
$f = F::c;
16+
17+
if ($e === E::c) {
18+
}
19+
if ($e == E::c) {
20+
}
21+
22+
if ($f === $e) {
23+
}
24+
if ($f == $e) {
25+
}
26+
27+
if ($f === E::c) {
28+
}
29+
if ($f == E::c) {
30+
}
31+
}
32+
33+
34+
function allGood(E $e, F $f):void {
35+
if ($f === $e) {
36+
}
37+
if ($f == $e) {
38+
}
39+
40+
if ($f === E::c) {
41+
}
42+
if ($f == E::c) {
43+
}
44+
}
45+

0 commit comments

Comments
 (0)