Skip to content

Commit 1b93306

Browse files
committed
Allow ARRAY_FILTER_USE_VALUE as the mode of array_filter() and narrow its result
Closes phpstan/phpstan#15372
1 parent 0e156a6 commit 1b93306

6 files changed

Lines changed: 99 additions & 1 deletion

File tree

‎resources/constantToFunctionParameterMap.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@
305305
'constants' => [
306306
'ARRAY_FILTER_USE_KEY',
307307
'ARRAY_FILTER_USE_BOTH',
308+
'ARRAY_FILTER_USE_VALUE',
308309
],
309310
],
310311
],

‎src/Type/Php/ArrayFilterFunctionReturnTypeHelper.php‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,10 @@ private function determineMode(?Expr $flagArg, Scope $scope): ?int
323323
return null;
324324
}
325325

326-
if ($flagValues[0] === $this->getConstant('ARRAY_FILTER_USE_KEY')) {
326+
// ARRAY_FILTER_USE_VALUE (PHP 8.6+) is 0, the default mode
327+
if ($flagValues[0] === 0) {
328+
return self::USE_ITEM;
329+
} elseif ($flagValues[0] === $this->getConstant('ARRAY_FILTER_USE_KEY')) {
327330
return self::USE_KEY;
328331
} elseif ($flagValues[0] === $this->getConstant('ARRAY_FILTER_USE_BOTH')) {
329332
return self::USE_BOTH;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php // lint >= 8.6
2+
3+
declare(strict_types = 1);
4+
5+
namespace Bug15372;
6+
7+
use function PHPStan\Testing\assertType;
8+
9+
/**
10+
* @param list<int|null> $list
11+
*/
12+
function doFoo(array $list): void
13+
{
14+
assertType('array<int<0, max>, int>', array_filter($list, static fn ($item): bool => $item !== null, ARRAY_FILTER_USE_VALUE));
15+
assertType('array<int<0, max>, int>', array_filter($list, static fn ($item): bool => $item !== null, mode: ARRAY_FILTER_USE_VALUE));
16+
assertType('array<int<0, max>, int>', array_filter($list, static fn ($item): bool => $item !== null, 0));
17+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Functions;
4+
5+
use PHPStan\Rules\FunctionCallParametersCheck;
6+
use PHPStan\Rules\NullsafeCheck;
7+
use PHPStan\Rules\PhpDoc\UnresolvableTypeHelper;
8+
use PHPStan\Rules\Properties\PropertyReflectionFinder;
9+
use PHPStan\Rules\Rule;
10+
use PHPStan\Rules\RuleLevelHelper;
11+
use PHPStan\Testing\RuleTestCase;
12+
13+
/**
14+
* @extends RuleTestCase<CallToFunctionParametersRule>
15+
*/
16+
class CallToFunctionParametersRulePhp86Test extends RuleTestCase
17+
{
18+
19+
protected function getRule(): Rule
20+
{
21+
$broker = self::createReflectionProvider();
22+
return new CallToFunctionParametersRule(
23+
$broker,
24+
new FunctionCallParametersCheck(
25+
new RuleLevelHelper(
26+
$broker,
27+
checkNullables: true,
28+
checkThisOnly: false,
29+
checkUnionTypes: true,
30+
checkExplicitMixed: true,
31+
checkImplicitMixed: true,
32+
checkBenevolentUnionTypes: false,
33+
discoveringSymbolsTip: true,
34+
),
35+
new NullsafeCheck(),
36+
new UnresolvableTypeHelper(),
37+
new PropertyReflectionFinder(),
38+
$broker,
39+
checkArgumentTypes: true,
40+
checkArgumentsPassedByReference: true,
41+
checkExtraArguments: true,
42+
checkMissingTypehints: true,
43+
),
44+
);
45+
}
46+
47+
public function testBug15372(): void
48+
{
49+
$this->analyse([__DIR__ . '/data/bug-15372.php'], [
50+
[
51+
'Constant SORT_REGULAR is not allowed for parameter #3 $mode of function array_filter.',
52+
10,
53+
],
54+
]);
55+
}
56+
57+
public static function getAdditionalConfigFiles(): array
58+
{
59+
return [
60+
__DIR__ . '/data/call-to-function-php86.neon',
61+
];
62+
}
63+
64+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug15372;
4+
5+
function (array $a): void {
6+
array_filter($a, fn ($v) => $v > 1, ARRAY_FILTER_USE_VALUE);
7+
array_filter($a, fn ($v) => $v > 1, mode: ARRAY_FILTER_USE_VALUE);
8+
array_filter($a, fn ($k) => $k > 1, ARRAY_FILTER_USE_KEY);
9+
array_filter($a, fn ($v, $k) => $v > $k, ARRAY_FILTER_USE_BOTH);
10+
array_filter($a, fn ($v) => $v > 1, SORT_REGULAR);
11+
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
parameters:
2+
phpVersion: 80600

0 commit comments

Comments
 (0)