Skip to content

Commit 5a1a6af

Browse files
authored
Treat ArrayType as covariant in its keys and values
1 parent f1cc53a commit 5a1a6af

File tree

3 files changed

+30
-17
lines changed

3 files changed

+30
-17
lines changed

src/Type/ArrayType.php

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
use PHPStan\Type\Constant\ConstantIntegerType;
2323
use PHPStan\Type\Constant\ConstantStringType;
2424
use PHPStan\Type\Generic\TemplateMixedType;
25-
use PHPStan\Type\Generic\TemplateType;
2625
use PHPStan\Type\Generic\TemplateTypeMap;
2726
use PHPStan\Type\Generic\TemplateTypeVariance;
2827
use PHPStan\Type\Traits\MaybeCallableTypeTrait;
@@ -636,24 +635,11 @@ public function inferTemplateTypes(Type $receivedType): TemplateTypeMap
636635

637636
public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance): array
638637
{
639-
$keyVariance = $positionVariance;
640-
$itemVariance = $positionVariance;
641-
642-
if (!$positionVariance->contravariant()) {
643-
$keyType = $this->getKeyType();
644-
if ($keyType instanceof TemplateType) {
645-
$keyVariance = $keyType->getVariance();
646-
}
647-
648-
$itemType = $this->getItemType();
649-
if ($itemType instanceof TemplateType) {
650-
$itemVariance = $itemType->getVariance();
651-
}
652-
}
638+
$variance = $positionVariance->compose(TemplateTypeVariance::createCovariant());
653639

654640
return array_merge(
655-
$this->getKeyType()->getReferencedTemplateTypes($keyVariance),
656-
$this->getItemType()->getReferencedTemplateTypes($itemVariance),
641+
$this->getKeyType()->getReferencedTemplateTypes($variance),
642+
$this->getItemType()->getReferencedTemplateTypes($variance),
657643
);
658644
}
659645

tests/PHPStan/Rules/Generics/MethodSignatureVarianceRuleTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,4 +224,14 @@ public function testBug9161(): void
224224
$this->analyse([__DIR__ . '/data/bug-9161.php'], []);
225225
}
226226

227+
public function testPr2465(): void
228+
{
229+
$this->analyse([__DIR__ . '/data/pr-2465.php'], [
230+
[
231+
'Template type T is declared as covariant, but occurs in invariant position in parameter thing of method Pr2465\UnitOfTest::foo().',
232+
16,
233+
],
234+
]);
235+
}
236+
227237
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Pr2465;
4+
5+
/** @template T */
6+
class InvariantThing {}
7+
8+
/**
9+
* @template-covariant T
10+
*/
11+
class UnitOfTest
12+
{
13+
/**
14+
* @param InvariantThing<array<T>> $thing
15+
*/
16+
public function foo(InvariantThing $thing): void {}
17+
}

0 commit comments

Comments
 (0)