Section 04: Derived trait-method emitter completion across receiver shapes (ROOT A)
Goal
The §09/BUG-02-066 fix made derived equals/debug/compare/hash mono-aware ONLY for generic-composite receivers (derive_codegen consuming Pool.resolutions per instantiation). The residual equals (56) / hash (38) / debug (58) hits are the same derived methods on receiver shapes that path does not cover. Extend derive_codegen to all receiver shapes from §01’s classification.
Implementation Sketch
Extend codegen/derive_codegen to emit derived equals/hash/debug for every receiver shape that currently starves (per §01.1), reusing the Pool.resolutions mono-aware mechanism. Keep the 4-crate derive sync (ir/types/eval/llvm) intact per the derived-trait sync rule. Dual-exec parity vs the interpreter’s derived-method dispatch is the gate. Do NOT regress the §09 generic-composite coverage.
Spec References
codegen/derive_codegen/; Pool.resolutions (BUG-02-066 mechanism); ir.md §DerivedTrait (4-crate sync); layer-coverage.md §3.1.
Work Items
- TDD-first: author failing AOT spec tests for derived equals/hash/debug on the §01-identified uncovered receiver shapes; confirm ‘missing mono instance?’ pre-fix; pin the §09 generic-composite cases as regression guards (must stay green).
- Extend derive_codegen to the uncovered receiver shapes via Pool.resolutions; interp==LLVM parity; zero leaks; no regression of the §09 composite coverage.
- Layer-matrix closure (L1-L12); equals/hash/debug residual signatures absent from the test-all mono grep; debug+release; dual-exec; leak; 4-crate derive sync verified.
Fresh intel (regenerated)
This is NOT a new mechanism — it is the completion of one already-shipped mechanism to the receiver shapes it skips. BUG-02-066 (resolved, high) built the entire mono-aware derive path: concrete_instantiations enumerates Pool.resolutions instantiations, emits a layout-correct method per instance, and registers it via register_mono_derive_function into the mono_derive_functions[(concrete_idx, method)] map; the call-site lookup derived_method_full reads that map first, then falls back to method_functions[(type_name, method)]. The “missing mono instance?” diagnostic (apply.rs:337 / terminators.rs:429) fires when NEITHER map is populated for a (receiver, method) pair. §04 makes the population reach the starving shapes.
The decisive [JOIN]: the entry point compile_derives iterates module.types (types DECLARED in the current module carrying #[derive(...)]) and, for each, asks concrete_instantiations for Applied(type_name, [concrete]) bodies in the pool. A derived method starves when its receiver shape is one this iteration never materializes a body for — a derive on a Result/Option-arm payload, a List/Set/Map field, a recursive sum child, or a generic instantiation whose Applied body is not reachable from module.types. The graph proves this is a KNOWN, OPEN, MEDIUM-DENSE bug cluster — eight open BUG-04-2xx derived-receiver miscompiles (Result, List/Set/Map, recursive sum, generic-instantiation operator) plus the in-progress ROOT-A sibling BUG-04-146.
Decisions this package forces before any code is written:
- The fix surface is the population side, not a per-call-site patch. The leverage is in
compile_derives+concrete_instantiations(the body emitter) andregister_mono_derive_function(the map writer) — NOT inemit_derived_eq_call/emit_derived_hash_call/emit_derived_compare_call(those three are MISSING_ABSTRACTION twins at 0.92–0.955 sim and already do the right lookup; they fail only because the map is empty). - Read BUG-02-066’s implementation first — it owns every symbol §04 touches (
concrete_instantiations,substitute_struct_fields,substitute_enum_variants,register_mono_derive_function,derived_method_full). §04 extends its instantiation-enumeration, and must not regress its generic-composite coverage (the §04 goal pins this). - The derive emitter surface has ZERO unit-test callers (§3.7) and is the hottest churn in the crate (§3.8 —
emit_field_operation869,emit_element_equals808). TDD-first per work itemw-449ffcaais non-negotiable: author failing AOT spec tests on the §01-identified uncovered receiver shapes (confirm “missing mono instance?” pre-fix), AND pin the §09 generic-composite cases as green regression guards. - 4-crate derive sync is a hard invariant (
ir/types/eval/llvmper the derived-trait sync rule). §04 is anori_llvm-only emission completion — it MUST NOT add aDerivedTraitvariant or touchmethod_name(); if it does, all four crates move together. - The close is gated at §07, not here. Per the plan’s §02 HISTORY structural finding, the mono-grep functional criterion runs ONE whole-corpus
./test-all.shat §07whole-corpus-verification(s-50bfe700); §04’s deliverable is the verified emitter extension + dual-exec parity on focused spec tests, not a per-section full test-all.
DIG DEEPER
scripts/intel-query.sh cypher "MATCH (b:Bug) WHERE b.bug_id CONTAINS '02-066' RETURN b.bug_id, b.status, b.title" --human
scripts/intel-query.sh symbol-plans concrete_instantiations --repo ori # → bug-02-066 implementation (completed)
(full dossier: derived-method-receiver-completion—s-0e92117e.intel.md)
Items
- Layer-matrix closure (L1-L12 per layer-coverage.md §1) over the FULL §04 derived-method receiver surface — the focused equals/hash/debug shapes AND the §07-surfaced uncovered
debugderived-method receiver shapes (the 53-hit whole-corpus residual at HEAD 330fc5f6): debug+release builds, AOT binary on a real target, dual-exec parity (L9), ORI_CHECK_LEAKS=1 zero leaks (L10), 4-crate derive sync verified (ir/types/eval/llvm — MUST NOT add a DerivedTrait variant or touch method_name()). Every §04 derived-method signature (equals/hash/debug) ABSENT from the §07 whole-corpus ./test-all.sh captured-log mono grep — the close is recorded at §07’s one whole-corpus run per the plan’s per-section/test-all structural finding, NEVER a per-section test-all. If adebugreceiver-shape AOT cure surfaces an RC double-free (-134) / UAF (-139) / leak, that RC floor is the aims-burden domain (arc.md §STOP): route it to /add-bug aims-burden with #skip(llvm) dispositions, NEVER fix the RC independently here; the mono-instance arm landing is §04 scope, the RC floor is not. - TDD-first (debug receiver-shape residual): author the FAILING AOT spec test(s) for the §07-surfaced uncovered
debugderived-method receiver shapes (the 53-hit whole-corpus residual at HEAD 330fc5f6) on the production AOT path (ori build -> run), asserting the real output. Source-confirm against the live derive_codegen surface (compiler/ori_llvm/src/codegen/derive_codegen/{mod.rs:compile_derives, instantiation.rs:concrete_instantiations + nested_derive_instantiations, mod.rs:compile_instantiation_closure}) which receiver shapes the module.types-iterating concrete_instantiations enumeration starves — a derive on a Result/Option-arm payload, a List/Set/Map field, a recursive-sum child, or a generic instantiation whose Applied body is not reachable from a module.types derive-bearing type. Confirm each currently emits ‘missing mono instance?’ pre-fix via the §07 ./test-all.sh captured-log grep, NEVER diagnostics/aot-guardrail.sh (that is an AIMS RC-burden tool whose count is orthogonal to this codegen-emission metric and FALSE-GREEN on the default path per arc.md §STOP). Pin the §09/BUG-02-066 generic-compositedebugcases as green regression guards (must stay green). Place the .ori leg under tests/spec/ by EXTENDING an existing derived-Debug spec test, NEVER authoring a parallel file. - Extend the derive_codegen population side to reach the §07-uncovered
debugderived-method receiver shapes: in compile_derives + concrete_instantiations (the body emitter) + the compile_instantiation_closure / nested_derive_instantiations transitive walk, materialize the starving (receiver, debug) instantiations into the mono_derive_functions map via register_mono_derive_function, reusing the BUG-02-066 Pool.resolutions mono-aware mechanism (the fix is the POPULATION side, NOT a per-call-site patch in emit_derived_*_call). Verify interp==LLVM parity (L9) + ORI_CHECK_LEAKS=1 zero leaks (L10). Preserve the 4-crate derive sync (ir/types/eval/llvm) — this is an ori_llvm-only emission completion: MUST NOT add a DerivedTrait variant or touch method_name() (if it does, all four crates move together). MUST NOT regress the §09 generic-composite coverage (concrete_instantiations gates on the MATERIALIZED body’s concreteness per the existing has_any_var_or_infer guard — do not weaken it). ABSOLUTE arc.md §STOP: if extending the debug emitter to a starving receiver shape surfaces an RC double-free (-134) / UAF (-139) / leak, that RC floor is the aims-burden domain — route the RC cluster to /add-bug aims-burden (mirroring §02’s to_fixed -> BUG-04-224 precedent: the mono-instance arm landed inline, the RC double-free routed out with #skip(llvm) dispositions). NEVER independently fix the RC; the mono-instance arm is §04 scope, the RC floor is not. Do NOT touch monomorphize/mangle.rs or nounwind/prepare.rs.