Fix internal error when using first class callable with NullsafeMethodCall#5888
Fix internal error when using first class callable with NullsafeMethodCall#5888phpstan-bot wants to merge 15 commits into
Conversation
…tead of throwing
- `NodeScopeResolver::processExprNode()` handled the first-class callable
syntax (`foo(...)`) for `FuncCall`, `MethodCall`, `StaticCall` and `New_`,
but `NullsafeMethodCall` (`$foo?->bar(...)`) fell through to the `else`
branch and threw `ShouldNotHappenException`, surfacing as an internal error.
- `NullsafeMethodCall` is the only `Expr\CallLike` subclass that was missing
from this branch. It is added by wrapping the call in a `MethodCallableNode`
built from an equivalent `MethodCall`, since `$foo?->bar(...)` is a fatal
error in PHP ("Cannot combine nullsafe operator with Closure creation") and
must not crash the analyser.
- Type resolution already routed correctly through `NullsafeMethodCallHandler`,
so no internal error occurs anywhere the expression is typed (assignment,
argument, array element, return).
staabm
left a comment
There was a problem hiding this comment.
Crash bug fixes need a AnalyserIntegrationTest
…ll crash Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Done. I addressed staabm's review by adding the requested What I did
Verification
Committed as |
…irst-class callable NullsafeMethodCall $foo?->bar(...) is a fatal error in PHP, but PHPStan only silently treated it as a regular method-call first-class callable. Carry a nullsafe flag on MethodCallableNode and report the non-ignorable error from MethodCallableRule. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…inal node Instead of a separate `$nullsafe` constructor flag, store the original `NullsafeMethodCall` in `MethodCallableNode::$originalNode` and derive `isNullsafe()` from an `instanceof` check. ClassStatementsGatherer converts the nullsafe node into a regular `MethodCall` when collecting it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Represent the nullsafe first-class callable in its own virtual node and report "Cannot combine nullsafe operator with Closure creation." from a dedicated NullsafeFirstClassCallableRule, instead of overloading MethodCallableNode/MethodCallableRule with a nullsafe branch. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Move the nullsafe first-class callable coverage out of MethodCallableRuleTest into a dedicated NullsafeFirstClassCallableRuleTest. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
NullsafeMethodCall as a MethodCall instead of throwing|
Since there is a new rule, it has to be approved by ondrej |
|
@ondrejmirtes this implements a simple new rule. would be great to have your approval. |
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Maybe you could split the PR in two and merge the bugfix @staabm ? |
|
I don't think its worth splitting up, as the internal error exists since 2023 and it seems noone else triggered it yet. |
Summary
Using the first-class callable syntax together with the nullsafe operator
(
$foo?->bar(...)) crashed PHPStan withInternal error.. While this is afatal error in PHP itself ("Cannot combine nullsafe operator with Closure
creation"), PHPStan must not crash on it. This change makes the analyser treat
such an expression as a regular method-call first-class callable.
Fixes phpstan/phpstan#9746