Skip to content

Allow ARRAY_FILTER_USE_VALUE as the mode of array_filter() and narrow its result - #6681

Merged
staabm merged 2 commits into
phpstan:2.3.xfrom
Amoifr:feature-15372-array-filter-use-value
Oct 9, 2026
Merged

staabm merged 2 commits into
phpstan:2.3.xfrom
Amoifr:feature-15372-array-filter-use-value

Conversation

@Amoifr

@Amoifr Amoifr commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Closes phpstan/phpstan#15372

PHP 8.6 adds ARRAY_FILTER_USE_VALUE (0) as an explicit $mode for array_filter(). It is now part of the allowed constants for that parameter. The parameter takes a single value, so combining it with another mode is still reported as argument.bitmaskNotAllowed.

While testing it, I noticed the result was not narrowed with this mode: ArrayFilterFunctionReturnTypeHelper::determineMode() only recognised the values of ARRAY_FILTER_USE_KEY and ARRAY_FILTER_USE_BOTH, so ARRAY_FILTER_USE_VALUE (and a literal 0) gave array<int, int|null> where omitting the mode gives array<int, int>. A value of 0 now maps to the default mode.

The rule test runs with phpVersion: 80600. The type inference test needs the constant at runtime, so it is gated with // lint >= 8.6.

@@ -1,2 +1,2 @@
parameters:
phpVersion: 80500
phpVersion: 80600

@staabm staabm Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to adjust pre-existing tests? we shouldn't do that

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The map test resolves every constant of constantToFunctionParameterMap.php through reflection for this phpVersion, and ARRAY_FILTER_USE_VALUE only exists as of PHP 8.6, so with 80500 it fails with Constant ARRAY_FILTER_USE_VALUE (used in array_filter($mode)) not found in reflection. With 80600 every existing entry is still checked and passes.

If you'd rather keep this file untouched, I could make the test skip constants that don't exist for the configured version instead. Which do you prefer?

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The implementation is localized, consistent with existing mode handling, and covered by targeted regression tests.

0 open findings

What changed in this PR

Adds PHP 8.6 support for ARRAY_FILTER_USE_VALUE in array_filter() validation and return-type narrowing.

Changes:

  • Allows ARRAY_FILTER_USE_VALUE as the $mode.
  • Treats mode 0 as value filtering for type narrowing.
  • Adds rule and type-inference regression coverage.
File Description
resources/​constantToFunctionParameterMap.php Registers the new allowed mode.
src/​Type/​Php/​ArrayFilterFunctionReturnTypeHelper.php Maps mode 0 to value filtering.
tests/​PHPStan/​Analyser/​nsrt/​bug-15372.php Verifies narrowed result types.
tests/​PHPStan/​Reflection/​constantToFunctionParameterMap.neon Tests constants against PHP 8.6.
tests/​PHPStan/​Rules/​Functions/​CallToFunctionParametersRulePhp86Test.php Adds PHP 8.6 rule coverage.
tests/​PHPStan/​Rules/​Functions/​data/​bug-15372.php Covers valid and invalid modes.
tests/​PHPStan/​Rules/​Functions/​data/​call-to-function-php86.neon Configures PHP 8.6 for the rule test.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@staabm
staabm force-pushed the feature-15372-array-filter-use-value branch from 467ee83 to 594e241 Compare October 9, 2026 08:45
@staabm
staabm merged commit 88e9f4c into phpstan:2.3.x Oct 9, 2026
568 of 569 checks passed
@staabm

staabm commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

array_filter supports a new constant ARRAY_FILTER_USE_VALUE

4 participants