100%

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>>.hash reached only by nesting). Its entire surface is ori_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 calls equals(T)/debug(T) on its OWN rigid type param T. The recorder records assert_eq’s own instance but the nested calls are type-checked against rigid T and 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_calleelookup_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:

  1. 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. The assert_eq → equals/debug signature class is a DIFFERENT residual the §04 closure never materializes a body for.
  2. 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 from Pool.resolutions — the apply.rs doc already names the unwired mono_instance_id = None fallback gap. The recorder-var-mapping fix (resolve_scheme_var) was SUPERSEDED in §09; re-attempting it is a known dead-end.
  3. TDD-first is non-negotiable: the recorder spine + the dispatch fix site are ZERO-unit-tested (maybe_record_mono_instance tc=0, lookup_mono_dispatch tc=0; §3.7). maybe_record_mono_instance is also the single HIGHEST-churn symbol in the graph (hotspot 10,702; §3.8) — author failing AOT spec tests on assert_eq<T>/repeat/transform BEFORE touching it.
  4. Close at §07, not here (per the plan’s §02 HISTORY structural finding): the mono-grep functional criterion runs ONE whole-corpus ./test-all.sh at §07 whole-corpus-verification (s-50bfe700). §05’s deliverable is the verified dispatch extension + dual-exec parity on focused spec tests.
  5. 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}.ori pass 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) == 0 probe — 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_progress livelock). Amended to gate on §05’s actual deliverable: the focused spec tests pass AOT. The whole-corpus transform signal (138, empirically collateral from struct_types.ori’s 34 variable not yet defined codegen 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.