diff --git a/resources/constantToFunctionParameterMap.php b/resources/constantToFunctionParameterMap.php index 9da9627c70b..481b68f676e 100644 --- a/resources/constantToFunctionParameterMap.php +++ b/resources/constantToFunctionParameterMap.php @@ -305,6 +305,7 @@ 'constants' => [ 'ARRAY_FILTER_USE_KEY', 'ARRAY_FILTER_USE_BOTH', + 'ARRAY_FILTER_USE_VALUE', ], ], ], diff --git a/src/Type/Php/ArrayFilterFunctionReturnTypeHelper.php b/src/Type/Php/ArrayFilterFunctionReturnTypeHelper.php index b5affda6003..e9e7627eeab 100644 --- a/src/Type/Php/ArrayFilterFunctionReturnTypeHelper.php +++ b/src/Type/Php/ArrayFilterFunctionReturnTypeHelper.php @@ -323,7 +323,10 @@ private function determineMode(?Expr $flagArg, Scope $scope): ?int return null; } - if ($flagValues[0] === $this->getConstant('ARRAY_FILTER_USE_KEY')) { + // ARRAY_FILTER_USE_VALUE (PHP 8.6+) is 0, the default mode + if ($flagValues[0] === 0) { + return self::USE_ITEM; + } elseif ($flagValues[0] === $this->getConstant('ARRAY_FILTER_USE_KEY')) { return self::USE_KEY; } elseif ($flagValues[0] === $this->getConstant('ARRAY_FILTER_USE_BOTH')) { return self::USE_BOTH; diff --git a/tests/PHPStan/Analyser/nsrt/bug-15372.php b/tests/PHPStan/Analyser/nsrt/bug-15372.php new file mode 100644 index 00000000000..53a1f6d91e7 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-15372.php @@ -0,0 +1,17 @@ += 8.6 + +declare(strict_types = 1); + +namespace Bug15372; + +use function PHPStan\Testing\assertType; + +/** + * @param list $list + */ +function doFoo(array $list): void +{ + assertType('array, int>', array_filter($list, static fn ($item): bool => $item !== null, ARRAY_FILTER_USE_VALUE)); + assertType('array, int>', array_filter($list, static fn ($item): bool => $item !== null, mode: ARRAY_FILTER_USE_VALUE)); + assertType('array, int>', array_filter($list, static fn ($item): bool => $item !== null, 0)); +} diff --git a/tests/PHPStan/Reflection/constantToFunctionParameterMap.neon b/tests/PHPStan/Reflection/constantToFunctionParameterMap.neon index 72ae924610a..7e44150e458 100644 --- a/tests/PHPStan/Reflection/constantToFunctionParameterMap.neon +++ b/tests/PHPStan/Reflection/constantToFunctionParameterMap.neon @@ -1,2 +1,2 @@ parameters: - phpVersion: 80500 + phpVersion: 80600 diff --git a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRulePhp86Test.php b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRulePhp86Test.php new file mode 100644 index 00000000000..6111a053e4b --- /dev/null +++ b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRulePhp86Test.php @@ -0,0 +1,64 @@ + + */ +class CallToFunctionParametersRulePhp86Test extends RuleTestCase +{ + + protected function getRule(): Rule + { + $broker = self::createReflectionProvider(); + return new CallToFunctionParametersRule( + $broker, + new FunctionCallParametersCheck( + new RuleLevelHelper( + $broker, + checkNullables: true, + checkThisOnly: false, + checkUnionTypes: true, + checkExplicitMixed: true, + checkImplicitMixed: true, + checkBenevolentUnionTypes: false, + discoveringSymbolsTip: true, + ), + new NullsafeCheck(), + new UnresolvableTypeHelper(), + new PropertyReflectionFinder(), + $broker, + checkArgumentTypes: true, + checkArgumentsPassedByReference: true, + checkExtraArguments: true, + checkMissingTypehints: true, + ), + ); + } + + public function testBug15372(): void + { + $this->analyse([__DIR__ . '/data/bug-15372.php'], [ + [ + 'Constant SORT_REGULAR is not allowed for parameter #3 $mode of function array_filter.', + 12, + ], + ]); + } + + public static function getAdditionalConfigFiles(): array + { + return [ + __DIR__ . '/data/call-to-function-php86.neon', + ]; + } + +} diff --git a/tests/PHPStan/Rules/Functions/data/bug-15372.php b/tests/PHPStan/Rules/Functions/data/bug-15372.php new file mode 100644 index 00000000000..d567a5eeb15 --- /dev/null +++ b/tests/PHPStan/Rules/Functions/data/bug-15372.php @@ -0,0 +1,13 @@ += 8.0 + +declare(strict_types = 1); + +namespace Bug15372; + +function (array $a): void { + array_filter($a, fn ($v) => $v > 1, ARRAY_FILTER_USE_VALUE); + array_filter($a, fn ($v) => $v > 1, mode: ARRAY_FILTER_USE_VALUE); + array_filter($a, fn ($k) => $k > 1, ARRAY_FILTER_USE_KEY); + array_filter($a, fn ($v, $k) => $v > $k, ARRAY_FILTER_USE_BOTH); + array_filter($a, fn ($v) => $v > 1, SORT_REGULAR); +}; diff --git a/tests/PHPStan/Rules/Functions/data/call-to-function-php86.neon b/tests/PHPStan/Rules/Functions/data/call-to-function-php86.neon new file mode 100644 index 00000000000..77372e44d42 --- /dev/null +++ b/tests/PHPStan/Rules/Functions/data/call-to-function-php86.neon @@ -0,0 +1,2 @@ +parameters: + phpVersion: 80600