Psalm seems to behave incorrectly with Collection<TKey, ...> types when TKey is inferred to be int<0, n>, rather than int, 1|2|3, and a Collection<int> is requested. I lack the proper terminology/keywords to explain and search this better, so here's an example:
<?php
/** @template TKey */
final class Collection
{
/** @param array<TKey, mixed> $items */
function __construct(array $items) {}
}
/** @param Collection<int> $c */
function usesIntCollection(Collection $c): void {
echo var_export($c, true); // irrelevant
}
// ok
$empty = new Collection([]);
/** @psalm-trace $empty */
usesIntCollection($empty);
// ok
$keysInferredAsUnionType = new Collection([1 => 'a', 2 => 'b']);
/** @psalm-trace $keysInferredAsUnionType */
usesIntCollection($keysInferredAsUnionType);
$keysInferredAsRange = new Collection(['a', 'b']);
/** @psalm-trace $keysInferredAsRange */
usesIntCollection($keysInferredAsRange);
Psalm seems to behave incorrectly with
Collection<TKey, ...>
types whenTKey
is inferred to beint<0, n>
, rather thanint
,1|2|3
, and aCollection<int>
is requested. I lack the proper terminology/keywords to explain and search this better, so here's an example:https://psalm.dev/r/8a5261da42
In the above example, all 3 examples should probably pass the
@param Collection<int> $c
parameter type required byusesIntCollection()
.Refs
Related: https://github.com/doctrine/orm/issues/11451 Related: https://github.com/doctrine/orm/pull/11454 Longer explanation @ https://github.com/doctrine/orm/pull/11454#issuecomment-2120717927
/cc @greg0ire @MatteoFeltrin