Latest Results
Fix tuple codec helpers to avoid LSP stack overflows (#7611)
## Summary
I reproduced an LSP crash where opening and incrementally editing
`fuel-o2-exports/contracts/order-book/src/main.sw` could abort the
server and leave stale semantic highlighting behind in the client.
Daniel pointed out that the generated tuple helpers in `std::codec` are
emitted as one large left-associative `&&` chain. This change fixes the
root recursion pressure there instead of carrying the LSP stack-size
workaround.
The generator change is in `sway-lib-std/generate.sh`, and the
regenerated output is checked in at `sway-lib-std/src/codec.sw`. The
snapshot updates are included because the generated helper shape changes
source spans, IR local numbering, bytecode size, and a few gas values in
the affected e2e snapshot outputs.
## Root cause
The LSP crash was a stack overflow while processing generated
`std::codec` tuple code. The tuple triviality helpers were emitted as
deeply left-associated `&&` expressions, e.g. one expression chaining
checks across all tuple elements.
Because `&&` is left-associative, that produces a deeply left-leaning
AST. Recursive compiler and LSP passes then consume one stack frame per
node while lowering, traversing, or building semantic-token state. On
the `fuel-o2-exports` order-book repro, that was enough to bring down
the language server and leave stale semantic highlighting in the editor.
The earlier LSP stack-size mitigation kept the process alive by giving
those recursive paths more stack. Daniel's suggestion fixes the
source-level shape that was creating the stack pressure in the first
place.
## Why this mitigates it
The tuple helpers now use:
```sway
let r = __runtime_mem_id::<Self>() == __encoding_mem_id::<Self>();
let r = r && is_encode_trivial::<A>();
let r = r && is_encode_trivial::<B>();
r
```
instead of one large chained expression.
That keeps each expression shallow, so compiler and LSP recursion does
not scale with the full tuple arity in a single left-deep AST. The
language server no longer needs the stack-size workaround for this
repro.
## Validation
- regenerated `sway-lib-std/src/codec.sw` from
`sway-lib-std/generate.sh`
- verified regeneration produced no extra generated-file diff beyond the
checked-in `codec.sw`
- verified no generated left-deep tuple triviality chains remain
- `RUSTUP_TOOLCHAIN=1.93.0 cargo build -p forc-lsp --release`
- tested in an isolated VS Code session using the rebuilt
`target/release/forc-lsp`
- opened `fuel-o2-exports/contracts/order-book/src/main.sw`
- exercised the original edit/semantic-highlighting path
- observed `225` `textDocument/didChange` notifications and `11`
`textDocument/semanticTokens/range` requests
- no panic, stack overflow, abort, server exit, or stale-highlighting
failure reproduced
- updated the affected e2e `stdout.snap` files after CI snapshot drift
- `RUSTUP_TOOLCHAIN=1.93.0 cargo run --locked --release --bin test --
--locked --kind snapshot` Latest Branches
0%
ironcev/optimize-vec-encoding-decoding 0%
+17%
ironcev/const-generic-array-not-an-indexable-type © 2026 CodSpeed Technology