Skip to content

Commit 0dbe3ab

Browse files
committedMar 7, 2023
Fix interface accepting a Closure
1 parent cfb784a commit 0dbe3ab

File tree

4 files changed

+74
-0
lines changed

4 files changed

+74
-0
lines changed
 

‎src/Type/ObjectType.php

+12
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,10 @@ public function isSuperTypeOf(Type $type): TrinaryLogic
325325
return self::$superTypes[$thisDescription][$description] = $type->isSubTypeOf($this);
326326
}
327327

328+
if ($type instanceof ClosureType) {
329+
return self::$superTypes[$thisDescription][$description] = $this->isInstanceOf(Closure::class);
330+
}
331+
328332
if ($type instanceof ObjectWithoutClassType) {
329333
if ($type->getSubtractedType() !== null) {
330334
$isSuperType = $type->getSubtractedType()->isSuperTypeOf($this);
@@ -1289,6 +1293,14 @@ public function isInstanceOf(string $className): TrinaryLogic
12891293
return TrinaryLogic::createYes();
12901294
}
12911295

1296+
$reflectionProvider = ReflectionProviderStaticAccessor::getInstance();
1297+
if ($reflectionProvider->hasClass($className)) {
1298+
$thatClassReflection = $reflectionProvider->getClass($className);
1299+
if ($thatClassReflection->isFinal()) {
1300+
return TrinaryLogic::createNo();
1301+
}
1302+
}
1303+
12921304
if ($classReflection->isInterface()) {
12931305
return TrinaryLogic::createMaybe();
12941306
}

‎tests/PHPStan/Type/ObjectTypeTest.php

+21
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use ArrayAccess;
66
use ArrayObject;
77
use Bug8850\UserInSessionInRoleEndpointExtension;
8+
use Bug9006\TestInterface;
89
use Closure;
910
use Countable;
1011
use DateInterval;
@@ -438,6 +439,16 @@ public function dataIsSuperTypeOf(): array
438439
new ThisType($reflectionProvider->getClass(UserInSessionInRoleEndpointExtension::class)),
439440
TrinaryLogic::createYes(),
440441
],
442+
62 => [
443+
new ObjectType(TestInterface::class),
444+
new ClosureType([], new MixedType(), false),
445+
TrinaryLogic::createNo(),
446+
],
447+
63 => [
448+
new ObjectType(TestInterface::class),
449+
new ObjectType(Closure::class),
450+
TrinaryLogic::createNo(),
451+
],
441452
];
442453
}
443454

@@ -492,6 +503,16 @@ public function dataAccepts(): array
492503
),
493504
TrinaryLogic::createNo(),
494505
],
506+
[
507+
new ObjectType(TestInterface::class),
508+
new ClosureType([], new MixedType(), false),
509+
TrinaryLogic::createNo(),
510+
],
511+
63 => [
512+
new ObjectType(TestInterface::class),
513+
new ObjectType(Closure::class),
514+
TrinaryLogic::createNo(),
515+
],
495516
];
496517
}
497518

‎tests/PHPStan/Type/TypeCombinatorTest.php

+33
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace PHPStan\Type;
44

5+
use Bug9006\TestInterface;
56
use CheckTypeFunctionCall\FinalClassWithMethodExists;
67
use CheckTypeFunctionCall\FinalClassWithPropertyExists;
78
use Closure;
@@ -2331,6 +2332,22 @@ public function dataUnion(): iterable
23312332
IntersectionType::class,
23322333
'array<int, string>&oversized-array',
23332334
];
2335+
yield [
2336+
[
2337+
new ObjectType(TestInterface::class),
2338+
new ClosureType([], new MixedType(), false),
2339+
],
2340+
UnionType::class,
2341+
'Bug9006\TestInterface|(Closure(): mixed)',
2342+
];
2343+
yield [
2344+
[
2345+
new ObjectType(TestInterface::class),
2346+
new ObjectType(Closure::class),
2347+
],
2348+
UnionType::class,
2349+
'Bug9006\TestInterface|Closure',
2350+
];
23342351
}
23352352

23362353
/**
@@ -3783,6 +3800,22 @@ public function dataIntersect(): iterable
37833800
IntersectionType::class,
37843801
'array<int, string>&oversized-array',
37853802
];
3803+
yield [
3804+
[
3805+
new ObjectType(TestInterface::class),
3806+
new ClosureType([], new MixedType(), false),
3807+
],
3808+
NeverType::class,
3809+
'*NEVER*=implicit',
3810+
];
3811+
yield [
3812+
[
3813+
new ObjectType(TestInterface::class),
3814+
new ObjectType(Closure::class),
3815+
],
3816+
NeverType::class,
3817+
'*NEVER*=implicit',
3818+
];
37863819
}
37873820

37883821
/**

‎tests/PHPStan/Type/data/bug-9006.php

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Bug9006;
4+
5+
interface TestInterface
6+
{
7+
8+
}

0 commit comments

Comments
 (0)
Please sign in to comment.