psalm
psalm copied to clipboard
False-positive `PossiblyNullArgument` when using `??=` on `ArrayAccess` with nullable `offsetGet()`
When using ??=
on an implementation of ArrayAccess
whose offsetGet()
can return null
for nonexistent offsets, I'm getting a false-positive PossiblyNullArgument
:
https://psalm.dev/r/f82e852479
// Psalm infers $foo as Foo|null even though that's impossible
$foo = ($map['foo'] ??= new Foo());
The offsetGet()
method is not called at all when ??=
is used so it is impossible for it to influence the call to offsetSet()
or the result of the ??=
operator:
https://3v4l.org/vQqLV
I found these snippets:
https://psalm.dev/r/f82e852479
<?php
/**
* @template TKey of array-key
* @template TValue
* @implements ArrayAccess<TKey, TValue>
*/
abstract class Map implements ArrayAccess
{
/**
* @param TKey $offset
*/
abstract function offsetExists(mixed $offset): bool;
/**
* @param TKey $offset
* @return TValue|null
*/
abstract function offsetGet(mixed $offset): mixed;
/**
* @param TKey $offset
* @param TValue $value
*/
abstract function offsetSet(mixed $offset, mixed $value): void;
/**
* @param TKey $offset
*/
abstract function offsetUnset(mixed $offset): void;
}
class Foo
{}
/**
* @param Map<string, Foo> $map
* @psalm-suppress UnusedVariable
*/
function example(Map $map): void
{
/** @psalm-trace $foo */
$foo = ($map['foo'] ??= new Foo());
}
Psalm output (using commit ef3b018):
ERROR: PossiblyNullArgument - 43:13 - Argument 2 of Map::offsetSet cannot be null, possibly null value provided
INFO: Trace - 43:5 - $foo: Foo|null
Duplicate of https://github.com/vimeo/psalm/issues/9960?
It could be the same cause, just with ??=
instead of ??
. Also in this case offsetGet()
does not get called at all.