vimeo / psalm

A static analysis tool for finding errors in PHP applications
https://psalm.dev
MIT License
5.57k stars 660 forks source link

Traversable<int, T:Gallery as GalleryItemInterface> cannot be identical to ArrayIterator #9449

Open jordisala1991 opened 1 year ago

jordisala1991 commented 1 year ago

We are facing an issue when upgrading from psalm 4 to psalm 5 on SonataMediaBundle. Here is the PR with the discussion about it: https://github.com/sonata-project/SonataMediaBundle/pull/2360

We have figured out a simpler reproducer: https://psalm.dev/r/6f6a50ae98

It seems to be caused by the T of someInterface on 2 consecutive classes.

psalm-github-bot[bot] commented 1 year ago

I found these snippets:

https://psalm.dev/r/6f6a50ae98 ```php * * @phpstan-return IteratorAggregate */ public function getGalleryItems(): IteratorAggregate; } /** * @phpstan-template T of GalleryItemInterface * @phpstan-implements GalleryInterface */ abstract class Gallery implements GalleryInterface { public function getGalleryItems(): \IteratorAggregate { throw new \Exception(); } public function reorderGalleryItems(): void { $iterator = $this->getGalleryItems()->getIterator(); if (!$iterator instanceof \ArrayIterator) { throw new \RuntimeException(sprintf( 'The gallery cannot be reordered, $galleryItems should implement %s', \ArrayIterator::class )); } $iterator->uasort( static fn (GalleryItemInterface $a, GalleryItemInterface $b): int => $a->getPosition() <=> $b->getPosition() ); } } ``` ``` Psalm output (using commit 3af9ccd): ERROR: RedundantCondition - 35:15 - Traversable cannot be identical to ArrayIterator INFO: MixedArgumentTypeCoercion - 42:21 - Type mixed should be a subtype of GalleryItemInterface ```
orklah commented 1 year ago

minimal reproducer: https://psalm.dev/r/558ef4b2a5

Note: if we replace T by int, the error disappear Also, if we drop the upper bound of the template (int in the reproducer) the error disappear as well

psalm-github-bot[bot] commented 1 year ago

I found these snippets:

https://psalm.dev/r/558ef4b2a5 ```php $iterator */ $iterator = []; assert(!$iterator instanceof \ArrayIterator); } } ``` ``` Psalm output (using commit 3af9ccd): ERROR: RedundantConditionGivenDocblockType - 13:18 - Traversable does not contain ArrayIterator ```