mirror of
https://github.com/danog/psalm.git
synced 2024-11-27 04:45:20 +01:00
Be less forgiving when extending builtin generic classes
This commit is contained in:
parent
952484c64d
commit
04879af105
@ -1860,7 +1860,6 @@ class ClassAnalyzer extends ClassLikeAnalyzer
|
||||
|
||||
if (isset($parent_storage->template_covariants[$i])
|
||||
&& !$parent_storage->template_covariants[$i]
|
||||
&& $parent_storage->user_defined
|
||||
) {
|
||||
foreach ($extended_type->getTypes() as $t) {
|
||||
if ($t instanceof Type\Atomic\TTemplateParam
|
||||
@ -1869,13 +1868,12 @@ class ClassAnalyzer extends ClassLikeAnalyzer
|
||||
&& ($local_offset
|
||||
= array_search($t->param_name, array_keys($storage->template_types)))
|
||||
!== false
|
||||
&& isset($storage->template_covariants[$local_offset])
|
||||
&& $storage->template_covariants[$local_offset]
|
||||
&& !empty($storage->template_covariants[$local_offset])
|
||||
) {
|
||||
if (IssueBuffer::accepts(
|
||||
new InvalidTemplateParam(
|
||||
'Cannot extend an invariant template param ' . $template_name
|
||||
. ' from an invariant context',
|
||||
. ' into a covariant context',
|
||||
$code_location
|
||||
),
|
||||
$storage->suppressed_issues + $this->getSuppressedIssues()
|
||||
|
@ -95,21 +95,30 @@ class ClassTemplateCovarianceTest extends TestCase
|
||||
|
||||
/**
|
||||
* @template-covariant TValue
|
||||
* @template-extends \ArrayObject<int,TValue>
|
||||
* @implements IteratorAggregate<int, TValue>
|
||||
*/
|
||||
class Collection extends \ArrayObject {
|
||||
class Collection implements IteratorAggregate {
|
||||
private $arr;
|
||||
|
||||
/**
|
||||
* @param array<int,TValue> $kv
|
||||
* @param array<int,TValue> $arr
|
||||
*/
|
||||
public function __construct(array $kv) {
|
||||
parent::__construct($kv);
|
||||
public function __construct(array $arr) {
|
||||
$this->arr = $arr;
|
||||
}
|
||||
|
||||
/** @return Traversable<int, TValue> */
|
||||
public function getIterator() {
|
||||
foreach ($this->arr as $k => $v) {
|
||||
yield $k => $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection<Animal> $list
|
||||
*/
|
||||
function getSounds(Traversable $list) : void {
|
||||
function getSounds(Collection $list) : void {
|
||||
foreach ($list as $l) {
|
||||
$l->getSound();
|
||||
}
|
||||
@ -136,9 +145,25 @@ class ClassTemplateCovarianceTest extends TestCase
|
||||
|
||||
/**
|
||||
* @template-covariant TValue
|
||||
* @template-extends \ArrayObject<int,TValue>
|
||||
* @implements IteratorAggregate<int, TValue>
|
||||
*/
|
||||
class Collection extends \ArrayObject {}
|
||||
class Collection implements IteratorAggregate {
|
||||
private $arr;
|
||||
|
||||
/**
|
||||
* @param array<int,TValue> $arr
|
||||
*/
|
||||
public function __construct(array $arr) {
|
||||
$this->arr = $arr;
|
||||
}
|
||||
|
||||
/** @return Traversable<int, TValue> */
|
||||
public function getIterator() {
|
||||
foreach ($this->arr as $k => $v) {
|
||||
yield $k => $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @template-extends Collection<Dog> */
|
||||
class HardwiredDogCollection extends Collection {}
|
||||
@ -542,6 +567,15 @@ class ClassTemplateCovarianceTest extends TestCase
|
||||
}',
|
||||
'error_message' => 'InvalidTemplateParam'
|
||||
],
|
||||
'preventExtendingCoreWithCovariantParam' => [
|
||||
'<?php
|
||||
/**
|
||||
* @template-covariant TValue
|
||||
* @template-extends \ArrayObject<int,TValue>
|
||||
*/
|
||||
class Collection extends \ArrayObject {}',
|
||||
'error_message' => 'InvalidTemplateParam',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user