Skip to content

Commit

Permalink
Union normalization - do not take template types apart
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Aug 22, 2021
1 parent 4e7d6c1 commit 3b17c0e
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/Type/TypeCombinator.php
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,9 @@ public static function union(Type ...$types): Type
if (!($types[$i] instanceof UnionType)) {
continue;
}
if ($types[$i] instanceof TemplateType) {
continue;
}

array_splice($types, $i, 1, $types[$i]->getTypes());
}
Expand Down
3 changes: 3 additions & 0 deletions src/Type/UnionType.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public function __construct(array $types)
if (!($type instanceof UnionType)) {
continue;
}
if ($type instanceof TemplateType) {
continue;
}

$throwException();
}
Expand Down
25 changes: 25 additions & 0 deletions tests/PHPStan/Analyser/data/generics.php
Original file line number Diff line number Diff line change
Expand Up @@ -1437,3 +1437,28 @@ function (float $f): void {
assertType('1.0', floatBound(1.0));
assertType('float', floatBound($f));
};

/**
* @template T of string|int|float|bool
*/
class UnionT
{

/**
* @param T|null $t
* @return T|null
*/
public function doFoo($t)
{
return $t;
}

}

/**
* @param UnionT<string> $foo
*/
function foooo(UnionT $foo): void
{
assertType('string|null', $foo->doFoo('a'));
}
18 changes: 18 additions & 0 deletions tests/PHPStan/Type/TypeCombinatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1804,6 +1804,24 @@ public function dataUnion(): array
UnionType::class,
'string|false',
],
[
[
TemplateTypeFactory::create(
TemplateTypeScope::createWithFunction('doFoo'),
'T',
new UnionType([
new StringType(),
new IntegerType(),
new FloatType(),
new BooleanType(),
]),
TemplateTypeVariance::createInvariant()
),
new NullType(),
],
UnionType::class,
'T of bool|float|int|string (function doFoo(), parameter)|null',
],
];
}

Expand Down

0 comments on commit 3b17c0e

Please sign in to comment.