perf: extend the walker-rule prefilter to call expressions - #584
Merged
Conversation
A call expression's type is its resolved signature's return type, and both the signature and that return type are cached from the main check phase. NodeCouldBeStrictEffect now consults them for KindCallExpression nodes and rules the call out when the declared return type conclusively cannot be a strict Effect, sparing the expensive re-check that GetTypeAtLocation performs on calls. Resolved signatures are instantiated, so generic calls whose instantiation is conclusively non-Effect are ruled out precisely; signature-less calls, optional chains and every inconclusive return type stay conservative. promiseInEffectSuccess also stops computing GetTypeAtLocation for call nodes only to discard it: it now goes straight to the resolved signature's return type and falls back to the location query only when no signature resolves. Diagnostics are unchanged (verified byte-identical on a full Effect monorepo build); wall time for that build drops a further ~4.6% on top of the reference prefilter. Co-Authored-By: Claude Fable 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.
What changed
Follow-up to #583. The reference-node prefilter left call expressions ungated — and calls were the largest remaining source of rule-phase
GetTypeAtLocationcost, because querying a call's type re-runs expensive call-checking machinery.NodeCouldBeStrictEffectnow handlesKindCallExpressionvia a newcallCouldReturnStrictEffect: it consults the cached resolved signature and its cached return type (both computed during the main check phase, so the lookup is nearly free) and rules the call out when the declared return type conclusively cannot be a strict Effect, using the same conservativecouldBeNamedwalk as perf: prefilter walker-rule type queries by declared type #583. Both walker rules pick this up through their existing gates with no rule changes.generic("x")conclusively returns the literal"x"and is ruled out, while signature-less calls,any, Effect-containing unions, and optional chains (return type union-widened withundefined) all stay conservative.promiseInEffectSuccessalso stops computingGetTypeAtLocationfor call nodes only to discard it — it goes straight to the resolved signature's return type, falling back to the location query only when no signature resolves.Soundness
A call expression's type is its resolved signature's return type (
promiseInEffectSuccessalready relied on this equivalence), calls are not flow-narrowed references, andStrictEffectTyperequires the type's symbol to be namedEffect. The gate answers a conclusive no only when the declared return type provably contains no possibly-Effect constituent; every shaky case falls through to the full query, and the whole path is panic-guarded like the rest of the predicate.Verification
tsc -b --diagnosticsbuild of the Effect monorepo.any, and optional chains kept conservative.pnpm lint,pnpm check, and the fullpnpm testsuite pass.🤖 Generated with Claude Code