You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 596dd95
Browse filesBrowse the repository at this point in the historyBrowse files
Use the enclosing body's send-decided template argument resolutions inside nested closure bodies
- TemplateArgumentFrame: record which resolutions a send decided (sentResolutionKeys,
filled by TemplateArgumentResolver::collectSentResolutionKeys()) and expose them via
resolveSentFromEnclosingBody(), which walks up the parent frames
- ResolvedFunctionVariantWithOriginal::unresolvedOrResolvedTemplateArgument(): while a
closure body observes, reuse an enclosing body's send-decided resolution of the call
site instead of creating a fresh marker that the closure's own pass resolves to the
literal initial type (method, function and static calls)
- NewHandler (unresolvedArgumentList(), rekeyParentTemplateArgument()) and
GenericTypeTemplateTraverser: same for `new` sites - constructor-inferred arguments,
classes without a constructor, and arguments inherited from a parent constructor
- ClosureTypeResolver::getClosureType(): walk a closure body in a single pass while the
enclosing body is observing, so its markers reach the enclosing body (the generic call
taking the closure, e.g. run(function () { ... })) instead of being resolved by the
closure's own pass before the enclosing body could see the send that decides them
- Only send-decided resolutions are reused: an argument the enclosing body merely
inferred (e.g. from a closure parameter, closureCreatesGenericObject) stays with the
closure's own walk, which infers it per invocation
- Ported to the turbo extension: TemplateArgumentFrame.cpp, TemplateArgumentResolver.cpp,
ResolvedFunctionVariantWithOriginal.cpp, NewHandler.cpp, ClosureTypeResolver.cpp,
support.h, regenerated TemplateArgumentFrame.h / TemplateArgumentResolver.h
- Probed and already correct: arrow functions (part of the enclosing body), nested
closures inside arrow functions, closures stored in a variable inside a closure
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: src/Analyser/Generics/TemplateArgumentFrame.php
+24Lines changed: 24 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -68,6 +68,7 @@ public static function returnTypeOfCall(ParametersAcceptor $acceptor, MutatingSc
68
68
* @param array<int, array{Expr\Closure, int, bool}> $byRefSites spl_object_id() of the closure node => the node, its statement index, whether every invocation was seen
69
69
* @param array<int, array{Expr\Variable, Type, Type}> $staticVariableTypes spl_object_id() of a `static` variable node => the node, its phpdoc and native type - see StaticVariableInference
70
70
* @param array<int, array{Node\Stmt\Static_, array<string, ConditionalExpressionHolder[]>}> $staticVariableConditionalExpressions spl_object_id() of the last statement of a run of `static` statements => the statement, the conditional expressions between the run's variables - see StaticVariableInference::getRuns()
71
+
* @param array<string, true> $sentResolutionKeys the keys of the resolutions a send decided - see resolveSentFromEnclosingBody()
0 commit comments