Skip to content

Quality sprint: remove LLVM backend, fix generics crashes, align docs, wire LSP#10

Merged
zvndev merged 7 commits into
masterfrom
audit-quality-sprint-0.9
Jun 8, 2026
Merged

Quality sprint: remove LLVM backend, fix generics crashes, align docs, wire LSP#10
zvndev merged 7 commits into
masterfrom
audit-quality-sprint-0.9

Conversation

@zvndev

@zvndev zvndev commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Deep quality audit + fix sprint on the Turbo compiler. Five parallel review agents (codegen, frontend pipeline, DX/tooling, claim verification, product/language design) produced a severity-ranked report; this branch executes the fixes. Every finding was verified before fixing, and the full suite is green after every change.

Validation

  • Clean release build, 0 warnings · cargo clippy --workspace 0 warnings · cargo fmt --check clean
  • 462 unit tests pass · 211 integration tests pass (+3 new regression tests) · all examples run
  • Net: +542 / −7,435 (the deletions are mostly the LLVM crate)

Highlights

Architectural: removed the experimental LLVM backend

It was a partial second implementation (~half the builtins), didn't build from the documented steps (zstd link error), and offered no measured speedup over Cranelift — which already beats cc -O2 on fib. Removing it kills ~6.8K LOC of duplicated codegen, an unbuildable advertised feature, and an unreproducible perf claim. Cranelift is now the single, honest backend.

Two CRITICAL bugs fixed (both verified)

  • Generic function bodies were never type-checked — a silent early return meant let y: i64 = "str" and undefined names inside any generic were accepted. Now checked with type-params erased to the Error poison so real bugs fire without false-positiving on x + 1 over T.
  • Generic [T] indexing segfaultedturbo_ty_from_type_expr dropped type_params recursing into Array/Optional/Result/Fn, so [T]'s element became Struct("T") and the refcount path dereferenced an integer. Fixed + call-site element-type recovery.

DX

  • VS Code extension now ships a real LSP client (the 2,140-LOC server was orphaned) + 25 snippets
  • prnt → "did you mean print?"; 1..n+1 parses; huge ints say "too large for i64"; explain is case-insensitive; LSP diagnostics carry E0NNN; formatter refuses unparseable files

Honesty + hygiene

  • Version drift fixed (README/COMPATIBILITY → 0.9.x; binary size 55KB → real 93KB; builtins 64+ → 100+); SYNTAX.md honesty banner + corrected derive/map-literal tags
  • 8 internal planning docs + a stray screenshot untracked from the repo root (kept on disk, gitignored)

Known pre-existing bugs (NOT regressions — confirmed by rebuilding the original compiler; left for follow-up)

  • examples/todo-cli/main.tb intermittently SIGTRAPs on teardown (string-arena/memory)
  • Cranelift remove_constant_phis panic on int-hashmap multi-function modules

Deferred (flagged, not half-built)

Optional auto-wrap (let x: str? = "hi"), as casts, trait bounds over primitives, generic arity checking, parser in-body error recovery, method-vs-function error wording, AST-based formatter for operator spacing. Each is a design-weight change.

The wedge (product takeaway)

Today Turbo is honestly "a small, fast, Go-simple compiled language with a TS-flavored surface" — not yet full "TypeScript's ease" (object literals, ??/?. on real optionals, typed maps, casts are the gaps). Sharpest defensible wedge right now: the fastest way to write a single-file native CLI/script that starts instantly and ships as a tiny binary.

🤖 Generated with Claude Code

zvndev added 7 commits June 6, 2026 23:37
Cranelift is now the single code-generation backend. The LLVM path was a
partial second implementation (~half the builtins, no push/str_*/math/http),
did not build cleanly from the documented steps (zstd link error), and offered
no measured speedup over Cranelift — which already edges out cc -O2 on the fib
benchmark. Removing it eliminates ~6.8K LOC of duplicated codegen and the cost
of keeping two backends at parity.

