mirror of
https://github.com/danog/psalm.git
synced 2025-01-22 05:41:20 +01:00
Allow using covariant template in mutation-free context
This commit is contained in:
parent
a91d2ef572
commit
532e2d64be
@ -169,6 +169,11 @@ class TTemplateParam extends \Psalm\Type\Atomic
|
||||
&& isset($class_storage->template_covariants[$template_offset])
|
||||
&& $class_storage->template_covariants[$template_offset]
|
||||
) {
|
||||
if ($source instanceof \Psalm\Internal\Analyzer\FunctionLikeAnalyzer
|
||||
&& $source->getFunctionLikeStorage()->mutation_free
|
||||
) {
|
||||
// do nothing
|
||||
} else {
|
||||
if (\Psalm\IssueBuffer::accepts(
|
||||
new \Psalm\Issue\InvalidTemplateParam(
|
||||
'Template param ' . $this->param_name . ' of '
|
||||
@ -182,6 +187,7 @@ class TTemplateParam extends \Psalm\Type\Atomic
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->as->check($source, $code_location, $suppressed_issues, $phantom_classes, $inferred);
|
||||
|
||||
|
@ -279,6 +279,56 @@ class ClassTemplateCovarianceTest extends TestCase
|
||||
takesIteratorAggregate($a);
|
||||
}'
|
||||
],
|
||||
'allowImmutableCovariance' => [
|
||||
'<?php
|
||||
class Animal {}
|
||||
class Dog extends Animal{}
|
||||
class Cat extends Animal{}
|
||||
|
||||
/**
|
||||
* @psalm-immutable
|
||||
* @template-covariant T
|
||||
*/
|
||||
class Collection {
|
||||
|
||||
/** @var list<T> */
|
||||
private $arr = [];
|
||||
|
||||
/**
|
||||
* @param T ...$a
|
||||
*/
|
||||
public function __construct(...$a) {
|
||||
$this->arr = $a;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param T $a
|
||||
* @return Collection<T>
|
||||
*/
|
||||
public function add($a) : Collection
|
||||
{
|
||||
return new Collection(...$this->arr, $a);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param Collection<Animal> $c
|
||||
* @return Collection<Animal>
|
||||
*/
|
||||
function covariant(Collection $c) : Collection
|
||||
{
|
||||
return $c->add(new Cat());
|
||||
}
|
||||
|
||||
$dogs = new Collection(new Dog(), new Dog());
|
||||
$cats = new Collection(new Cat(), new Cat());
|
||||
$misc = new Collection(new Cat(), new Dog());
|
||||
|
||||
covariant($dogs);
|
||||
covariant($cats);
|
||||
covariant($misc);',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user