From e9472870a0f6e735b8394b2e96119e031f36986a Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Thu, 26 Jun 2025 11:27:59 +0200 Subject: [PATCH 1/3] Avoid false positif in_array always true --- .../Comparison/ImpossibleCheckTypeHelper.php | 5 ++++ ...mpossibleCheckTypeFunctionCallRuleTest.php | 6 ++++ .../Rules/Comparison/data/bug-13151.php | 28 +++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 tests/PHPStan/Rules/Comparison/data/bug-13151.php diff --git a/src/Rules/Comparison/ImpossibleCheckTypeHelper.php b/src/Rules/Comparison/ImpossibleCheckTypeHelper.php index 269e032be9..b0e71448b5 100644 --- a/src/Rules/Comparison/ImpossibleCheckTypeHelper.php +++ b/src/Rules/Comparison/ImpossibleCheckTypeHelper.php @@ -157,6 +157,11 @@ public function findSpecifiedType( continue; } + $haystackArrayValueConstantScalarTypes = $haystackArrayValueType->getConstantScalarTypes(); + if (count($haystackArrayValueConstantScalarTypes) > 1) { + continue; + } + foreach ($haystackArrayValueType->getConstantScalarTypes() as $constantScalarType) { if ($constantScalarType->isSuperTypeOf($needleType)->yes()) { continue 3; diff --git a/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php b/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php index 2ffbddf715..5653c4f113 100644 --- a/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php @@ -981,4 +981,10 @@ public function testBugPR3404(): void ]); } + public function testBug13151(): void + { + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-13151.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Comparison/data/bug-13151.php b/tests/PHPStan/Rules/Comparison/data/bug-13151.php new file mode 100644 index 0000000000..d7baf76b45 --- /dev/null +++ b/tests/PHPStan/Rules/Comparison/data/bug-13151.php @@ -0,0 +1,28 @@ + 1, + 'b' => 1, + 'c' => 1 + ]; + } + + public function test(): void + { + echo in_array(0, $this->extractAsArray(), true) ? "True" : "False"; + } + + public function test2(): void + { + echo in_array(0, $this->extractAsArray()) ? "True" : "False"; + } +} From eb2f23a592b49a4b0c4620ccf4d2ef4139162b40 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Thu, 26 Jun 2025 11:49:37 +0200 Subject: [PATCH 2/3] Add tests --- ...mpossibleCheckTypeFunctionCallRuleTest.php | 12 +++++++ .../Rules/Comparison/data/bug-12755.php | 35 +++++++++++++++++++ .../Rules/Comparison/data/bug-8818.php | 20 +++++++++++ 3 files changed, 67 insertions(+) create mode 100644 tests/PHPStan/Rules/Comparison/data/bug-12755.php create mode 100644 tests/PHPStan/Rules/Comparison/data/bug-8818.php diff --git a/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php b/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php index 5653c4f113..952edfa872 100644 --- a/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php @@ -987,4 +987,16 @@ public function testBug13151(): void $this->analyse([__DIR__ . '/data/bug-13151.php'], []); } + public function testBug8818(): void + { + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-8818.php'], []); + } + + public function testBug12755(): void + { + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-12755.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Comparison/data/bug-12755.php b/tests/PHPStan/Rules/Comparison/data/bug-12755.php new file mode 100644 index 0000000000..6df2876e3b --- /dev/null +++ b/tests/PHPStan/Rules/Comparison/data/bug-12755.php @@ -0,0 +1,35 @@ + $stack + */ + public function sayHello(array $stack): bool + { + return count($stack) === 1 && in_array(MyEnum::ONE, $stack, true); + } +} From e163f8a80a09dab26aac0bed83e3d28161eaf644 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Thu, 26 Jun 2025 12:00:52 +0200 Subject: [PATCH 3/3] Add test --- .../Analyser/NodeScopeResolverTest.php | 1 + ...mpossibleCheckTypeFunctionCallRuleTest.php | 6 +++++ .../Rules/Comparison/data/bug-12412.php | 26 +++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 tests/PHPStan/Rules/Comparison/data/bug-12412.php diff --git a/tests/PHPStan/Analyser/NodeScopeResolverTest.php b/tests/PHPStan/Analyser/NodeScopeResolverTest.php index bc8f4ac04e..32d7746d54 100644 --- a/tests/PHPStan/Analyser/NodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/NodeScopeResolverTest.php @@ -88,6 +88,7 @@ private static function findTestFiles(): iterable yield __DIR__ . '/../Rules/Variables/data/bug-10577.php'; yield __DIR__ . '/../Rules/Variables/data/bug-10610.php'; yield __DIR__ . '/../Rules/Comparison/data/bug-2550.php'; + yield __DIR__ . '/../Rules/Comparison/data/bug-12412.php'; yield __DIR__ . '/../Rules/Properties/data/bug-3777.php'; yield __DIR__ . '/../Rules/Methods/data/bug-4552.php'; yield __DIR__ . '/../Rules/Methods/data/infer-array-key.php'; diff --git a/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php b/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php index 952edfa872..f83bd6f26f 100644 --- a/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php @@ -999,4 +999,10 @@ public function testBug12755(): void $this->analyse([__DIR__ . '/data/bug-12755.php'], []); } + public function testBug12412(): void + { + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-12412.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Comparison/data/bug-12412.php b/tests/PHPStan/Rules/Comparison/data/bug-12412.php new file mode 100644 index 0000000000..397088dfa8 --- /dev/null +++ b/tests/PHPStan/Rules/Comparison/data/bug-12412.php @@ -0,0 +1,26 @@ + + */ +function f(string $type): array { + $field_list = [ ]; + if ($type === 'A') { + array_push($field_list, 'x1'); + } + if ($type === 'B') { + array_push($field_list, 'x2'); + } + + assertType('bool', in_array('x1', $field_list, true)); + + array_push($field_list, 'x3'); + assertType('bool', in_array('x1', $field_list, true)); + + return $field_list; +}