Skip to content

Commit 91f1650

Browse files
Fix issue with template of union
1 parent 9798bd4 commit 91f1650

File tree

4 files changed

+53
-0
lines changed

4 files changed

+53
-0
lines changed

src/Analyser/MutatingScope.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
use PHPStan\Type\Generic\TemplateTypeHelper;
107107
use PHPStan\Type\Generic\TemplateTypeMap;
108108
use PHPStan\Type\Generic\TemplateTypeVarianceMap;
109+
use PHPStan\Type\Generic\TemplateUnionType;
109110
use PHPStan\Type\IntegerRangeType;
110111
use PHPStan\Type\IntegerType;
111112
use PHPStan\Type\IntersectionType;

src/Type/UnionType.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,20 @@ public function getTypes(): array
9292
public function filterTypes(callable $filterCb): Type
9393
{
9494
$newTypes = [];
95+
$changed = false;
9596
foreach ($this->getTypes() as $innerType) {
9697
if (!$filterCb($innerType)) {
98+
$changed = true;
9799
continue;
98100
}
99101

100102
$newTypes[] = $innerType;
101103
}
102104

105+
if (!$changed) {
106+
return $this;
107+
}
108+
103109
return TypeCombinator::union(...$newTypes);
104110
}
105111

tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,4 +1054,9 @@ public function testBug10715(): void
10541054
$this->analyse([__DIR__ . '/data/bug-10715.php'], []);
10551055
}
10561056

1057+
public function testBug11663(): void
1058+
{
1059+
$this->analyse([__DIR__ . '/data/bug-11663.php'], []);
1060+
}
1061+
10571062
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug11663;
4+
5+
class BuilderA
6+
{
7+
/**
8+
* @param string $test
9+
* @return $this
10+
*/
11+
public function where(string $test)
12+
{
13+
return $this;
14+
}
15+
}
16+
17+
class BuilderB
18+
{
19+
/**
20+
* @param string $test
21+
* @return $this
22+
*/
23+
public function where(string $test)
24+
{
25+
return $this;
26+
}
27+
}
28+
29+
30+
class Test
31+
{
32+
/**
33+
* @template B of BuilderA|BuilderB
34+
* @param B $template
35+
* @return B
36+
*/
37+
public function test($template)
38+
{
39+
return $template->where('test');
40+
}
41+
}

0 commit comments

Comments
 (0)