-
Notifications
You must be signed in to change notification settings - Fork 665
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
Inconsistent handling of "empty"-status of arrays as return values #9188
Labels
Comments
I found these snippets: https://psalm.dev/r/7320dbad2e<?php
/**
* @template Tk
* @template Tv
* @template T
*
* @param iterable<Tk, Tv> $iterable Iterable to be mapped over
* @param (Closure(Tv): T) $function
*
* @return list<T>
*/
function map(iterable $iterable, Closure $function): array
{
if (is_array($iterable)) {
return array_values(array_map(
/**
* @param Tv $v
*/
static fn($v) => $function($v),
$iterable
));
}
$result = [];
foreach ($iterable as $value) {
$result[] = $function($value);
}
return $result;
}
function echoThings(string $first, string ...$rest): void
{
foreach ([$first, ...$rest] as $thingToSay) {
echo $thingToSay;
}
}
/**
* @var array<string> $things
* @phpstan-var array<non-empty-string> $things
* @psalm-var non-empty-array<non-empty-string> $things
*/
$things = ['example'];
echoThings(...map($things, static fn (string $thing) => $thing));
https://psalm.dev/r/5f017e6180<?php
/**
* @template Tk
* @template Tv
* @template T
*
* @param iterable<Tk, Tv> $iterable Iterable to be mapped over
* @param (Closure(Tv): T) $function
*
* @return array<T>
*/
function map(iterable $iterable, Closure $function): array
{
if (is_array($iterable)) {
return array_values(array_map(
/**
* @param Tv $v
*/
static fn($v) => $function($v),
$iterable
));
}
$result = [];
foreach ($iterable as $value) {
$result[] = $function($value);
}
return $result;
}
function echoThings(string $first, string ...$rest): void
{
foreach ([$first, ...$rest] as $thingToSay) {
echo $thingToSay;
}
}
/**
* @var array<string> $things
* @phpstan-var array<non-empty-string> $things
* @psalm-var non-empty-array<non-empty-string> $things
*/
$things = ['example'];
echoThings(...map($things, static fn (string $thing) => $thing));
|
Simplified: https://psalm.dev/r/8d4e5c66da |
I found these snippets: https://psalm.dev/r/8d4e5c66da<?php
function echoThings(string $_first, string ...$_rest): void {}
/** @return list<non-empty-string> */
function mapList(): array { throw new Exception; }
$mapped = mapList();
/** @psalm-trace $mapped */;
echoThings(...$mapped);
// -------------------------------
/** @return non-empty-array<non-empty-string> */
function mapArray(): array { throw new Exception; }
$mapped = mapArray();
/** @psalm-trace $mapped */;
echoThings(...$mapped);
|
This is fixed in #10777 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Description
The assumption about whether arrays are non-empty seems to be inconsistent between the types
list
andarray
as output typing from a function.To Reproduce
https://psalm.dev/r/7320dbad2e
In this first snippet, the return type of the function
map
is typed with "list". When attempting to use the spread operator on this return value as the parameter of a function which requires at least 1 member to be present, it triggers a warning "possibly undefined".https://psalm.dev/r/5f017e6180
The second snippet is the same setup -- but the return value is array not list -- but the above error does not occur.
Expected behavior
I don't have intimate knowledge of Psalm internals, so I can't say whether the one behaviour or the other is correct -- but it does seem that it is inconsistent between the two.
I would expect that Psalm would consider both array and list to be potentially undefined in this spread operator -- or that they would both not cause a problem.
Environment (please complete the following information):
Thanks a lot for a great library !
The text was updated successfully, but these errors were encountered: