Skip to content

Commit 39fe102

Browse files
committed
Deduplicate inferred template type generalization logic
1 parent a532baf commit 39fe102

File tree

3 files changed

+18
-21
lines changed

3 files changed

+18
-21
lines changed

src/Analyser/MutatingScope.php

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

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-
}
5073-
}
5074-
5075-
return $newType;
5066+
return TemplateTypeHelper::generalizeInferredTemplateType($type, $newType);
50765067
}
50775068

50785069
return $traverse($type);

src/Reflection/ResolvedFunctionVariant.php

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
use PHPStan\Reflection\Php\DummyParameterWithPhpDocs;
77
use PHPStan\Type\ConditionalTypeForParameter;
88
use PHPStan\Type\ErrorType;
9-
use PHPStan\Type\GeneralizePrecision;
109
use PHPStan\Type\Generic\GenericObjectType;
1110
use PHPStan\Type\Generic\TemplateType;
1211
use PHPStan\Type\Generic\TemplateTypeHelper;
@@ -17,7 +16,6 @@
1716
use PHPStan\Type\Type;
1817
use PHPStan\Type\TypeTraverser;
1918
use PHPStan\Type\TypeUtils;
20-
use PHPStan\Type\VerbosityLevel;
2119
use function array_key_exists;
2220
use function array_map;
2321

@@ -184,15 +182,7 @@ private function resolveResolvableTemplateTypes(Type $type, TemplateTypeVariance
184182
return $traverse($type);
185183
}
186184

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-
}
194-
}
195-
185+
$newType = TemplateTypeHelper::generalizeInferredTemplateType($type, $newType);
196186
$variance = TemplateTypeVariance::createInvariant();
197187
foreach ($references as $reference) {
198188
// this uses identity to distinguish between different occurrences of the same template type

src/Type/Generic/TemplateTypeHelper.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
namespace PHPStan\Type\Generic;
44

55
use PHPStan\Type\ErrorType;
6+
use PHPStan\Type\GeneralizePrecision;
67
use PHPStan\Type\NonAcceptingNeverType;
78
use PHPStan\Type\Type;
89
use PHPStan\Type\TypeTraverser;
10+
use PHPStan\Type\VerbosityLevel;
911

1012
class TemplateTypeHelper
1113
{
@@ -93,4 +95,18 @@ public static function toArgument(Type $type): Type
9395
});
9496
}
9597

98+
public static function generalizeInferredTemplateType(TemplateType $templateType, Type $type): Type
99+
{
100+
if (!$templateType->getVariance()->covariant()) {
101+
$isArrayKey = $templateType->getBound()->describe(VerbosityLevel::precise()) === '(int|string)';
102+
if ($type->isScalar()->yes() && $isArrayKey) {
103+
$type = $type->generalize(GeneralizePrecision::templateArgument());
104+
} elseif ($type->isConstantValue()->yes() && (!$templateType->getBound()->isScalar()->yes() || $isArrayKey)) {
105+
$type = $type->generalize(GeneralizePrecision::templateArgument());
106+
}
107+
}
108+
109+
return $type;
110+
}
111+
96112
}

0 commit comments

Comments
 (0)