Skip to content

Commit d517bb4

Browse files
jiripudilondrejmirtes
authored andcommitted
implement ClosureType::getReferencedTemplateTypes()
1 parent 7b0d777 commit d517bb4

File tree

3 files changed

+44
-2
lines changed

3 files changed

+44
-2
lines changed

src/Type/ClosureType.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,10 @@
3636
use PHPStan\Type\Generic\TemplateType;
3737
use PHPStan\Type\Generic\TemplateTypeHelper;
3838
use PHPStan\Type\Generic\TemplateTypeMap;
39+
use PHPStan\Type\Generic\TemplateTypeVariance;
3940
use PHPStan\Type\Generic\TemplateTypeVarianceMap;
4041
use PHPStan\Type\Traits\NonArrayTypeTrait;
4142
use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
42-
use PHPStan\Type\Traits\NonGenericTypeTrait;
4343
use PHPStan\Type\Traits\NonIterableTypeTrait;
4444
use PHPStan\Type\Traits\NonOffsetAccessibleTypeTrait;
4545
use PHPStan\Type\Traits\NonRemoveableTypeTrait;
@@ -53,7 +53,6 @@ class ClosureType implements TypeWithClassName, CallableParametersAcceptor
5353
{
5454

5555
use NonArrayTypeTrait;
56-
use NonGenericTypeTrait;
5756
use NonIterableTypeTrait;
5857
use UndecidedComparisonTypeTrait;
5958
use NonOffsetAccessibleTypeTrait;
@@ -540,6 +539,23 @@ private function inferTemplateTypesOnParametersAcceptor(ParametersAcceptor $para
540539
return $typeMap->union($this->getReturnType()->inferTemplateTypes($returnType));
541540
}
542541

542+
public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance): array
543+
{
544+
$references = $this->getReturnType()->getReferencedTemplateTypes(
545+
$positionVariance->compose(TemplateTypeVariance::createCovariant()),
546+
);
547+
548+
$paramVariance = $positionVariance->compose(TemplateTypeVariance::createContravariant());
549+
550+
foreach ($this->getParameters() as $param) {
551+
foreach ($param->getType()->getReferencedTemplateTypes($paramVariance) as $reference) {
552+
$references[] = $reference;
553+
}
554+
}
555+
556+
return $references;
557+
}
558+
543559
public function traverse(callable $cb): Type
544560
{
545561
if ($this->isCommonCallable) {

tests/PHPStan/Rules/Generics/MethodSignatureVarianceRuleTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,4 +234,14 @@ public function testPr2465(): void
234234
]);
235235
}
236236

237+
public function testBug10609(): void
238+
{
239+
$this->analyse([__DIR__ . '/data/bug-10609.php'], [
240+
[
241+
'Template type A is declared as covariant, but occurs in contravariant position in parameter fn of method Bug10609\Collection::tap().',
242+
13,
243+
],
244+
]);
245+
}
246+
237247
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Bug10609;
4+
5+
/**
6+
* @template-covariant A
7+
*/
8+
final class Collection
9+
{
10+
/**
11+
* @param \Closure(A): A $fn
12+
*/
13+
public function tap(mixed $fn): void
14+
{
15+
}
16+
}

0 commit comments

Comments
 (0)