Permalink
Browse files
Allow using covariant template in mutation-free context
- Loading branch information
|
@@ -169,16 +169,22 @@ public function check( |
|
|
&& isset($class_storage->template_covariants[$template_offset]) |
|
|
&& $class_storage->template_covariants[$template_offset] |
|
|
) { |
|
|
if (\Psalm\IssueBuffer::accepts( |
|
|
new \Psalm\Issue\InvalidTemplateParam( |
|
|
'Template param ' . $this->param_name . ' of ' |
|
|
. $this->defining_class . ' is marked covariant and cannot be used' |
|
|
. ' as input to a function', |
|
|
$code_location |
|
|
), |
|
|
$source->getSuppressedIssues() |
|
|
)) { |
|
|
// fall through |
|
|
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 ' |
|
|
. $this->defining_class . ' is marked covariant and cannot be used' |
|
|
. ' as input to a function', |
|
|
$code_location |
|
|
), |
|
|
$source->getSuppressedIssues() |
|
|
)) { |
|
|
// fall through |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
@@ -279,6 +279,56 @@ function takesMyArrayOfException(MyArray $a) : void { |
|
|
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);', |
|
|
], |
|
|
]; |
|
|
} |
|
|
|
|
|
0 comments on commit
532e2d6