Skip to content

Commit 663cbfa

Browse files
Do not report generic covariant issue without strict check
1 parent 7092778 commit 663cbfa

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

src/Rules/PhpDoc/VarTagTypeRuleHelper.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
use PHPStan\Type\ArrayType;
1919
use PHPStan\Type\FileTypeMapper;
2020
use PHPStan\Type\Generic\GenericObjectType;
21+
use PHPStan\Type\Generic\TemplateTypeVariance;
2122
use PHPStan\Type\IsSuperTypeOfResult;
2223
use PHPStan\Type\MixedType;
2324
use PHPStan\Type\ObjectType;
2425
use PHPStan\Type\Type;
26+
use PHPStan\Type\TypeTraverser;
2527
use PHPStan\Type\TypeUtils;
2628
use PHPStan\Type\VerbosityLevel;
2729
use function array_key_exists;
@@ -182,6 +184,17 @@ private function isValidSuperType(Scope $scope, Type $type, Type $varTagType, in
182184
return $this->isSuperTypeOfVarType($scope, $type, $varTagType);
183185
}
184186

187+
$type = TypeTraverser::map($type, static function (Type $type, callable $traverse): Type {
188+
if ($type instanceof GenericObjectType) {
189+
$type = $type->changeVariances(array_map(
190+
static fn (TemplateTypeVariance $variance) => $variance->invariant() ? TemplateTypeVariance::createCovariant() : $variance,
191+
$type->getVariances(),
192+
));
193+
}
194+
195+
return $traverse($type);
196+
});
197+
185198
if ($type->isConstantArray()->yes()) {
186199
if ($type->isIterableAtLeastOnce()->no()) {
187200
$type = new ArrayType(new MixedType(), new MixedType());

src/Type/Generic/GenericObjectType.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,14 @@ protected function recreate(string $className, array $types, ?Type $subtractedTy
403403
);
404404
}
405405

406+
/**
407+
* @param TemplateTypeVariance[] $variances
408+
*/
409+
public function changeVariances(array $variances): self
410+
{
411+
return $this->recreate($this->getClassName(), $this->getTypes(), $this->getSubtractedType(), $variances);
412+
}
413+
406414
public function changeSubtractedType(?Type $subtractedType): Type
407415
{
408416
$result = parent::changeSubtractedType($subtractedType);

tests/PHPStan/Rules/PhpDoc/WrongVariableNameInVarTagRuleTest.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ public function testBug12457(): void
586586
]);
587587
}
588588

589-
public function testGenericSubtype(): void
589+
public function testGenericSubtypeWithStrictCheck(): void
590590
{
591591
$this->checkTypeAgainstPhpDocType = true;
592592
$this->strictWideningCheck = true;
@@ -604,6 +604,13 @@ public function testGenericSubtype(): void
604604
]);
605605
}
606606

607+
public function testGenericSubtypeWithoutStrictCheck(): void
608+
{
609+
$this->checkTypeAgainstPhpDocType = true;
610+
$this->strictWideningCheck = false;
611+
$this->analyse([__DIR__ . '/data/generic-subtype.php'], []);
612+
}
613+
607614
public function testNewIsAlwaysFinalClass(): void
608615
{
609616
$this->checkTypeAgainstPhpDocType = true;

0 commit comments

Comments
 (0)