Prelude collection-builtin AOT mono-emission (len/contains in generic/iterator bodies)
Goal
Drive the prelude collection-builtin (len / contains) AOT monomorphization-emission residual to ZERO — the dominant cluster (291 of 525: 220 len + 71 contains) of the §07 whole-corpus mission gate (s-50bfe700). End-state: a generic-body or iterator-adapter call to .len() / .contains() monomorphizes and emits its concrete LLVM instance at AOT, so the unresolved function len in apply — missing mono instance diagnostic no longer fires for these callees in any backend.
Implementation Sketch
The residual was classified in §01 (work_item w-4652a266) at len 220 and persists EXACTLY at 220 after every §02-§06 cure — never touched, because those cures owned the then/then_with/escape (ROOT-A builtin emitter arms), Traceable, derived, and assert_eq-nested families. The §01 cross-reference (w-9bac815e) tied len to sibling BUG-04-119 (imported-generic collect_mono_functions not traversing import_sigs), which is now RESOLVED — yet the residual stands, proving a DISTINCT root: the prelude builtin free-function/method len/contains is not monomorphized/emitted at AOT (LLVM) when called in NON-imported generic-body or iterator-adapter contexts. The signature path: ArcIrEmitter::resolve_callee (ori_llvm/codegen/arc_emitter/apply.rs:244) -> lookup_mono_dispatch (apply.rs:151) misses the concrete instance, so emit_apply (apply.rs:337) / emit_invoke (terminators.rs:429) fall to record_codegen_error_with_msg. The cure extends the ONE canonical resolution+recording chain (typeck collect_mono_functions / canon record_mono_dispatch_if_present / arc lookup_mono_dispatch) to emit the prelude-builtin instance for the concrete element type — NEVER a parallel dispatcher (intel dossier §5 MISSING_ABSTRACTION verdict). Today these are non-fatal WARNs (indirect-dispatch fallback keeps the suite green), but a green suite still emitting the signatures does NOT satisfy the mission (the §09 FALSE-GREEN trap) — the gate is pinned at L8/L11 (AOT + spec), never a typeck-only mono_instances-non-empty assertion.
This is mono/codegen-domain work, DISTINCT from the aims-burden ARC floor (the fat_ptr_iter borrowed-param AOT failures are the expected coexistence floor per arc.md §STOP) — no arc.md §STOP carve-out applies; full compiler rigor (TDD matrix, dual-exec parity, leak check) is required.
Spec References
arc.md §Debugging (ORI_LOG=ori_llvm::mono=debug to distinguish a recording gap from a dispatch gap); §07 whole-corpus-verification (s-50bfe700) work_item w-bf8beb40 (the “route back into §01 classification” contract this section discharges); §01 root-cause-classification (s-b4bb16a3) work_item w-4652a266 (the len 220 inventory entry); layer-coverage.md §1 (L8 AOT, L9 dual-exec parity, L10 leak, L11 spec, L12 production AOT entry point); intel dossier whole-corpus-verification—s-50bfe700.intel.md §2 (the four emission sites) + §5 (extend the canonical chain, never fork).
Items
- RCA + faithful repro: build the release binary, then
ori build(AOT/LLVM) a minimal.len()/.contains()call inside a NON-imported generic-body and an iterator-adapter body; capture theunresolved function len in apply — missing mono instanceemission. TraceArcIrEmitter::resolve_callee(apply.rs:244) ->lookup_mono_dispatch(apply.rs:151) to determine why the concrete prelude-builtin mono instance is absent (recording gap in collect_mono_functions / canon record_mono_dispatch_if_present, vs dispatch-lookup gap). Distinguish from BUG-04-119 (imported-generic import_sigs traversal, RESOLVED) — this is the prelude-builtin NON-imported path. Record graph-recon outcome. - TDD matrix (write failing pins BEFORE fix): type dimension (int, str, [int], Option
, struct, map, set element types) x context dimension (bare top-level, generic-fn body, iterator-adapter body, nested generic) for both lenandcontains. >=1 semantic pin that only passes with the emitted mono instance; >=1 negative pin asserting themissing mono instancediagnostic is GONE. Production-path AOT pins land in compiler/ori_llvm/tests/aot/ (L8/L12 real entry point), not seam-injected. - Fix: emit the monomorphized prelude-builtin (
len/contains) instance for the concrete element type along the non-imported generic/iterator path, at the architecturally-correct emission/recording site (extend the canonical resolve_callee -> lookup_mono_dispatch chain; NEVER fork a parallel dispatcher per intel dossier §5). Debug AND release builds. - Verify (layer matrix): grep -cE ‘unresolved function (len|contains) in (apply|invoke)’ on a fresh test-all.log reads 0 for the len/contains cluster (L8 AOT); interp<->LLVM dual-exec parity preserved across new tests (L9 via
ori test --backend=llvm); ORI_CHECK_LEAKS=1 zero leaks on the new fixtures (L10); spec corpus green (L11). Re-measure the §07 four-signature gate to confirm the ~291 len+contains residual cleared; route any surviving residual back to §01 classification. - TDD matrix (write failing pins BEFORE fix): type dimension (int, str, [int], Option
, struct, map, set element types) x context dimension (bare top-level, generic-fn body, iterator-adapter body, nested generic) for both lenandcontains. >=1 semantic pin that only passes with the emitted mono instance; >=1 negative pin asserting themissing mono instancediagnostic is GONE. Production-path AOT pins land in compiler/ori_llvm/tests/aot/ (L8/L12 real entry point), not seam-injected. ADD two regression guards the cure must NOT break (per intel dossier §0 decision 5 + §4 — both bugs sit on the same livelendispatch surface): (a) name-collision pin — a user-defined generic free fn namedlen/containsin a generic body must NOT self-recurse under the codegen mono name-fallback discriminator (BUG-04-200 hazard); (b) enum-heap-payload pin —lenon a list payload extracted from an enum variant (e.g.match L(xs) -> len(xs)) returns the correct length with interp<->LLVM parity (BUG-04-214 hazard). Land both as negative/regression pins in the production AOT matrix.
Fresh intel (regenerated)
{ “schema_version”: 1, “target”: { “kind”: “plan-section”, “ref”: “aot-mono-stdlib-completeness/s-55bd6aa5” }, “generated_at”: “2026-06-26T05:22:39.335098+00:00”, “graph_state”: { “head_sha”: “e1e71e60”, “last_code_import_at”: “2026-06-26T05:20:34.202Z”, “embedding_stale”: false, “insights_stale”: false, “cpg_stale”: false }, “surfaces”: {}, “summary”: “intel-package[plan-section:aot-mono-stdlib-completeness/s-55bd6aa5] agent-authored dossier”, “degraded”: false, “dossier”: { “objective_symbols”: [], “tiers”: {}, “agent_authored”: true, “constrained_symbols”: [ “resolve_scheme_var”, “maybe_record_mono_instance”, “mangle_mono_name”, “collect_mono_functions” ], “difficulty”: { “class”: “routine”, “research_online”: false, “research_mode”: “auto”, “signals”: [], “plan_dir”: “/home/eric/projects/ori_lang/plans/aot-mono-stdlib-completeness” } } }
(full dossier: prelude-collection-builtin-aot-mono-emission-len-contains—s-55bd6aa5.intel.json)