Skip to content

Commit c9aec10

Browse files
ondrejmirtesclaude
andcommitted
Seed the closure type cache from the call-argument body walks
processArgs() walks closure and arrow function arguments itself; the reads that follow - the preferred ClosureType invalidate-expression read for closures and the invalidation read for arrow functions - then priced the argument through another body walk. Seeding the type cache from the walk just performed makes those reads cache hits. The reads themselves are untouched: when a parked fiber may still complete the gathered data, the seed is skipped and they keep re-walking with the fibers flushed, preserving the completeness contract documented at the closure read. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DaBZjgksga4c5s6Q9FniY7
1 parent 32fc5cb commit c9aec10

1 file changed

Lines changed: 11 additions & 1 deletion

File tree

‎src/Analyser/NodeScopeResolver.php‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
use PhpParser\NodeFinder;
5050
use PhpParser\NodeTraverser;
5151
use PHPStan\Analyser\ExprHandler\AssignHandler;
52+
use PHPStan\Analyser\ExprHandler\Helper\ClosureTypeResolver;
5253
use PHPStan\Analyser\ExprHandler\Helper\ImplicitToStringCallHelper;
5354
use PHPStan\Analyser\ExprHandler\Helper\MethodThrowPointHelper;
5455
use PHPStan\BetterReflection\Reflection\Adapter\ReflectionClass;
@@ -3875,6 +3876,10 @@ public function processArgs(
38753876

38763877
$this->callNodeCallbackWithExpression($nodeCallback, $arg->value, $scopeToPass, $storage, $context);
38773878
$closureResult = $this->processClosureNode($stmt, $arg->value, $scopeToPass, $storage, $nodeCallback, $context, $parameterType, $parameterNativeType);
3879+
// the preferred ClosureType read below now answers from this seed
3880+
// instead of walking the body again (unless a parked fiber may
3881+
// still complete the gathered data - then it keeps re-walking)
3882+
$this->container->getByType(ClosureTypeResolver::class)->seedCacheFromClosureWalk($scopeToPass, $arg->value, $closureResult, $storage);
38783883
if ($this->callCallbackImmediately($parameter, $parameterType, $calleeReflection)) {
38793884
$throwPoints = array_merge($throwPoints, array_map(static fn (InternalThrowPoint $throwPoint) => $throwPoint->isExplicit() ? InternalThrowPoint::createExplicit($scope, $throwPoint->getType(), $arg->value, $throwPoint->canContainAnyThrowable()) : InternalThrowPoint::createImplicit($scope, $arg->value), $closureResult->getThrowPoints()));
38803885
$impurePoints = array_merge($impurePoints, $closureResult->getImpurePoints());
@@ -3958,7 +3963,12 @@ public function processArgs(
39583963
}
39593964

39603965
$this->callNodeCallbackWithExpression($nodeCallback, $arg->value, $scopeToPass, $storage, $context);
3961-
$arrowFunctionResult = $this->processArrowFunctionNode($stmt, $arg->value, $scopeToPass, $storage, $nodeCallback, $parameterType, $parameterNativeType)->getExpressionResult();
3966+
$processArrowFunctionResult = $this->processArrowFunctionNode($stmt, $arg->value, $scopeToPass, $storage, $nodeCallback, $parameterType, $parameterNativeType);
3967+
// the invalidation read below now answers from this seed instead
3968+
// of walking the body again (unless a parked fiber may still
3969+
// complete the gathered data - then it keeps re-walking)
3970+
$this->container->getByType(ClosureTypeResolver::class)->seedCacheFromArrowFunctionWalk($scopeToPass, $arg->value, $processArrowFunctionResult, $storage);
3971+
$arrowFunctionResult = $processArrowFunctionResult->getExpressionResult();
39623972
if ($this->callCallbackImmediately($parameter, $parameterType, $calleeReflection)) {
39633973
$throwPoints = array_merge($throwPoints, array_map(static fn (InternalThrowPoint $throwPoint) => $throwPoint->isExplicit() ? InternalThrowPoint::createExplicit($scope, $throwPoint->getType(), $arg->value, $throwPoint->canContainAnyThrowable()) : InternalThrowPoint::createImplicit($scope, $arg->value), $arrowFunctionResult->getThrowPoints()));
39643974
$impurePoints = array_merge($impurePoints, $arrowFunctionResult->getImpurePoints());

0 commit comments

Comments
 (0)