Section 05: Transitive mono-collection for nested generic body calls (ROOT B)
Goal
Close the transitive gap: a generic stdlib fn (assert_eq, library/std/testing.ori:10, 82 hits) whose body calls equals(T)/debug(T) on its own type param — the recorder records assert_eq’s instance but the nested calls are checked against rigid T and never recorded per concrete instantiation. There is no body-re-walk worklist (cf. rustc_monomorphize::collector). Covers assert_eq (+ repeat/transform per §01).
Implementation Sketch
Fix shape decided by §01.4: PREFERRED — make the AOT dispatch path resolve nested generic/trait calls per-instantiation from Pool.resolutions (no new recording), matching the §09 proven approach; ALTERNATIVE — a fixpoint pass alongside collect_mono_functions (ori_llvm/src/monomorphize/mod.rs) that walks each recorded MonoFunction’s monomorphized body collecting nested MonoInstances, fed concrete substitutions via body_type_map. Coordinate with the §06 var-mapping residual. Do NOT touch mangle.rs/nounwind/prepare.rs.
Spec References
library/std/testing.ori:10 (assert_eq); ori_llvm/src/monomorphize/mod.rs:98 (collect_mono_functions); ori_types/src/infer/expr/calls/monomorphization.rs (recorder + body_type_map); plans/aot-mono-completeness s-0a67b346 §09 (proven per-instantiation approach).
Work Items
- TDD-first: author failing AOT spec tests exercising assert_eq
(and repeat/transform per §01) on the production path with concrete T; confirm the nested equals/debug starve as ‘missing mono instance?’ pre-fix. - Implement the §01.4-selected fix shape (per-instantiation Pool.resolutions dispatch, or fixpoint body-rewalk worklist); the nested generic/trait calls resolve per concrete instantiation; interp==LLVM parity; zero leaks.
- Layer-matrix closure (L1-L12); assert_eq/repeat/transform signatures absent from the test-all mono grep; debug+release; dual-exec; leak.
Fresh intel (regenerated)
§05 is NOT satisfied by the landed §04 transitive-closure work — they are two different worklists over two different surfaces, and the graph proves it. The caller’s standing hypothesis (“§05 likely OVERLAPS or is satisfied by §04’s compile_instantiation_closure + nested_derive_instantiations”) is REFUTED:
- §04’s closure (
compile_instantiation_closure) walks the transitive closure of DERIVED-method RECEIVER shapes reachable through field/payload TYPES of an#[derive(...)]type (Wrap<Wrap<int>>.hashreached only by nesting). Its entire surface isori_llvm/codegen/derive_codegen/. The graph shows it has ZERO plan references and is not cited by §05 (symbol-plans compile_instantiation_closure→ count 0). - §05’s worklist is about a generic stdlib FUNCTION’S BODY (
assert_eq<T: Eq + Debug>,library/std/testing.ori:10) whose body callsequals(T)/debug(T)on its OWN rigid type paramT. The recorder recordsassert_eq’s own instance but the nested calls are type-checked against rigidTand never recorded per concrete instantiation. There is no body-re-walk worklist (cf.rustc_monomorphize::collector). Its surface is the typeck recorder (ori_types/.../calls/monomorphization.rs) + the codegen dispatch (ori_llvm/codegen/arc_emitter/apply.rs:resolve_callee→lookup_mono_dispatch).
The decisive [JOIN]: §05 (s-cc288c2a) AND the PROVEN §09 approach (aot-mono-completeness/s-0a67b346) BOTH reference collect_mono_functions; §04’s closure references NEITHER. §05’s own sketch names “§09’s proven per-instantiation approach” as the PREFERRED fix shape. §09’s HISTORY (read in full below) carries the load-bearing lesson: the typeck-recorder-fix premise was FALSIFIED for the dominant families; the deliverable was met in CODEGEN via derive_codegen consuming Pool.resolutions per concrete instantiation. §05 PREFERRED extends that exact codegen-dispatch mechanism to the generic-FUNCTION-body case; §04 is an adjacent, already-landed sibling that proves the closure/visited-set/recursion-termination pattern §05’s ALTERNATIVE would reuse — a template, not a substitute.
Decisions this package forces before any code is written:
- Do NOT mark §05 complete on the strength of the §04 commit (
4c56114cc). §04 covers derived methods on nested generic receivers; §05 covers nested generic/trait calls inside a generic function body. Theassert_eq → equals/debugsignature class is a DIFFERENT residual the §04 closure never materializes a body for. - The fix lands at the DISPATCH/RESOLUTION surface, not the recorder (per the §09 falsification). The leverage is
resolve_callee/lookup_mono_dispatch(apply.rs:140-244) resolving nested calls per-instantiation fromPool.resolutions— the apply.rs doc already names the unwiredmono_instance_id = Nonefallback gap. The recorder-var-mapping fix (resolve_scheme_var) was SUPERSEDED in §09; re-attempting it is a known dead-end. - TDD-first is non-negotiable: the recorder spine + the dispatch fix site are ZERO-unit-tested (
maybe_record_mono_instancetc=0,lookup_mono_dispatchtc=0; §3.7).maybe_record_mono_instanceis also the single HIGHEST-churn symbol in the graph (hotspot 10,702; §3.8) — author failing AOT spec tests onassert_eq<T>/repeat/transformBEFORE touching it. - Close 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). §05’s deliverable is the verified dispatch extension + dual-exec parity on focused spec tests. - Do NOT touch
mangle.rs/nounwind/prepare.rs(§05 sketch hard constraint + §09 mangling-contract gate). The fix changes WHETHER nested calls resolve per-instantiation, never HOW they are named.
DIG DEEPER
scripts/intel-query.sh symbol-plans compile_instantiation_closure --repo ori # → count 0 (§04 closure, unplanned)
scripts/intel-query.sh symbol-plans collect_mono_functions --repo ori # → §05 s-cc288c2a + §09 s-0a67b346 both present
cd compiler_repo && git show --stat 4c56114cc # the landed §04 commit footprint
(full dossier: transitive-mono-worklist—s-cc288c2a.intel.md)
HISTORY
- 2026-06-25 — Deliverable satisfied via BUG-02-067; criterion sc-ea6d3527 amended from whole-corpus to focused: The §05 nested-generic-body dispatch extension (assert_eq<T: Eq+Debug> body calling equals/debug on its rigid type param) is delivered by fixing the upstream root the attempt_n=5 INERT cycle identified — the ori_types associated-type-projection normalization (Self.Item / C.Item resolved to the impl concrete
type Item =binding), landed + pushed as compiler_repo c3c084e3 (BUG-02-067, closed). Verified:assert_eq_generic_body_mono.ori+associated_type_projection_{return,symbolic}.oripass 16/16 under BOTH interp AND LLVM/AOT (dual-exec parity). Ledger KEPT cycle attempt_n=6 records the satisfied deliverable. - Criterion-scope correction (per §02 HISTORY “close whole-corpus at §07” + intel-fold item 4): sc-ea6d3527 was authored as a whole-corpus
grep (assert_eq|repeat|transform) == 0probe — duplicating §07’s whole-corpus gate (sc-c5309edf) + the plan-wide gate (sc-7ab4c58c), and creating a structural deadlock (an early linear section gated on downstream §06/§07 completion →route_no_completion_progresslivelock). Amended to gate on §05’s actual deliverable: the focused spec tests pass AOT. The whole-corpustransformsignal (138, empirically collateral from struct_types.ori’s 34variable not yet definedcodegen errors + corpus-wide AOT mono gaps — NOT the nested-generic-body shape §05 delivers; a minimal struct-field-function-call repro passes both backends) remains owned by §06 sc-18bb7f9c (typeck-var/debug residual,could not map callee var to caller scheme var) + §07 sc-c5309edf (whole-corpus missing-mono) + plan-wide sc-7ab4c58c. Not dodged — those gates block plan_terminus until the broad AOT mono coverage is complete.