From b5e93d59469a15cae0f3b4f7530e1fd491701301 Mon Sep 17 00:00:00 2001 From: phpstan-bot <79867460+phpstan-bot@users.noreply.github.com> Date: Tue, 17 Feb 2026 01:02:40 +0000 Subject: [PATCH 1/5] Mark array_filter, array_map, and array_reduce as pure functions - Added array_filter, array_map, and array_reduce to bin/functionMetadata_original.php with hasSideEffects => false - Regenerated resources/functionMetadata.php to include the new entries - Callback impure points are already tracked separately via processArgs, so impure callbacks will still be detected - Updated tests/PHPStan/Command/data/file-without-errors.php to assign array_filter result (now correctly flagged as no-effect) - New regression test in tests/PHPStan/Rules/Functions/data/bug-11101.php --- bin/functionMetadata_original.php | 3 +++ resources/functionMetadata.php | 3 +++ .../Command/data/file-without-errors.php | 2 +- ...ionStatementWithoutSideEffectsRuleTest.php | 18 +++++++++++++++ .../Rules/Functions/data/bug-11101.php | 23 +++++++++++++++++++ 5 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 tests/PHPStan/Rules/Functions/data/bug-11101.php diff --git a/bin/functionMetadata_original.php b/bin/functionMetadata_original.php index 17be4631a9..50ba6b3ab4 100644 --- a/bin/functionMetadata_original.php +++ b/bin/functionMetadata_original.php @@ -18,6 +18,7 @@ 'array_diff_ukey' => ['hasSideEffects' => false], 'array_fill' => ['hasSideEffects' => false], 'array_fill_keys' => ['hasSideEffects' => false], + 'array_filter' => ['hasSideEffects' => false], 'array_flip' => ['hasSideEffects' => false], 'array_intersect' => ['hasSideEffects' => false], 'array_intersect_assoc' => ['hasSideEffects' => false], @@ -28,6 +29,7 @@ 'array_key_last' => ['hasSideEffects' => false], 'array_key_exists' => ['hasSideEffects' => false], 'array_keys' => ['hasSideEffects' => false], + 'array_map' => ['hasSideEffects' => false], 'array_merge' => ['hasSideEffects' => false], 'array_merge_recursive' => ['hasSideEffects' => false], 'array_pad' => ['hasSideEffects' => false], @@ -35,6 +37,7 @@ 'array_product' => ['hasSideEffects' => false], 'array_push' => ['hasSideEffects' => true], 'array_rand' => ['hasSideEffects' => false], + 'array_reduce' => ['hasSideEffects' => false], 'array_replace' => ['hasSideEffects' => false], 'array_replace_recursive' => ['hasSideEffects' => false], 'array_reverse' => ['hasSideEffects' => false], diff --git a/resources/functionMetadata.php b/resources/functionMetadata.php index a01a7181a6..6dd24442d8 100644 --- a/resources/functionMetadata.php +++ b/resources/functionMetadata.php @@ -724,6 +724,7 @@ 'array_diff_ukey' => ['hasSideEffects' => false], 'array_fill' => ['hasSideEffects' => false], 'array_fill_keys' => ['hasSideEffects' => false], + 'array_filter' => ['hasSideEffects' => false], 'array_first' => ['hasSideEffects' => false], 'array_flip' => ['hasSideEffects' => false], 'array_intersect' => ['hasSideEffects' => false], @@ -737,6 +738,7 @@ 'array_key_last' => ['hasSideEffects' => false], 'array_keys' => ['hasSideEffects' => false], 'array_last' => ['hasSideEffects' => false], + 'array_map' => ['hasSideEffects' => false], 'array_merge' => ['hasSideEffects' => false], 'array_merge_recursive' => ['hasSideEffects' => false], 'array_pad' => ['hasSideEffects' => false], @@ -744,6 +746,7 @@ 'array_product' => ['hasSideEffects' => false], 'array_push' => ['hasSideEffects' => true], 'array_rand' => ['hasSideEffects' => false], + 'array_reduce' => ['hasSideEffects' => false], 'array_replace' => ['hasSideEffects' => false], 'array_replace_recursive' => ['hasSideEffects' => false], 'array_reverse' => ['hasSideEffects' => false], diff --git a/tests/PHPStan/Command/data/file-without-errors.php b/tests/PHPStan/Command/data/file-without-errors.php index 08929907d3..c6d0a42c3a 100644 --- a/tests/PHPStan/Command/data/file-without-errors.php +++ b/tests/PHPStan/Command/data/file-without-errors.php @@ -1,3 +1,3 @@ analyse([__DIR__ . '/data/bug-11101.php'], [ + [ + 'Call to function array_filter() on a separate line has no effect.', + 11, + ], + [ + 'Call to function array_map() on a separate line has no effect.', + 12, + ], + [ + 'Call to function array_reduce() on a separate line has no effect.', + 13, + ], + ]); + } + #[RequiresPhp('>= 8.5')] public function testPipeOperator(): void { diff --git a/tests/PHPStan/Rules/Functions/data/bug-11101.php b/tests/PHPStan/Rules/Functions/data/bug-11101.php new file mode 100644 index 0000000000..161714aa0a --- /dev/null +++ b/tests/PHPStan/Rules/Functions/data/bug-11101.php @@ -0,0 +1,23 @@ + $array + */ +function doFoo(array $array): void +{ + // These should all be reported as having no effect + array_filter($array, 'is_string'); // line 11 + array_map('is_string', $array); // line 12 + array_reduce($array, function ($carry, $item) { // line 13 + return $carry + $item; + }, 0); + + // These are fine - using the return value + $a = array_filter($array, 'is_string'); + $b = array_map('is_string', $array); + $c = array_reduce($array, function ($carry, $item) { + return $carry + $item; + }, 0); +} From a87845fb7e4f05a65d27576360392c41c8189bf7 Mon Sep 17 00:00:00 2001 From: phpstan-bot Date: Tue, 17 Feb 2026 01:12:23 +0000 Subject: [PATCH 2/5] Add regression test for #11100 Closes https://github.com/phpstan/phpstan/issues/11100 --- .../PHPStan/Rules/Pure/PureMethodRuleTest.php | 6 ++++ tests/PHPStan/Rules/Pure/data/bug-11100.php | 30 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 tests/PHPStan/Rules/Pure/data/bug-11100.php diff --git a/tests/PHPStan/Rules/Pure/PureMethodRuleTest.php b/tests/PHPStan/Rules/Pure/PureMethodRuleTest.php index 0aa586868e..c8464ee419 100644 --- a/tests/PHPStan/Rules/Pure/PureMethodRuleTest.php +++ b/tests/PHPStan/Rules/Pure/PureMethodRuleTest.php @@ -279,6 +279,12 @@ public function testAllMethodsArePure(): void ]); } + public function testBug11100(): void + { + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-11100.php'], []); + } + public function testBug12382(): void { $this->treatPhpDocTypesAsCertain = true; diff --git a/tests/PHPStan/Rules/Pure/data/bug-11100.php b/tests/PHPStan/Rules/Pure/data/bug-11100.php new file mode 100644 index 0000000000..a0e3f5f384 --- /dev/null +++ b/tests/PHPStan/Rules/Pure/data/bug-11100.php @@ -0,0 +1,30 @@ += 8.0 + +namespace Bug11100; + +final class FooClass +{ + /** + * @param array $getParams + * + * @phpstan-pure + */ + public function build(array $getParams, string $trailingSlash, bool $useSlashSeparator): string + { + if ($getParams === []) { + return ''; + } + + if ($useSlashSeparator) { + return '/' . implode('/', array_map( + static function (string $key, string|int $value): string { + return rawurlencode($key) . '/' . rawurlencode((string) $value); + }, + array_keys($getParams), + $getParams + )) . $trailingSlash; + } + + return $trailingSlash . '?' . http_build_query($getParams); + } +} From c1ca2ac3e0b876df3a8624182d54aa988bcb9a8b Mon Sep 17 00:00:00 2001 From: phpstan-bot Date: Tue, 17 Feb 2026 01:20:37 +0000 Subject: [PATCH 3/5] Add regression test for #11317 Closes https://github.com/phpstan/phpstan/issues/11317 --- ...nctionStatementWithoutSideEffectsRuleTest.php | 10 ++++++++++ tests/PHPStan/Rules/Functions/data/bug-11317.php | 16 ++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/PHPStan/Rules/Functions/data/bug-11317.php diff --git a/tests/PHPStan/Rules/Functions/CallToFunctionStatementWithoutSideEffectsRuleTest.php b/tests/PHPStan/Rules/Functions/CallToFunctionStatementWithoutSideEffectsRuleTest.php index 7d0d871661..98bbe9d986 100644 --- a/tests/PHPStan/Rules/Functions/CallToFunctionStatementWithoutSideEffectsRuleTest.php +++ b/tests/PHPStan/Rules/Functions/CallToFunctionStatementWithoutSideEffectsRuleTest.php @@ -119,6 +119,16 @@ public function testFirstClassCallables(): void ]); } + public function testBug11317(): void + { + $this->analyse([__DIR__ . '/data/bug-11317.php'], [ + [ + 'Call to function array_map() on a separate line has no effect.', + 12, + ], + ]); + } + public function testBug11101(): void { $this->analyse([__DIR__ . '/data/bug-11101.php'], [ diff --git a/tests/PHPStan/Rules/Functions/data/bug-11317.php b/tests/PHPStan/Rules/Functions/data/bug-11317.php new file mode 100644 index 0000000000..be633f78ee --- /dev/null +++ b/tests/PHPStan/Rules/Functions/data/bug-11317.php @@ -0,0 +1,16 @@ + $a + */ + public function sayHello(array $a): void + { + array_map(function ($i) { + return $i; + }, $a); + } +} From 5bdb306c8f6311e7c59f33fdc405c03c78fbbf03 Mon Sep 17 00:00:00 2001 From: phpstan-bot Date: Tue, 17 Feb 2026 01:21:29 +0000 Subject: [PATCH 4/5] Add regression test for #3770 Closes https://github.com/phpstan/phpstan/issues/3770 --- ...ionStatementWithoutSideEffectsRuleTest.php | 18 +++++++++++++ .../PHPStan/Rules/Functions/data/bug-3770.php | 27 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 tests/PHPStan/Rules/Functions/data/bug-3770.php diff --git a/tests/PHPStan/Rules/Functions/CallToFunctionStatementWithoutSideEffectsRuleTest.php b/tests/PHPStan/Rules/Functions/CallToFunctionStatementWithoutSideEffectsRuleTest.php index 98bbe9d986..057ee275b4 100644 --- a/tests/PHPStan/Rules/Functions/CallToFunctionStatementWithoutSideEffectsRuleTest.php +++ b/tests/PHPStan/Rules/Functions/CallToFunctionStatementWithoutSideEffectsRuleTest.php @@ -119,6 +119,24 @@ public function testFirstClassCallables(): void ]); } + public function testBug3770(): void + { + $this->analyse([__DIR__ . '/data/bug-3770.php'], [ + [ + 'Call to function array_map() on a separate line has no effect.', + 8, + ], + [ + 'Call to function array_map() on a separate line has no effect.', + 15, + ], + [ + 'Call to function array_map() on a separate line has no effect.', + 23, + ], + ]); + } + public function testBug11317(): void { $this->analyse([__DIR__ . '/data/bug-11317.php'], [ diff --git a/tests/PHPStan/Rules/Functions/data/bug-3770.php b/tests/PHPStan/Rules/Functions/data/bug-3770.php new file mode 100644 index 0000000000..c5781f5a34 --- /dev/null +++ b/tests/PHPStan/Rules/Functions/data/bug-3770.php @@ -0,0 +1,27 @@ + $numbers */ +$numbers = []; + +array_map( + function ($value) { + return $value; + }, + $numbers, +); + +array_map( + /** @param 1|2|3 $value */ + function ($value) { + return $value; + }, + $numbers, +); + +array_map( + /** @param 1|2|3 $value */ + fn($value) => $value, + $numbers, +); From 5c94ea9962bfb62788e46605e072728c12282c20 Mon Sep 17 00:00:00 2001 From: phpstan-bot Date: Tue, 17 Feb 2026 01:30:38 +0000 Subject: [PATCH 5/5] Add regression test for #11101 Closes https://github.com/phpstan/phpstan/issues/11101 Co-Authored-By: Claude Opus 4.6