Skip to content

Commit 6147f91

Browse files
phpstan-botVincentLangletclaudestaabm
authored
Check inner union types before delegating to isSubTypeOf for LateResolvableType in UnionType::isSuperTypeOf() (#5645)
Co-authored-by: VincentLanglet <9052536+VincentLanglet@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Markus Staab <maggus.staab@googlemail.com>
1 parent 86f8b7a commit 6147f91

3 files changed

Lines changed: 70 additions & 2 deletions

File tree

src/Type/UnionType.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,6 @@ public function isSuperTypeOf(Type $otherType): IsSuperTypeOfResult
268268
($otherType instanceof self && !$otherType instanceof TemplateUnionType)
269269
|| ($otherType instanceof IterableType && !$otherType instanceof TemplateIterableType)
270270
|| $otherType instanceof NeverType
271-
|| ($otherType instanceof LateResolvableType && $otherType instanceof CompoundType && !$otherType instanceof TemplateType)
272271
|| $otherType instanceof IntegerRangeType
273272
) {
274273
return $otherType->isSubTypeOf($this);
@@ -284,7 +283,10 @@ public function isSuperTypeOf(Type $otherType): IsSuperTypeOfResult
284283
}
285284
$result = IsSuperTypeOfResult::createNo()->or(...$results);
286285

287-
if ($otherType instanceof TemplateUnionType) {
286+
if (
287+
$otherType instanceof TemplateUnionType
288+
|| ($otherType instanceof LateResolvableType && $otherType instanceof CompoundType && !$otherType instanceof TemplateType)
289+
) {
288290
return $result->or($otherType->isSubTypeOf($this));
289291
}
290292

tests/PHPStan/Rules/Methods/MethodSignatureRuleTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,4 +630,12 @@ public function testBug14563Trait(): void
630630
]);
631631
}
632632

633+
#[RequiresPhp('>= 8.0.0')]
634+
public function testBug10942(): void
635+
{
636+
$this->reportMaybes = true;
637+
$this->reportStatic = true;
638+
$this->analyse([__DIR__ . '/data/bug-10942.php'], []);
639+
}
640+
633641
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php // lint >= 8.0
2+
3+
namespace Bug10942;
4+
5+
class A
6+
{
7+
/**
8+
* @param string|($operator is 'in' ? int : never) $sqlRight
9+
*/
10+
protected function _renderConditionBinary(string $operator, string $sqlLeft, $sqlRight): string
11+
{
12+
return 'x';
13+
}
14+
}
15+
16+
class B extends A
17+
{
18+
protected function _renderConditionBinary(string $operator, string $sqlLeft, $sqlRight): string
19+
{
20+
return 'y';
21+
}
22+
}
23+
24+
class C
25+
{
26+
/**
27+
* @param string|($x is int ? float : bool) $y
28+
*/
29+
public function foo(mixed $x, mixed $y): void
30+
{
31+
}
32+
33+
/**
34+
* @return string|($x is int ? float : bool)
35+
*/
36+
public function bar(mixed $x): mixed
37+
{
38+
return '';
39+
}
40+
}
41+
42+
class D extends C
43+
{
44+
/**
45+
* @param string|($x is int ? float : bool) $y
46+
*/
47+
public function foo(mixed $x, mixed $y): void
48+
{
49+
}
50+
51+
/**
52+
* @return string|($x is int ? float : bool)
53+
*/
54+
public function bar(mixed $x): mixed
55+
{
56+
return '';
57+
}
58+
}

0 commit comments

Comments
 (0)