Replace scattered enum transmutes with an index_enum macro - #329
Merged
Conversation
Square, File and Rank each hand-wrote unsafe { transmute } to convert a
u8 back into the enum (~18 call sites). Introduce an index_enum! macro
that generates, for a contiguous #[repr(u8)] enum:
- ALL: the variants indexed by discriminant,
- from_index: the safe checked conversion (None when out of range),
- from_index_unchecked: one audited, debug-asserted unsafe constructor
wrapping the single remaining transmute.
Cold and fallible sites (FEN/UCI parsing, TryFrom, Display/Debug,
Square::next) now use the safe from_index / ALL and contain no unsafe at
all. The few hot infallible conversions (Square::new/file/rank/
flip_perspective, Bitboard::as_square and the bitboard iterator) call
from_index_unchecked with a SAFETY note, keeping them zero-cost.
This shrinks 18 scattered transmutes to a single one inside the macro.
Movegen benchmark is unchanged from baseline (no regression) and the full
perft suite still passes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GVrKvkMe4xDmkRAksacBzk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fifth and last in the sequence (after #325–#328). The
transmutesafety cleanup.Square,File, andRankeach hand-wroteunsafe { mem::transmute }to turn au8back into the enum — ~18 scattered call sites, each an independent chance to introduce UB if a bound was ever wrong.Changes
An
index_enum!macro generates, for a contiguous#[repr(u8)]enum:ALL— the variants indexed by discriminant;from_index— the safe, checked conversion (Noneout of range);from_index_unchecked— one audited,debug_assert-guardedunsafeconstructor wrapping the single remainingtransmute, with a documented safety contract.Cold and fallible sites — FEN/UCI parsing, all the
TryFromimpls,Display/Debug,Square::next— now use the safefrom_index/ALLand contain nounsafeat all. The few hot infallible conversions (Square::new/file/rank/flip_perspective,Bitboard::as_square, and the bitboard iterator) callfrom_index_uncheckedwith a// SAFETYnote explaining why the index is in range by construction.Net: 18 scattered transmutes → 1, inside the macro.
Performance
This is on the movegen hot path, so I benchmarked it. A first, fully-safe version (array indexing everywhere) regressed movegen ~3.4%; keeping the hot infallible conversions zero-cost via
from_index_uncheckedbrings it back to 25.9 ms vs. the 27.4 ms baseline — no regression (within noise, if anything slightly faster).Testing
cargo benchmovegen: no regression vs. baseline.cargo clippy --all-targets --all-featureszero warnings;cargo +nightly fmt --checkclean.Sequence complete
This finishes the five-PR plan you asked for: (1) unify
Game+ tablebase-in-search #325, (2) transposition table / tree reuse #326, (3) datagen self-play #327, (4) UCI completeness #328, and (5) this transmute cleanup.🤖 Generated with Claude Code
https://claude.ai/code/session_01GVrKvkMe4xDmkRAksacBzk
Generated by Claude Code