Skip to content

Commit 75596c3

Browse files
Fix phpstan/phpstan#13799: false positive on in_array(...) check with impure second argument (#5141)
Co-authored-by: VincentLanglet <9052536+VincentLanglet@users.noreply.github.com> Co-authored-by: Vincent Langlet <vincentlanglet@hotmail.fr>
1 parent 8f3930e commit 75596c3

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-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: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,4 +1195,16 @@ 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+
'Call to function in_array() with arguments \'c\', list<\'a\'|\'b\'> and true will always evaluate to false.',
1204+
24,
1205+
'Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.',
1206+
],
1207+
]);
1208+
}
1209+
11981210
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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+
}
23+
24+
if (in_array('c', get_whitelist(), true)) {
25+
echo 'ok';
26+
}

0 commit comments

Comments
 (0)