- delete turbo-codegen-llvm crate; drop it from the workspace + turbo-cli deps
- remove the `--llvm` cargo feature
- drop the LLVM jobs/steps from CI, nightly, and release workflows
- update RELEASE.md / CLAUDE.md test commands (no more --exclude turbo-codegen-llvm)

A future optimizing backend, if pursued, should lower through a shared
mid-level IR rather than re-walking the AST a second time.
Two correctness holes in generic functions:

1. Generic function bodies were never type-checked — check_function returned
   early for any function with type params, so concrete errors inside them
   (let y: i64 = "str"; undefined names) were silently accepted. Now the body
   is checked with each type parameter erased to the Error poison type, so
   genuine bugs fire while operations over a type param (x + 1) don't
   false-positive.

2. Indexing a generic array param ([T]) segfaulted: turbo_ty_from_type_expr
   dropped type_params when recursing into Array/Optional/Result/Fn, so [T]'s
   element resolved to Struct("T"); indexing then returned an integer typed
   as a struct pointer and the refcount path dereferenced it. The call site
   now also recovers the concrete element type so a [str] arg prints correctly.

Also: undefined-function errors now suggest a close match ("did you mean
`print`?"), backed by a single-source BUILTIN_FNS list.

Adds regression tests generic_body_checked and generic_array_index.
- parser: range upper bound now parses a full binary expression, so `0..len + 1`
  and `1..n - 1` work (previously only a unary was parsed)
- lexer/cli: an integer literal too large for i64 now reports
  "integer literal ... is too large for i64" instead of "unexpected character"
- cli: `explain` accepts lowercase codes (`explain e0100`)
- cli: drop the now-dead `--llvm` build flag
- formatter: refuse to reformat files that don't lex/parse (no more silently
  reindenting broken code)
- lsp: diagnostics now carry the E0NNN error code

Adds regression test range_arith_bound.
- delete unused resolve_cl_type_with_data (was kept alive by #[allow(dead_code)])
- clippy: use std::ptr::eq for raw-pointer comparison; const thread-local Cell;
  collapse a nested if; use RangeInclusive::contains
- rustfmt reflow

cargo clippy --workspace is now warning-clean.
The extension shipped syntax highlighting only — the 2,140-LOC language server
(turbolang lsp) was never reachable from VS Code. Add:

- extension.js: a vscode-languageclient that launches `turbolang lsp` over
  stdio, enabling diagnostics, hover, go-to-definition, completions, references,
  rename, and document symbols in the editor
- package.json: main/activationEvents/deps, plus turbo.lsp.path and
  turbo.lsp.enable settings
- snippets/turbo.json: 25 idiomatic snippets (fn, struct, type, match, for,
  test, server, …)
- README with build/install instructions
- README: drop the v0.8.x label, fix binary size 55KB -> 93KB (measured),
  builtins 64+ -> 100+, fix the VS Code extension line (publisher zvn-dev,
  25 snippets), show the working arrow-closure form in map/filter/reduce,
  remove the LLVM perf row and backend section
- COMPATIBILITY: update the version series to 0.9.x; drop the LLVM backend
  from the experimental list
- CHANGELOG: note the LLVM backend removal under [Unreleased]
- SYNTAX.md: add a banner clarifying it's the design vision (not the changelog),
  correct the derive list to Eq/Clone/Display, and retag map/object literals
  as planned rather than implemented
Untrack 8 internal sprint/audit docs (AUDIT-REPORT, FINDINGS-REPORT, the three
SPRINT-PLAN files, STDLIB-ROADMAP, TODO, turbo/PHASE1-POLISH-SPRINT) and a stray
benchmark screenshot from the public repo root — they leak internal planning and
contradict the current state. The .gitignore already had a section titled
"Internal planning docs (should never be committed)"; these had slipped past it.
Files remain on disk locally; they're now gitignored, along with the stray
mock_agent/simple_agent build artifacts.
@zvndev zvndev merged commit 367d2bb into master Jun 8, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant