Skip to content

Commit 673c613

Browse files
VincentLangletphpstan-bot
authored andcommitted
Fix in_array false positive with possibly-empty non-constant array
- For non-constant arrays that might be empty (isIterableAtLeastOnce is not yes), return null (indeterminate) when the needle type is compatible with the haystack value type, since the array could be empty making in_array return false - Still correctly reports "always false" when needle type is incompatible with haystack value type regardless of array emptiness - Added regression test for the reported issue Closes phpstan/phpstan#13799
1 parent 1b1f48c commit 673c613

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

src/Rules/Comparison/ImpossibleCheckTypeHelper.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,11 @@ public function findSpecifiedType(
141141

142142
return null;
143143
}
144+
145+
if (!$isNeedleSupertype->no()) {
146+
// Array might be empty, so in_array can return false
147+
return null;
148+
}
144149
}
145150

146151
if (!$haystackType instanceof ConstantArrayType || count($haystackType->getValueTypes()) > 0) {

tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,4 +1195,10 @@ public function testBug13566(): void
11951195
]);
11961196
}
11971197

1198+
public function testBug13799(): void
1199+
{
1200+
$this->treatPhpDocTypesAsCertain = true;
1201+
$this->analyse([__DIR__ . '/data/bug-13799.php'], []);
1202+
}
1203+
11981204
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug13799;
4+
5+
/**
6+
* @phpstan-impure
7+
* @return list<'a'|'b'>
8+
*/
9+
function get_whitelist(): array {
10+
$s = [];
11+
if (rand(0, 1)) {
12+
$s[] = 'a';
13+
}
14+
if (rand(0, 1)) {
15+
$s[] = 'b';
16+
}
17+
return $s;
18+
}
19+
20+
if (in_array('a', get_whitelist(), true)) {
21+
echo 'ok';
22+
}

0 commit comments

Comments
 (0)