-
Notifications
You must be signed in to change notification settings - Fork 660
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Possible regression with Doctrine since psalm version 5.10.0 #9947
Comments
Hey @CReimer, can you reproduce the issue on https://psalm.dev ? |
Actually, I can. Here's the link: https://psalm.dev/r/a98fd8bfec |
I found these snippets: https://psalm.dev/r/a98fd8bfec<?php
use Doctrine\Common\Collections\Selectable;
/**
* @psalm-template TKey of array-key
* @template-covariant T
*/
interface ReadableCollection {
/**
* Checks whether an element is contained in the collection.
* This is an O(n) operation, where n is the size of the collection.
*
* @param mixed $element The element to search for.
* @psalm-param TMaybeContained $element
*
* @return bool TRUE if the collection contains the element, FALSE otherwise.
* @psalm-return (TMaybeContained is T ? bool : false)
*
* @template TMaybeContained
*/
public function contains(mixed $element);
}
/**
* The missing (SPL) Collection/Array/OrderedMap interface.
*
* A Collection resembles the nature of a regular PHP array. That is,
* it is essentially an <b>ordered map</b> that can also be used
* like a list.
*
* A Collection has an internal iterator just like a PHP array. In addition,
* a Collection can be iterated with external iterators, which is preferable.
* To use an external iterator simply use the foreach language construct to
* iterate over the collection (which calls {@link getIterator()} internally) or
* explicitly retrieve an iterator though {@link getIterator()} which can then be
* used to iterate over the collection.
* You can not rely on the internal iterator of the collection being at a certain
* position unless you explicitly positioned it before. Prefer iteration with
* external iterators.
*
* @psalm-template TKey of array-key
* @psalm-template T
* @template-extends ReadableCollection<TKey, T>
*/
interface Collection extends ReadableCollection {
}
/**
* An ArrayCollection is a Collection implementation that wraps a regular PHP array.
*
* Warning: Using (un-)serialize() on a collection is not a supported use-case
* and may break when we change the internals in the future. If you need to
* serialize a collection use {@link toArray()} and reconstruct the collection
* manually.
*
* @psalm-template TKey of array-key
* @psalm-template T
* @template-implements Collection<TKey,T>
* @psalm-consistent-constructor
*/
class ArrayCollection implements Collection {
/**
* An array containing the entries of this collection.
*
* @psalm-var array<TKey,T>
*
* @var mixed[]
*/
private array $elements = [];
/**
* Initializes a new ArrayCollection.
*
* @psalm-param array<TKey,T> $elements
*/
public function __construct(array $elements = []) {
$this->elements = $elements;
}
/**
* {@inheritDoc}
*
* @template TMaybeContained
*/
public function contains(mixed $element) {
return in_array($element, $this->elements, true);
}
}
$data = [
'data1',
'data2',
'data3',
];
$collection = new ArrayCollection($data);
if ($collection->contains('data2')) {
echo 'HELLO WORLD' . PHP_EOL;
}
|
Seems to fix itself as long as you repeat the phpdoc in the signature of contains: https://psalm.dev/r/1049462d2e |
I found these snippets: https://psalm.dev/r/1049462d2e<?php
use Doctrine\Common\Collections\Selectable;
/**
* @psalm-template TKey of array-key
* @template-covariant T
*/
interface ReadableCollection {
/**
* Checks whether an element is contained in the collection.
* This is an O(n) operation, where n is the size of the collection.
*
* @param mixed $element The element to search for.
* @psalm-param TMaybeContained $element
*
* @return bool TRUE if the collection contains the element, FALSE otherwise.
* @psalm-return (TMaybeContained is T ? bool : false)
*
* @template TMaybeContained
*/
public function contains(mixed $element);
}
/**
* The missing (SPL) Collection/Array/OrderedMap interface.
*
* A Collection resembles the nature of a regular PHP array. That is,
* it is essentially an <b>ordered map</b> that can also be used
* like a list.
*
* A Collection has an internal iterator just like a PHP array. In addition,
* a Collection can be iterated with external iterators, which is preferable.
* To use an external iterator simply use the foreach language construct to
* iterate over the collection (which calls {@link getIterator()} internally) or
* explicitly retrieve an iterator though {@link getIterator()} which can then be
* used to iterate over the collection.
* You can not rely on the internal iterator of the collection being at a certain
* position unless you explicitly positioned it before. Prefer iteration with
* external iterators.
*
* @psalm-template TKey of array-key
* @psalm-template T
* @template-extends ReadableCollection<TKey, T>
*/
interface Collection extends ReadableCollection {
}
/**
* An ArrayCollection is a Collection implementation that wraps a regular PHP array.
*
* Warning: Using (un-)serialize() on a collection is not a supported use-case
* and may break when we change the internals in the future. If you need to
* serialize a collection use {@link toArray()} and reconstruct the collection
* manually.
*
* @psalm-template TKey of array-key
* @psalm-template T
* @template-implements Collection<TKey,T>
* @psalm-consistent-constructor
*/
class ArrayCollection implements Collection {
/**
* An array containing the entries of this collection.
*
* @psalm-var array<TKey,T>
*
* @var mixed[]
*/
private array $elements = [];
/**
* Initializes a new ArrayCollection.
*
* @psalm-param array<TKey,T> $elements
*/
public function __construct(array $elements = []) {
$this->elements = $elements;
}
/**
* @param mixed $element The element to search for.
* @psalm-param TMaybeContained $element
*
* @return bool TRUE if the collection contains the element, FALSE otherwise.
* @psalm-return (TMaybeContained is T ? bool : false)
*
* @template TMaybeContained
*/
public function contains(mixed $element) {
return in_array($element, $this->elements, true);
}
}
$data = [
'data1',
'data2',
'data3',
];
$collection = new ArrayCollection($data);
if ($collection->contains('data2')) {
echo 'HELLO WORLD' . PHP_EOL;
}
|
Also fixed by removing the extra template annotation: https://psalm.dev/r/97b80a50b6 |
I found these snippets: https://psalm.dev/r/97b80a50b6<?php
use Doctrine\Common\Collections\Selectable;
/**
* @psalm-template TKey of array-key
* @template-covariant T
*/
interface ReadableCollection {
/**
* Checks whether an element is contained in the collection.
* This is an O(n) operation, where n is the size of the collection.
*
* @param mixed $element The element to search for.
* @psalm-param TMaybeContained $element
*
* @return bool TRUE if the collection contains the element, FALSE otherwise.
* @psalm-return (TMaybeContained is T ? bool : false)
*
* @template TMaybeContained
*/
public function contains(mixed $element);
}
/**
* The missing (SPL) Collection/Array/OrderedMap interface.
*
* A Collection resembles the nature of a regular PHP array. That is,
* it is essentially an <b>ordered map</b> that can also be used
* like a list.
*
* A Collection has an internal iterator just like a PHP array. In addition,
* a Collection can be iterated with external iterators, which is preferable.
* To use an external iterator simply use the foreach language construct to
* iterate over the collection (which calls {@link getIterator()} internally) or
* explicitly retrieve an iterator though {@link getIterator()} which can then be
* used to iterate over the collection.
* You can not rely on the internal iterator of the collection being at a certain
* position unless you explicitly positioned it before. Prefer iteration with
* external iterators.
*
* @psalm-template TKey of array-key
* @psalm-template T
* @template-extends ReadableCollection<TKey, T>
*/
interface Collection extends ReadableCollection {
}
/**
* An ArrayCollection is a Collection implementation that wraps a regular PHP array.
*
* Warning: Using (un-)serialize() on a collection is not a supported use-case
* and may break when we change the internals in the future. If you need to
* serialize a collection use {@link toArray()} and reconstruct the collection
* manually.
*
* @psalm-template TKey of array-key
* @psalm-template T
* @template-implements Collection<TKey,T>
* @psalm-consistent-constructor
*/
class ArrayCollection implements Collection {
/**
* An array containing the entries of this collection.
*
* @psalm-var array<TKey,T>
*
* @var mixed[]
*/
private array $elements = [];
/**
* Initializes a new ArrayCollection.
*
* @psalm-param array<TKey,T> $elements
*/
public function __construct(array $elements = []) {
$this->elements = $elements;
}
/**
* {@inheritDoc}
*/
public function contains(mixed $element) {
return in_array($element, $this->elements, true);
}
}
$data = [
'data1',
'data2',
'data3',
];
$collection = new ArrayCollection($data);
if ($collection->contains('data2')) {
echo 'HELLO WORLD' . PHP_EOL;
}
$_false = $collection->contains(123);
/** @psalm-trace $_false */
|
Does that mean it's an upstream doctrine/collection issue? Should I report it there then? |
Yeah, please do, let's hear what they think about this |
It looks like I don't need to. It's already fixed upstream. Unfortunately no release yet. doctrine/collections#368 (Report) Thank you all. I'm sorry for wasting your time. |
No worries! Feedback is great :) |
My team and I can't upgrade beyond psalm 5.9.0 because newer version keep flooding us with these error messages
Here's a small example of this error
Of which psalm 5.12.0 returns this error message
PHP version: 8.2.7
Doctrine/ORM version: 2.15.2
Psalm version: 5.12.0
The text was updated successfully, but these errors were encountered: