Skip to content
Permalink
Browse files

Be less forgiving when extending builtin generic classes

  • Loading branch information
muglug committed Nov 30, 2019
1 parent 952484c commit 04879af10573e0aeb99c2c130ce6de82b1920d8e
Showing with 44 additions and 12 deletions.
  1. +2 −4 src/Psalm/Internal/Analyzer/ClassAnalyzer.php
  2. +42 −8 tests/Template/ClassTemplateCovarianceTest.php
@@ -1860,7 +1860,6 @@ private function checkTemplateParams(
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 @@ private function checkTemplateParams(
&& ($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 @@ public function getSound() : string {
/**
* @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 @@ public function getSound() : string {
/**
* @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 @@ public function getReference() : InvariantReference
}',
'error_message' => 'InvalidTemplateParam'
],
'preventExtendingCoreWithCovariantParam' => [
'<?php
/**
* @template-covariant TValue
* @template-extends \ArrayObject<int,TValue>
*/
class Collection extends \ArrayObject {}',
'error_message' => 'InvalidTemplateParam',
],
];
}
}

0 comments on commit 04879af

Please sign in to comment.
You can’t perform that action at this time.