psalm
psalm copied to clipboard
Regression: incorrectly reported TypeDoesNotContainType in a loop
Psalm started incorrectly reporting TypeDoesNotContainType some time after 5.19.1
Consider a two dimensional array, the code returns a count for each unique value in "key" column
/**
* @param array{key: string}[] $array
*/
function func(array $array): array
{
$r = [];
foreach ($array as $row) {
$r[$row['key']] = empty($r[$row['key']])
? 1
: $r[$row['key']] + 1;
}
return $r;
}
psalm reports
Psalm output (using commit [c488d40](https://github.com/vimeo/psalm/commit/c488d40)):
ERROR: [TypeDoesNotContainType](https://psalm.dev/056) - 10:27 - Operand of type false is always falsy
https://psalm.dev/r/707051b9f6
I found these snippets:
https://psalm.dev/r/707051b9f6
<?php
/**
* @param array{key: string}[] $array
*/
function func(array $array): array
{
$r = [];
foreach ($array as $row) {
$r[$row['key']] = empty($r[$row['key']])
? 1
: $r[$row['key']] + 1;
}
return $r;
}
Psalm output (using commit c488d40):
ERROR: TypeDoesNotContainType - 10:27 - Operand of type false is always falsy
Not really a regression, you just weren't aware that psalm had a bug here in the first place: https://psalm.dev/r/64f874f2bc
$y
shouldn't be '1|2|3' there, so this wasn't correctly checked by psalm before either.
I found these snippets:
https://psalm.dev/r/64f874f2bc
<?php
/**
* @param array{key: string}[] $array
*/
function func(array $array): array
{
$r = [];
foreach ($array as $row) {
$y = $r[$row['key']];
/** @psalm-trace $y */;
$r[$row['key']] = empty($r[$row['key']])
? 1
: $r[$row['key']] + 1;
}
return $r;
}
Psalm output (using commit c488d40):
INFO: Trace - 11:31 - $y: 1|2|3
ERROR: TypeDoesNotContainType - 13:27 - Operand of type false is always falsy
INFO: UnusedVariable - 10:9 - $y is never referenced or the value is not used
@kkmuffme interesting!
I guess an earlier issue manifests differently now. But it's definitely a regression specifically for the use case I posted. It worked ok before, but fails now... But yeah, there's clearly some issue with type detection when an array is assigned in a loop.