Skip to content

Commit 56b1476

Browse files
github-actions[bot]phpstan-bot
authored andcommitted
Fix phpstan/phpstan#10076: Union of string literal and class-string<T> loses literal members
- GenericClassStringType::isSuperTypeOf() returned Yes for non-class-string constants when the generic type was MixedType (including TemplateMixedType) - This caused TypeCombinator::union to absorb string literals like 'object' and 'array' into class-string<T>, losing them from the union - Added a check: when generic type is MixedType but the constant string is not a class-string, return Maybe instead of Yes - New regression test in tests/PHPStan/Rules/Functions/data/bug-10076.php
1 parent 4c6ef6e commit 56b1476

3 files changed

Lines changed: 28 additions & 0 deletions

File tree

src/Type/Generic/GenericClassStringType.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ public function isSuperTypeOf(Type $type): IsSuperTypeOfResult
9494
if ($type instanceof ConstantStringType) {
9595
$genericType = $this->type;
9696
if ($genericType instanceof MixedType) {
97+
if (!$type->isClassString()->yes()) {
98+
return IsSuperTypeOfResult::createMaybe();
99+
}
97100
return IsSuperTypeOfResult::createYes();
98101
}
99102

tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2817,4 +2817,9 @@ public function testBug14312b(): void
28172817
$this->analyse([__DIR__ . '/data/bug-14312b.php'], []);
28182818
}
28192819

2820+
public function testBug10076(): void
2821+
{
2822+
$this->analyse([__DIR__ . '/data/bug-10076.php'], []);
2823+
}
2824+
28202825
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Bug10076;
4+
5+
/**
6+
* @template T
7+
*
8+
* @param 'object'|'array'|class-string<T> $type
9+
*
10+
* @return list<mixed>
11+
*/
12+
function result($type = 'object'): array
13+
{
14+
return [];
15+
}
16+
17+
result();
18+
result('object');
19+
result('array');
20+
result(\DateTime::class);

0 commit comments

Comments
 (0)