min() and max() may return false if array size could be zero#300
min() and max() may return false if array size could be zero#300ondrejmirtes merged 3 commits intophpstan:masterfrom pmmp:min-max-false-return
Conversation
|
Having some strange behaviour with an integration test file I'm trying to add, @ondrejmirtes could you shed any light on this? <?php
namespace MinMaxArrays;
function takesInt(int $int): void
{
}
function dummy(): void
{
takesInt(min([1]));
takesInt(min([]));
takesInt(max([1]));
takesInt(max([]));
}
/**
* @param int[] $ints
*/
function dummy2(array $ints): void
{
if (count($ints) > 0) {
takesInt(min($ints));
takesInt(max($ints));
} else {
takesInt(min($ints));
takesInt(max($ints));
}
}
/**
* @param int[] $ints
*/
function dummy3(array $ints): void
{
takesInt(min($ints));
takesInt(max($ints));
}just spews errors about |
|
This is best tested in NodeScopeResolver::testFileAsserts(), it's just about type inference. We don't need to add integration test for the "accepts type" rules. |
| $argType = $scope->getType($functionCall->args[0]->value); | ||
| if ($argType->isArray()->yes()) { | ||
| $isIterable = $argType->isIterableAtLeastOnce(); | ||
| if ($isIterable->no()) { |
There was a problem hiding this comment.
Nice, this is exactly how I'd implement it 👍
|
It seems that /**
* @param int[] $ints
*/
function dummy2(array $ints): void
{
if (count($ints) > 0) {
takesInt(min($ints)); //should be fine
takesInt(max($ints)); //should be fine
} else {
takesInt(min($ints)); //definitely not ok
takesInt(max($ints)); //definitely not ok
}
} |
|
Looks like some cases aren't covered: https://phpstan.org/r/90c6a1be-8301-4d60-9715-634814964a6a (here it works for You can look into it in TypeSpecifier, and also add some type assertions. A non empty array is |
|
Seems like it only works for |
|
Alright, let’s merge this after the build passes and then I’ll ask you to fix the TypeSpecifier for these cases, thanks 😊 |
|
Thank you! |
Working on tests, just thought it would be nice to get some feedback on this 👍
https://phpstan.org/r/4d4d5332-d1ad-45b2-bbdd-43c8cb87ff61
https://3v4l.org/f0kNk
I'm not 100% sure this is the right way to address the issue since in 8.0 this starts throwing a
ValueErrorinstead. But, since most of us are still using 7, I think this should be useful anyway.