Skip to content

Commit 9121f72

Browse files
Improve
1 parent c5a4041 commit 9121f72

File tree

2 files changed

+55
-1
lines changed

2 files changed

+55
-1
lines changed

src/Type/UnionType.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use PHPStan\Type\Generic\GenericClassStringType;
2323
use PHPStan\Type\Generic\TemplateMixedType;
2424
use PHPStan\Type\Generic\TemplateType;
25+
use PHPStan\Type\Generic\TemplateTypeFactory;
2526
use PHPStan\Type\Generic\TemplateTypeMap;
2627
use PHPStan\Type\Generic\TemplateTypeVariance;
2728
use PHPStan\Type\Generic\TemplateUnionType;
@@ -106,7 +107,22 @@ public function filterTypes(callable $filterCb): Type
106107
return $this;
107108
}
108109

109-
return TypeCombinator::union(...$newTypes);
110+
$result = TypeCombinator::union(...$newTypes);
111+
if ($this instanceof BenevolentUnionType) {
112+
$result = TypeUtils::toBenevolentUnion($result);
113+
}
114+
if ($this instanceof TemplateType) {
115+
$result = TemplateTypeFactory::create(
116+
$this->getScope(),
117+
$this->getName(),
118+
$result,
119+
$this->getVariance(),
120+
$this->getStrategy(),
121+
$this->getDefault(),
122+
);
123+
}
124+
125+
return $result;
110126
}
111127

112128
public function isNormalized(): bool

tests/PHPStan/Rules/Methods/data/bug-11663.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ public function where(string $test)
2626
}
2727
}
2828

29+
interface A
30+
{
31+
public function doFoo(): static;
32+
}
33+
34+
interface B
35+
{
36+
}
2937

3038
class Test
3139
{
@@ -38,4 +46,34 @@ public function test($template)
3846
{
3947
return $template->where('test');
4048
}
49+
50+
/**
51+
* @param __benevolent<BuilderA|BuilderB|false> $template
52+
* @return __benevolent<BuilderA|BuilderB>
53+
*/
54+
public function test2($template)
55+
{
56+
return $template->where('test');
57+
}
58+
59+
60+
/**
61+
* @template T of A|B
62+
* @param T $ab
63+
* @return T
64+
*/
65+
function foo(A|B $ab): A|B
66+
{
67+
return $ab->doFoo();
68+
}
69+
70+
/**
71+
* @template T of __benevolent<A|B>
72+
* @param T $ab
73+
* @return T
74+
*/
75+
function foo2(A|B $ab): A|B
76+
{
77+
return $ab->doFoo();
78+
}
4179
}

0 commit comments

Comments
 (0)