Section 02: Enum Access Migration and Derive Repair
Context
The live LLVM derive emitters for Eq, Comparable, Hashable, and Format still extract aggregate elements 0 and 1 directly. That is incompatible with the enabled tagged-pointer representation and with future niche/tagless layouts. The old plan also made LLVM TagAccess the universal enum API, which would incorrectly make LLVM vocabulary the owner for the VM and ori_backend.
The final seam has three consumers of two physical plans:
- LLVM
TagAccessis a thin emitter overCompiledEnumLayout. ori_backendhas its own thin BIR/MIR emitter over the identicalCompiledEnumLayout.- the bytecode compiler and verifier use
VmEnumLayout; they do not import LLVM or compiled aggregate indices.
No adapter may select an encoding, infer an ABI, recompute offsets, or silently fall back.
02.1 Derive Repair - Promotion Blocker
- Write the failing production-path TDD matrix first for every shipped enum derive found by a fresh constructor-site census, including Eq, Comparable, Hashable, and Format. Cross
{Explicit, TaggedPtr, Niche when admitted, None}with unit, one-field, multi-field, heterogeneous, generic, nested, recursive-reference, and invalid-layout cases. - Define a closed LLVM enum-access surface over
CompiledEnumLayout: load discriminant, compare discriminant, project a named variant field, obtain payload address/value, construct a variant, replace a tag, and emit drop traversal. Each operation takes stable semantic variant/field identity and returns a checked result. - Migrate
enum_eq.rsto the access surface. Remove aggregate index literals and local slot arithmetic; equality must compare semantic tags and exactly the active variant’s fields for every admitted encoding. - Migrate
enum_comparable.rswith the same access surface. Pin tag ordering, payload lexicographic ordering, tagless behavior, and malformed-plan rejection. - Migrate
enum_hashable.rsand every additional derive emitter found by the census, includingenum_format.rs. Pin equal-values-equal-hashes, variant separation, formatting parity, no panic on valid tagged-pointer input, and checked failure on invalid layout. - Exercise the real CLI/AOT path, not a seam-injected helper only. Verify debug, release, linked AOT, normalized evaluator parity, and leak-free drop behavior for every matrix family.
- Add a negative semantic pin that mutates the supplied field map or encoding and proves validation/emission rejects it before IR construction; the test must fail if the adapter starts guessing index 0 or 1.
- Keep
TAGGED_PTR_CODEGEN_READYenabled and fix the reachable path. Do not green tests by disabling the representation, skipping derives, or routing eligible enums to an unrelated canonical path. - Close the subsection only after a live-source census finds no derive-specific layout decoder or raw aggregate access for enum values.
02.2 Runtime Enums and Shared Compiled Adapters
- Inventory every Option/Result/runtime enum boundary in
ori_rt, LLVM builtins, collection helpers, debug helpers, monadic helpers, FFI glue, and direct-WASM imports/exports. Replace the boolean runtime marker with the typed ABI contract from Section 01. - Migrate LLVM construction, extraction, match, builtin, monadic, RC, debug, and runtime-call consumers to
CompiledEnumLayoutthrough the LLVM adapter. Runtime declarations and call ABIs come from the shared compiled plan. - Add the
ori_backendenum adapter contract and conformance fixtures. BIR/MIR stores stable layout IDs and semantic variant/field IDs; target lowering resolves them from the same compiled plan and contains no copied LLVM classifier. - Add runtime round-trip tests for each actual runtime enum ABI on host and non-host layout fixtures. Cover success/error variants, zero-sized and nontrivial payloads, nested runtime enums, FFI/public boundaries, and direct compiled WASM import/export glue.
- Prove LLVM and
ori_backendserialize identicalCompiledEnumLayoutandFunctionAbifixtures for x86-64, aarch64, riscv64, s390x, and wasm targets. Backend-specific IR may differ; selected layout and ABI may not. - Fail closed when a target lacks a required runtime ABI, encoding, alignment, or relocation capability. Diagnostics must name the enum, target, rejected constraint, and actionable target/backend choice.
- Verify direct WebAssembly module emission uses the compiled adapter and target ABI only; no evaluator call, bytecode generation,
VmEnumLayout, or VM runtime is permitted on this path.
02.3 VM Consumer and Remaining Migration
- Implement bytecode-compiler enum operations from
VmEnumLayout: construct, inspect tag, project semantic field, match/switch, drop/trace, and debug/format. Rewrite operands to verified VM storage locations before execution so the hot loop does not rediscover enum layout. - Make the bytecode verifier prove opcode/layout compatibility, variant bounds, field ownership, payload class, handle validity, drop schema, and unwind cleanup. Add malformed-bytecode tests for cross-variant field access, forged handles, wrong register classes, and double drop.
- Migrate every remaining LLVM enum consumer, including instruction dispatch, RC helpers, ABI/type-info construction, drop emission, and builtins. Replace local i64-slot arithmetic with plan queries; do not merely centralize an LLVM-only helper.
- Delete duplicated enum encoding, field-position, size/alignment, tag-width, and ABI classifiers from
ori_llvm,ori_backend, andori_vm. Preserve only thin mapping code whose input is a validated plan entry. - Add an architecture seam scan backed by API visibility and an explicit allowlist. Detect hardcoded enum aggregate indices, local encoding matches used to classify layout, target layout queries outside the compiled-plan builder, and VM storage queries outside
VmLayoutPlanconstruction/verifier code. - Add combined behavior tests that mix nested enums, collections, iterators, calls, closures, recursion, derives, panic/unwind, and Option/Result runtime calls so isolated microtests cannot hide interaction failures.
- Update crate docs, mission maps, repr rules, bytecode ISA documentation, backend design records, and public comments after the migration. Remove comments that still call the landed
EnumLayoutInfothe universal final SSOT.
02.4 Completion Checklist
- Every enum consumer resolves semantic access through
CompiledEnumLayoutorVmEnumLayout; the evaluator remains layout-abstract. - Every shipped derive handles every admitted encoding and has positive and negative production-path pins.
- The tagged-pointer derive miscompile is fixed without disabling tagged-pointer eligibility or a derive feature.
- Runtime enum construction and calls use typed ABI contracts with host, non-host, and direct-WASM fixtures.
- No compiled backend contains a second enum layout or ABI classifier.
- No VM path consumes compiled byte offsets or LLVM aggregate indices, and no compiled path consumes VM slots or heap schemas.
- Full test-all and targeted debug/release/AOT/native/WASM matrices are green on the canonical verdict surfaces.
- Lints, seam scans, format checks, and repository hygiene are clean.
- Leak checks report zero final live allocations for enum success, panic, unwind, verifier rejection, and runtime failure cases.
- Third-party review is clean and all validated findings are fixed.
- Implementation-hygiene review is clean after third-party review.
- Cross-plan contracts and documentation are synchronized with the retained architecture.
02.R Third Party Review Findings
- The prior section omitted
enum_format.rs, which live source shows also hardcodes explicit aggregate positions. - The prior section proposed hand-dispatching on
EnumTaginside each derive. The revised design makes derives request semantic operations from a shared adapter, preventing another encoding switch from spreading across consumers. - The prior section treated LLVM
TagAccessas the universal consumer seam. The revised design keeps LLVM, VM, andori_backendadapters separate while sharing the one appropriate physical plan.