Skip to content

Parameter closure type extensions for array_map/filter/walk/find + native flavour resolution - #6147

Merged
ondrejmirtes merged 2 commits into
2.2.xfrom
closure-type-extensions
Jul 30, 2026
Merged

Parameter closure type extensions for array_map/filter/walk/find + native flavour resolution#6147
ondrejmirtes merged 2 commits into
2.2.xfrom
closure-type-extensions

Conversation

@ondrejmirtes

Copy link
Copy Markdown
Member

Ports the four Array*ParameterClosureTypeExtensions from the resolve-type-rewrite-2 branch and teaches the extension hook to resolve the native flavour.

Commit 1 adds the extensions verbatim. The intrinsic blocks in ParametersAcceptorSelector::selectFromArgs() keep providing the same parameter types (and the rule-facing "expects callable(...)" messages come only from them, so they must stay) — analysis output does not change.

Commit 2 invokes the matched extension a second time on the natively-promoted scope after a non-null phpdoc-side override, and overrides the native parameter type with the result. Extensions may now see a natively-promoted scope from $scope->getType(). This keeps closure parameters natively precise without relying on the intrinsic blocks — verified by locally neutering the array_map block's native side: bug-11014.php stays green through the extension path alone. The existing PregReplaceCallbackClosureTypeExtension now also resolves the native flavour, so the native side of its match shapes becomes precise (one expectation upgraded in preg_replace_callback_shapes.php).

Full test suite, make phpstan and make cs green; the only output change is the more precise native match shape.

🤖 Generated with Claude Code

https://claude.ai/code/session_01DaBZjgksga4c5s6Q9FniY7

ondrejmirtes and others added 2 commits July 30, 2026 14:04
…ray_walk, array_find

Ported from the resolve-type-rewrite-2 branch. The intrinsic blocks in
ParametersAcceptorSelector::selectFromArgs() keep providing the same
parameter types (and the rule-facing messages), so analysis output does
not change - the extensions express the same knowledge through the
public FunctionParameterClosureTypeExtension interface.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DaBZjgksga4c5s6Q9FniY7
…osure type extensions

After a parameter closure type extension overrides the phpdoc-side
parameter type, invoke the same extension again on the natively-promoted
scope and override the native parameter type too. Extensions asking
$scope->getType() then see native types, so the closure parameters keep
their native precision without the intrinsic blocks in
ParametersAcceptorSelector - verified by neutering the array_map block's
native side locally: bug-11014 stays green through the extension path
alone.

MutatingScope::doNotTreatPhpDocTypesAsCertain() narrows its return type
to self (covariant) so the natively-promoted scope can be passed where
MutatingScope is expected.

The existing PregReplaceCallbackClosureTypeExtension now also resolves
the native flavour, making the native side of its match shapes precise
(preg_replace_callback_shapes.php).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DaBZjgksga4c5s6Q9FniY7
@ondrejmirtes
ondrejmirtes merged commit 1d345a6 into 2.2.x Jul 30, 2026
741 of 744 checks passed
@ondrejmirtes
ondrejmirtes deleted the closure-type-extensions branch July 30, 2026 13:57
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.

1 participant