Skip to content

Error instead of crashing on deeply nested expressions in the transpiler - #31242

Merged
Jarred-Sumner merged 12 commits into
mainfrom
farm/499eacc8/fix-deep-expr-stack-overflow
May 24, 2026
Merged

Error instead of crashing on deeply nested expressions in the transpiler#31242
Jarred-Sumner merged 12 commits into
mainfrom
farm/499eacc8/fix-deep-expr-stack-overflow

Report the stack overflow error from the DCE helpers instead of silen…

fe1dd85
Select commit
Loading
Failed to load commit list.
Claude / Claude Code Review completed May 23, 2026 in 18m 21s

Code review found 2 potential issues

Found 5 candidates, confirmed 2. See review comments for details.

Details

Severity Count
🔴 Important 0
🟡 Nit 2
🟣 Pre-existing 0
Severity File:Line Issue
🟡 Nit test/bundler/transpiler/transpiler.test.js:3694-3698 Test catch rejects the printer StackOverflow error path
🟡 Nit src/js_parser/scan/scan_side_effects.rs:896-898 to_boolean reports stack overflow at EOF loc instead of expression loc

Annotations

Check warning on line 3698 in test/bundler/transpiler/transpiler.test.js

See this annotation in the file changed.

@claude claude / Claude Code Review

Test catch rejects the printer StackOverflow error path

The catch only swallows errors containing `Maximum call stack size exceeded`, but this PR also adds a printer-side guard that surfaces as `"StackOverflow Failed to print code"` (lib.rs:3270 → JSTranspiler.rs:1621 → JSGlobalObject.rs:904) — that string doesn't match, so if a build config ever trips the print guard before the visit guard the catch re-throws, the child exits non-zero without printing `depth-ok`, and the test fails even though nothing crashed. The PR description itself lists "/ a pr

Check warning on line 898 in src/js_parser/scan/scan_side_effects.rs

See this annotation in the file changed.

@claude claude / Claude Code Review

to_boolean reports stack overflow at EOF loc instead of expression loc

Minor: this is the only `report_stack_overflow()` call site that passes `p.lexer.loc()` instead of an expression `loc` — but `to_boolean` runs during the visit pass, after the lexer has consumed the whole source, so `lexer.loc()` points at EOF rather than the deep expression. In practice the once-per-parse guard means `visit_expr_in_out` almost always reports first with a correct `e.loc` and this call is a no-op, so it's a consistency nit rather than a UX bug; `Loc::EMPTY` (or threading a `loc`