Skip to content

Commit 844c506

Browse files
phpstan-botclaude
andcommitted
Move HasOffset generalization logic into the type classes themselves
Instead of hardcoding `new MixedType()` in TemplateTypeHelper, add `generalize(GeneralizePrecision::templateArgument())` overrides to HasOffsetValueType and HasOffsetType that return MixedType. The TypeTraverser in generalizeInferredTemplateType now delegates to the type's own generalize() method. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 9f0b709 commit 844c506

3 files changed

Lines changed: 27 additions & 4 deletions

File tree

src/Type/Accessory/HasOffsetType.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use PHPStan\Type\Constant\ConstantStringType;
1414
use PHPStan\Type\Enum\EnumCaseObjectType;
1515
use PHPStan\Type\ErrorType;
16+
use PHPStan\Type\GeneralizePrecision;
1617
use PHPStan\Type\IntegerRangeType;
1718
use PHPStan\Type\IntersectionType;
1819
use PHPStan\Type\IsSuperTypeOfResult;
@@ -44,7 +45,9 @@ class HasOffsetType implements CompoundType, AccessoryType
4445
use NonGenericTypeTrait;
4546
use UndecidedComparisonCompoundTypeTrait;
4647
use NonRemoveableTypeTrait;
47-
use NonGeneralizableTypeTrait;
48+
use NonGeneralizableTypeTrait {
49+
generalize as traitGeneralize;
50+
}
4851

4952
/**
5053
* @api
@@ -53,6 +56,15 @@ public function __construct(private ConstantStringType|ConstantIntegerType $offs
5356
{
5457
}
5558

59+
public function generalize(GeneralizePrecision $precision): Type
60+
{
61+
if ($precision->isTemplateArgument()) {
62+
return new MixedType();
63+
}
64+
65+
return $this->traitGeneralize($precision);
66+
}
67+
5668
public function getOffsetType(): ConstantStringType|ConstantIntegerType
5769
{
5870
return $this->offsetType;

src/Type/Accessory/HasOffsetValueType.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use PHPStan\Type\ConstantScalarType;
1616
use PHPStan\Type\Enum\EnumCaseObjectType;
1717
use PHPStan\Type\ErrorType;
18+
use PHPStan\Type\GeneralizePrecision;
1819
use PHPStan\Type\IntegerRangeType;
1920
use PHPStan\Type\IntegerType;
2021
use PHPStan\Type\IntersectionType;
@@ -48,12 +49,23 @@ class HasOffsetValueType implements CompoundType, AccessoryType
4849
use NonGenericTypeTrait;
4950
use UndecidedComparisonCompoundTypeTrait;
5051
use NonRemoveableTypeTrait;
51-
use NonGeneralizableTypeTrait;
52+
use NonGeneralizableTypeTrait {
53+
generalize as traitGeneralize;
54+
}
5255

5356
public function __construct(private ConstantStringType|ConstantIntegerType $offsetType, private Type $valueType)
5457
{
5558
}
5659

60+
public function generalize(GeneralizePrecision $precision): Type
61+
{
62+
if ($precision->isTemplateArgument()) {
63+
return new MixedType();
64+
}
65+
66+
return $this->traitGeneralize($precision);
67+
}
68+
5769
public function getOffsetType(): ConstantStringType|ConstantIntegerType
5870
{
5971
return $this->offsetType;

src/Type/Generic/TemplateTypeHelper.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use PHPStan\Type\Accessory\HasOffsetValueType;
88
use PHPStan\Type\ErrorType;
99
use PHPStan\Type\GeneralizePrecision;
10-
use PHPStan\Type\MixedType;
1110
use PHPStan\Type\NonAcceptingNeverType;
1211
use PHPStan\Type\Type;
1312
use PHPStan\Type\TypeTraverser;
@@ -153,7 +152,7 @@ public static function generalizeInferredTemplateType(TemplateType $templateType
153152

154153
$type = TypeTraverser::map($type, static function (Type $type, callable $traverse): Type {
155154
if ($type instanceof HasOffsetValueType || $type instanceof HasOffsetType) {
156-
return new MixedType();
155+
return $type->generalize(GeneralizePrecision::templateArgument());
157156
}
158157

159158
return $traverse($type);

0 commit comments

Comments
 (0)