Repository navigation
Analyse partial function applications as closures - #6932
Open
SanderMuller wants to merge 3 commits into
Open
SanderMuller wants to merge 3 commits into
SanderMuller wants to merge 3 commits into
Conversation
A call with a ? placeholder (PHP 8.6) passed the guards that only skipped first-class callables and crashed in getArgs(). NodeScopeResolver now replaces it with PartialFunctionApplicationNode, which processes the callee and the bound arguments and has the type Closure. The guards in front of getArgs() check isPartialFunctionApplication(). PartialFunctionApplicationRule reports partial function application below PHP 8.6, and the nullsafe and new forms that PHP does not compile. ClassStatementsGatherer counts a partially applied method as a call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sion check The detector parses with the tokenizer of PHP 8.5, which cannot read the ? placeholder. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PHPStan crashes on a partial function application, for example
str_replace(' ', '-', ?). The guards in front ofgetArgs()only skip first-class callables, so a call with a?placeholder gets through. The crash starts in the parser visitors (assert(!$this->isPartialFunctionApplication()), as in the playground link in the issue) or later inArgumentsHandler.This PR does not add precise closure types yet. The result type is
Closure, and a follow-up can build the signature from the RFC rules.NodeScopeResolverreplaces a partial function application with a new virtual node,PartialFunctionApplicationNode, like it does for first-class callables. Its handler processes the callee and the bound arguments, because PHP evaluates them when it creates the closure. Rules for the call itself do not see the original node.getArgs()useisPartialFunctionApplication()now. Code that needs a first-class callable, like the pipe operator support, still checks for one.$a?->b(?)andnew Foo(?), which PHP does not compile.$a?->b(...)crashed before this change too, and now gets the same error.ClassStatementsGatherercounts$this->foo(?)as a call, so a private method that only a partial application uses is not reported as unused.Calls in constant expressions, for example a parameter default
strlen(?), get the typeClosuretoo.Part of phpstan/phpstan#15364
🤖 Generated with Claude Code