Skip to content

Commit 3b17c0e

Browse files
committed
Union normalization - do not take template types apart
1 parent 4e7d6c1 commit 3b17c0e

File tree

4 files changed

+49
-0
lines changed

4 files changed

+49
-0
lines changed

src/Type/TypeCombinator.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ public static function union(Type ...$types): Type
185185
if (!($types[$i] instanceof UnionType)) {
186186
continue;
187187
}
188+
if ($types[$i] instanceof TemplateType) {
189+
continue;
190+
}
188191

189192
array_splice($types, $i, 1, $types[$i]->getTypes());
190193
}

src/Type/UnionType.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ public function __construct(array $types)
4646
if (!($type instanceof UnionType)) {
4747
continue;
4848
}
49+
if ($type instanceof TemplateType) {
50+
continue;
51+
}
4952

5053
$throwException();
5154
}

tests/PHPStan/Analyser/data/generics.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,3 +1437,28 @@ function (float $f): void {
14371437
assertType('1.0', floatBound(1.0));
14381438
assertType('float', floatBound($f));
14391439
};
1440+
1441+
/**
1442+
* @template T of string|int|float|bool
1443+
*/
1444+
class UnionT
1445+
{
1446+
1447+
/**
1448+
* @param T|null $t
1449+
* @return T|null
1450+
*/
1451+
public function doFoo($t)
1452+
{
1453+
return $t;
1454+
}
1455+
1456+
}
1457+
1458+
/**
1459+
* @param UnionT<string> $foo
1460+
*/
1461+
function foooo(UnionT $foo): void
1462+
{
1463+
assertType('string|null', $foo->doFoo('a'));
1464+
}

tests/PHPStan/Type/TypeCombinatorTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1804,6 +1804,24 @@ public function dataUnion(): array
18041804
UnionType::class,
18051805
'string|false',
18061806
],
1807+
[
1808+
[
1809+
TemplateTypeFactory::create(
1810+
TemplateTypeScope::createWithFunction('doFoo'),
1811+
'T',
1812+
new UnionType([
1813+
new StringType(),
1814+
new IntegerType(),
1815+
new FloatType(),
1816+
new BooleanType(),
1817+
]),
1818+
TemplateTypeVariance::createInvariant()
1819+
),
1820+
new NullType(),
1821+
],
1822+
UnionType::class,
1823+
'T of bool|float|int|string (function doFoo(), parameter)|null',
1824+
],
18071825
];
18081826
}
18091827

0 commit comments

Comments
 (0)