From 93e2c38878921d453a6ee6b248ef9d33d0f3ad72 Mon Sep 17 00:00:00 2001 From: Flechazoie Date: Fri, 12 Jun 2026 19:06:01 +0800 Subject: [PATCH] fix: run the compiler pipeline on a worker thread with a larger stack The compiler is recursive-descent throughout (parsing, AST->IR lowering, type inference), so stack usage grows linearly with expression length. tests/long_code2 (~4000 terms) already needs >5 MiB of the default 8 MiB main-thread stack; an 8000-term expression overflows it outright. Run the pipeline on a worker thread with a 256 MiB stack instead -- the same technique rustc uses to sidestep deep-recursion stack overflows. The reservation is virtual memory only; pages are committed on demand. --- src/main.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 6506296..1c26891 100644 --- a/src/main.rs +++ b/src/main.rs @@ -162,8 +162,24 @@ fn run() -> Result<()> { /// Entry point: delegates to [`run`] and converts any error into a /// human-readable message printed to stderr, exiting with code 1. +/// +/// The compiler is recursive-descent throughout (parsing, AST→IR lowering, +/// type inference), so a deeply nested source expression — e.g. a sum of +/// several thousand terms — recurses as deep as the expression nests and can +/// exhaust the default 8 MiB main-thread stack. We run the pipeline on a +/// worker thread with a generous stack instead, the same technique rustc uses +/// to sidestep deep-recursion stack overflows. fn main() { - if let Err(e) = run() { + const COMPILER_STACK_SIZE: usize = 256 * 1024 * 1024; + + let result = std::thread::Builder::new() + .stack_size(COMPILER_STACK_SIZE) + .spawn(run) + .expect("failed to spawn compiler worker thread") + .join() + .expect("compiler worker thread panicked"); + + if let Err(e) = result { eprintln!("Error: {e:#}"); std::process::exit(1); }