← board

Rust corpus: the own-written chess engine as Track R's real-world target

STATUS (2026-07-16)

Adapted-branch engine: DONE and bit-comparable by perft. A pxx-friendly branch of the movegen/search compiles and runs, and its move enumeration is identical to the reference perft — the "bit-comparable" bar for a chess engine. Two forms live in test/:

Frontend enablers landed to get here (all green, self-host byte-identical): 5/6-param internal calls (r8/r9 spill), fixed arrays of structs (arr[i].field), slice-of-record (&[Move], slice[i].field).

NOT done: the UNMODIFIED ~/nextlevel/engine/src sources. Those remain blocked on value-flow features the adapted branch sidesteps — in priority order as the real modules hit them: Option<T> (chess.rs wall, stage 2), array-typed return values (fn -> [T; N], attacks.rs), the unity build for data modules (tables.rs, stage 3), then Result/?, String/format!, derives/traits. Do NOT claim the real source compiles — only the adapted branch does.

Why this target is ideal

Baseline (2026-07-09, rparser as of the ports-back pass)

Every module dies within its first 4 lines: use items unhandled, #[derive(...)]/#[inline] attributes unhandled, top-level const X: usize = ... items unhandled, pub type aliases unhandled. So stage 0 is pure swallowing/trivia, cheap and high-leverage.

Staged plan (each stage = more of the engine parses/compiles)

  1. Trivia sweep (cheap): swallow use ...;, #[...]/#![...], //! docs; pub type Alias = ...;; top-level const NAME: T = expr; including const arrays ([T; N] literals already landed at let-level).
  2. Core-language pass (single file): tuple structs (Square(pub u8)), Self in impls, method calls with by-value self returning Self, match on Self::Variant paths, u8/i8 arithmetic with as casts, wrapping_add/sub/shr mapped to plain ops (documented deviation).
  3. Option + str (drives [[feature-rust-rtl-core-types]] and the &str half of [[feature-rust-borrowed-slice-type]]): Option<T> as a monomorphized generic enum (concrete enums + generic fns both exist; generic ENUM instantiation is the new piece), &str as the landed ptr+len slice with .len()/.as_bytes()/byte indexing.
  4. Modules via unity build (kills the multi-file problem the zlib way): a runner.rs concatenation (or a tiny preprocessor step stripping use crate::... and mod x;) — no real module system needed, same trick as test/zlib/runner.c.
  5. ArrayVec replacement: pxx-friendly engine branch with a local struct MoveList { data: [Move; 256], len: usize } — allowed because the target is ours.
  6. Traits/derives as used ([[feature-rust-derive-macros]], [[feature-rust-dyn-trait-dispatch]]): the engine mostly needs PartialEq/Clone/Copy derives (field-wise synthesis) and fmt::Display for UCI output — the latter may be cheaper rerouted through println!-style intrinsics than through real trait dispatch.
  7. Gate ladder: all files parse → chess.rs compiles → perft(4) matches cargo → search finds a mate-in-2 → uci.rs echo loop.

Non-goals

Log