fix: preserve TCO through error values#818
Open
He-Pin wants to merge 1 commit intodatabricks:masterfrom
Open
Conversation
115eba9 to
6f1f2ee
Compare
Keep tail-position error values and boolean-result checks on the TailCall trampoline without allocating per-wrapper continuation objects. This preserves correct error ordering while keeping the hot resolve loop GC-light and JIT-friendly.
6f1f2ee to
e2abf73
Compare
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.
Rebased onto current
masteratb4c667d5(Add lazy array views for large stdlib arrays (#814)).Motivation
error valueevaluatesvalueimmediately before throwing. That value is a tail position for auto-TCO and explicittailstrict, but resolving aTailCallinside theerrorexpression would re-enter the trampoline from the current function body and can bring back recursive stack growth for deeperror f(n - 1)chains.error valuealso must not be treated as an unconditional non-recursive exit. A function likelocal f() = error f()has no base case; auto-TCOing it would turn the existing max-stack diagnostic into an infinite trampoline loop.Implementation
error valuewith tail-call support and attach a delayed error-value continuation to the returnedTailCall.TailCallas primitive/ref fields: optional&&/||validation plus optionalerror valuethrow.TailCall.resolvecarries pending checks in local parameters and returns immediately when no final check is pending.error valuepreempts any outer boolean check or outer error throwExpr.Errorrecursively inspects its value expression instead of always counting as a non-recursive exit.Performance notes
TailCall.Tests
New golden tests cover:
tailstrictthrougherror valueerror f(n - 1, unused)chainerror valueexpression whose non-recursive exit is inside the error valueerror f()case that must keep the max-stack diagnosticVerification
./mill --no-server 'sjsonnet.jvm[3.3.7].compile'./mill --no-server 'sjsonnet.jvm[2.13.18].compile'./mill --no-server 'sjsonnet.jvm[2.12.21].compile'./mill --no-server 'sjsonnet.jvm[3.3.7].test.testOnly' sjsonnet.FileTests sjsonnet.TailCallOptimizationTests./mill --no-server 'sjsonnet.js[2.13.18].compile' 'sjsonnet.wasm[2.13.18].compile'./mill --no-server 'sjsonnet.native[2.13.18].compile'./mill --no-server '__.checkFormat'./mill --no-server '_.jvm[_].__.test'./mill --no-server '_.js[_].__.test'./mill --no-server '_.wasm[_].__.test'./mill --no-server '_.native[_].__.test'git diff --checkRebase note
The previous CI failures were caused by the stale base:
EncodingModule.scalahad an unusedUTF_8import on that revision. Currentmasteruses that import, so rebasing fixes those compile failures.