Skip to content

Commit d3e3292

Browse files
committed
Fix intersection of two identical ThisType
1 parent b510dda commit d3e3292

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

Diff for: src/Type/ThisType.php

+32
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PHPStan\Reflection\ClassReflection;
66
use PHPStan\Reflection\ReflectionProviderStaticAccessor;
77
use PHPStan\TrinaryLogic;
8+
use function get_class;
89
use function sprintf;
910

1011
/** @api */
@@ -23,6 +24,33 @@ public function __construct(
2324
parent::__construct($classReflection, $subtractedType);
2425
}
2526

27+
public function equals(Type $type): bool
28+
{
29+
if (get_class($type) !== static::class) {
30+
return false;
31+
}
32+
33+
/** @var ThisType $type */
34+
$type = $type;
35+
$equals = $this->getStaticObjectType()->equals($type->getStaticObjectType());
36+
if (!$equals) {
37+
return false;
38+
}
39+
40+
if ($this->getTraitReflection() === null) {
41+
if ($type->getTraitReflection() === null) {
42+
return true;
43+
}
44+
45+
return false;
46+
}
47+
if ($type->getTraitReflection() === null) {
48+
return false;
49+
}
50+
51+
return $this->getTraitReflection()->getName() === $type->getTraitReflection()->getName();
52+
}
53+
2654
public function changeBaseClass(ClassReflection $classReflection): StaticType
2755
{
2856
return new self($classReflection, $this->getSubtractedType(), $this->traitReflection);
@@ -50,6 +78,10 @@ function () use ($callback): string {
5078
public function isSuperTypeOf(Type $type): TrinaryLogic
5179
{
5280
if ($type instanceof self) {
81+
if ($this->equals($type)) {
82+
return TrinaryLogic::createYes();
83+
}
84+
5385
return $this->getStaticObjectType()->isSuperTypeOf($type);
5486
}
5587

Diff for: tests/PHPStan/Analyser/data/trait-instance-of.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function test(): string {
4343
}
4444

4545
if ($this instanceof ATrait1Class) {
46-
assertType('*NEVER*', $this);
46+
assertType('$this(TraitInstanceOf\FinalTrait2Class~TraitInstanceOf\FinalTrait2Class)&TraitInstanceOf\ATrait1Class', $this);
4747
return 'hello world';
4848
}
4949

Diff for: tests/PHPStan/Type/TypeCombinatorTest.php

+11
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
use Test\ClassWithToString;
4848
use Test\FirstInterface;
4949
use Throwable;
50+
use TraitInstanceOf\ATrait1Class;
51+
use TraitInstanceOf\Trait1;
5052
use Traversable;
5153
use function array_map;
5254
use function array_reverse;
@@ -3978,6 +3980,15 @@ public function dataIntersect(): iterable
39783980
IntersectionType::class,
39793981
'$this(TraitInstanceOf\FinalTrait2Class~TraitInstanceOf\FinalOther)&NonExistantClass',
39803982
];
3983+
3984+
yield [
3985+
[
3986+
new ThisType($reflectionProvider->getClass(ATrait1Class::class), null, $reflectionProvider->getClass(Trait1::class)),
3987+
new ThisType($reflectionProvider->getClass(ATrait1Class::class), null, $reflectionProvider->getClass(Trait1::class)),
3988+
],
3989+
ThisType::class,
3990+
'$this(TraitInstanceOf\ATrait1Class)',
3991+
];
39813992
}
39823993

39833994
/**

0 commit comments

Comments
 (0)