Skip to content

Commit 3c142df

Browse files
authored
Merge branch refs/heads/1.10.x into 1.11.x
2 parents ae67c8c + 73a926c commit 3c142df

File tree

4 files changed

+44
-11
lines changed

4 files changed

+44
-11
lines changed

src/Analyser/MutatingScope.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5063,11 +5063,13 @@ private function exactInstantiation(New_ $node, string $className): ?Type
50635063
return $type->getBound();
50645064
}
50655065

5066-
$isArrayKey = $type->getBound()->describe(VerbosityLevel::precise()) === '(int|string)';
5067-
if ($newType->isScalar()->yes() && !$type->getVariance()->covariant() && $isArrayKey) {
5068-
$newType = $newType->generalize(GeneralizePrecision::templateArgument());
5069-
} elseif ($newType->isConstantValue()->yes() && (!$type->getBound()->isScalar()->yes() || $isArrayKey)) {
5070-
$newType = $newType->generalize(GeneralizePrecision::templateArgument());
5066+
if (!$type->getVariance()->covariant()) {
5067+
$isArrayKey = $type->getBound()->describe(VerbosityLevel::precise()) === '(int|string)';
5068+
if ($newType->isScalar()->yes() && $isArrayKey) {
5069+
$newType = $newType->generalize(GeneralizePrecision::templateArgument());
5070+
} elseif ($newType->isConstantValue()->yes() && (!$type->getBound()->isScalar()->yes() || $isArrayKey)) {
5071+
$newType = $newType->generalize(GeneralizePrecision::templateArgument());
5072+
}
50715073
}
50725074

50735075
return $newType;

src/Reflection/ResolvedFunctionVariant.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,13 @@ private function resolveResolvableTemplateTypes(Type $type, TemplateTypeVariance
184184
return $traverse($type);
185185
}
186186

187-
$isArrayKey = $type->getBound()->describe(VerbosityLevel::precise()) === '(int|string)';
188-
if ($newType->isScalar()->yes() && !$type->getVariance()->covariant() && $isArrayKey) {
189-
$newType = $newType->generalize(GeneralizePrecision::templateArgument());
190-
} elseif ($newType->isConstantValue()->yes() && (!$type->getBound()->isScalar()->yes() || $isArrayKey)) {
191-
$newType = $newType->generalize(GeneralizePrecision::templateArgument());
187+
if (!$type->getVariance()->covariant()) {
188+
$isArrayKey = $type->getBound()->describe(VerbosityLevel::precise()) === '(int|string)';
189+
if ($newType->isScalar()->yes() && $isArrayKey) {
190+
$newType = $newType->generalize(GeneralizePrecision::templateArgument());
191+
} elseif ($newType->isConstantValue()->yes() && (!$type->getBound()->isScalar()->yes() || $isArrayKey)) {
192+
$newType = $newType->generalize(GeneralizePrecision::templateArgument());
193+
}
192194
}
193195

194196
$variance = TemplateTypeVariance::createInvariant();

tests/PHPStan/Analyser/data/bug-7078.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,5 @@ public function get(TypeDefault ...$type);
3333

3434
function (Param $p) {
3535
$result = $p->get(new TypeDefault(1), new TypeDefault('a'));
36-
assertType('int|string', $result);
36+
assertType('1|\'a\'', $result);
3737
};

tests/PHPStan/Analyser/data/generics-do-not-generalize.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,32 @@ function (): void {
117117

118118
assertType('ArrayIterator<int, string>', createArrayIterator($a));
119119
};
120+
121+
/** @template T */
122+
class FooInvariant
123+
{
124+
125+
/** @param T $p */
126+
public function __construct($p)
127+
{
128+
129+
}
130+
131+
}
132+
133+
/** @template-covariant T */
134+
class FooCovariant
135+
{
136+
137+
/** @param T $p */
138+
public function __construct($p)
139+
{
140+
141+
}
142+
143+
}
144+
145+
function (): void {
146+
assertType('GenericsDoNotGeneralize\\FooInvariant<int>', new FooInvariant(1));
147+
assertType('GenericsDoNotGeneralize\\FooCovariant<1>', new FooCovariant(1));
148+
};

0 commit comments

Comments
 (0)