Skip to content

Commit 47a820b

Browse files
committed
Special-case LateResolvableType in UnionType::isSuperTypeOf()
1 parent 6bdce5d commit 47a820b

File tree

4 files changed

+74
-2
lines changed

4 files changed

+74
-2
lines changed

src/Type/UnionType.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,7 @@ public function isSuperTypeOf(Type $otherType): IsSuperTypeOfResult
240240
($otherType instanceof self && !$otherType instanceof TemplateUnionType)
241241
|| ($otherType instanceof IterableType && !$otherType instanceof TemplateIterableType)
242242
|| $otherType instanceof NeverType
243-
|| $otherType instanceof ConditionalType
244-
|| $otherType instanceof ConditionalTypeForParameter
243+
|| ($otherType instanceof LateResolvableType && $otherType instanceof CompoundType)
245244
|| $otherType instanceof IntegerRangeType
246245
) {
247246
return $otherType->isSubTypeOf($this);

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ private static function findTestFiles(): iterable
103103

104104
if (PHP_VERSION_ID >= 80000) {
105105
yield __DIR__ . '/../Rules/Comparison/data/bug-4857.php';
106+
yield __DIR__ . '/../Rules/PhpDoc/data/bug-13652.php';
106107
}
107108

108109
yield __DIR__ . '/../Rules/Methods/data/bug-5089.php';

tests/PHPStan/Rules/PhpDoc/IncompatiblePhpDocTypeRuleTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,4 +466,19 @@ public function testBug13452(): void
466466
$this->analyse([__DIR__ . '/data/bug-13452.php'], []);
467467
}
468468

469+
#[RequiresPhp('>= 8.0')]
470+
public function testBug13652(): void
471+
{
472+
$this->analyse([__DIR__ . '/data/bug-13652.php'], [
473+
[
474+
'PHPDoc tag @return with type array{a: string, b: bool, c: int, d: float}[TKey] is not subtype of native type bool|int|string.',
475+
28,
476+
],
477+
[
478+
'PHPDoc tag @param for parameter $value with type array{a: string, b: bool, c: int, d: float}[TKey] is not subtype of native type bool|int|string.',
479+
48,
480+
],
481+
]);
482+
}
483+
469484
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
namespace Bug13652;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
/**
8+
* @phpstan-type Bob array{a: string, b: bool, c: int, d: float}
9+
*/
10+
class Y {
11+
public function __construct(/** @var Bob */ public array $bob) {}
12+
13+
/**
14+
* @template TKey of key-of<Bob>
15+
* @param TKey $key
16+
* @return Bob[TKey]
17+
*/
18+
public function x(string $key): string|bool|int|float
19+
{
20+
return $this->bob[$key];
21+
}
22+
23+
/**
24+
* @template TKey of key-of<Bob>
25+
* @param TKey $key
26+
* @return Bob[TKey]
27+
*/
28+
public function x2(string $key): string|bool|int
29+
{
30+
return $this->bob[$key];
31+
}
32+
33+
/**
34+
* @template TKey of key-of<Bob>
35+
* @param TKey $key
36+
* @param Bob[TKey] $value
37+
*/
38+
public function x3(string $key, string|bool|int|float $value): void
39+
{
40+
41+
}
42+
43+
/**
44+
* @template TKey of key-of<Bob>
45+
* @param TKey $key
46+
* @param Bob[TKey] $value
47+
*/
48+
public function x4(string $key, string|bool|int $value): void
49+
{
50+
51+
}
52+
}
53+
54+
function (): void {
55+
$y = new Y(['a' => 'y', 'b' => true, 'c' => 99, 'd' => 4.2]);
56+
assertType('bool', $y->x('b'));
57+
};

0 commit comments

Comments
 (0)