0%

Section 04: Complex-Generic-Arg Method Mono (BUG-04-061)

Status: Not Started Goal: Close the complex-generic-arg gap. Method calls on receivers like Option<[int]>, Option<[[int]]>, Option<{str:int}> resolve through mono dispatch as cleanly as Option<int> does today.

Context: Per §01.3 BUG-04-061 entry, simpler Option<int>.unwrap() and Option<str>.unwrap() work; failure mode is specific to Option<T> where T is a complex generic (e.g., [int] — a heap-typed generic itself). The MonoInstance dedup predicate or the downstream function_compiler mono resolution treats nested-generic receivers as the same instance as scalar-arg receivers, OR the upstream typeck emission fails to record the nested args. Distinct from §03 (simple generic self type) and §05 (builtin Apply).

Reference implementations:

  • Rust rustc_middle::ty::subst::SubstsRef — generic args are a structured array, not a flat list; dedup is full structural equality, including nested substitutions.
  • Swift SIL::SubstitutionMap — substitution maps carry full generic context; mono dispatch uses structural map equality.

Depends on: §01 (cite §01.3 BUG-04-061), §02 (collect_mono_functions stable).

Intelligence Reconnaissance

Queries planned:

  • scripts/intel-query.sh --human callers "MonoInstance" --repo ori — every dedup consumer; identify the predicate site.
  • scripts/intel-query.sh --human file-symbols "compiler/ori_llvm/src/codegen/function_compiler" --repo ori — function_compiler surface (per BUG-04-061 subsystem field).
  • scripts/intel-query.sh --human similar "SubstsRef equality" --repo rust --limit 3 — full structural equality patterns.

Results summary (≤500 chars, recorded 2026-05-14) [ori]: TO BE POPULATED at section start by running the queries above. Scaffold authored 2026-05-14 — queries deferred to execution time when MonoInstance dedup predicate site is current.


04.1 MonoInstance dedup predicate over compound generic args

File(s): compiler_repo/compiler/ori_types/src/check/mod.rs:341-407, compiler_repo/compiler/ori_llvm/src/monomorphize/mod.rs:104-120

  • Locate the MonoInstance dedup predicate (per §01.2 mapping). Is it field equality over (fn_name, receiver_type, generic_args, impl_args, method_args)?
  • Verify receiver_type: Option<Idx> uses interned-pool equality — Idx of Option<[int]> must differ from Idx of Option<int> (verify in pool interning).
  • If the pool DOES discriminate but emission upstream collapses them: fix the emission site to use the post-substitution receiver type, not the unsubstituted Option<T> shape.
  • In monomorphize/mod.rs:104-120, the mangler uses instance.fn_name + generic_args + impl_args + method_args — verify impl_args carries the receiver’s full type substitution. If not, the mangled name collides for Option<int>.unwrap and Option<[int]>.unwrap.
  • Subsection close-out (04.1) — MANDATORY before §04.2:
    • cargo build --release succeeds.
    • Manual repro: ORI_LOG=ori_types=trace ori check fixture.ori for a fixture containing both Option<int>.unwrap() and Option<[int]>.unwrap() shows two distinct MonoInstance emissions.
    • Run /improve-tooling retrospectively on §04.1.
    • Run /sync-claude on §04.1 — MonoInstance dedup semantics changed; check types.md §RG-3 + llvm.md §Type-Qualified Mangling.
    • Run compiler_repo/diagnostics/repo-hygiene.sh --check.

04.2 Mono dispatch wiring in function_compiler

File(s): compiler_repo/compiler/ori_llvm/src/codegen/function_compiler/ (subsystem per BUG-04-061 entry)

  • Locate the mono-instance resolution call in function_compiler (per §04 recon). Identify why Option<[int]>.unwrap lookup fails today.
  • Cross-section coordination with §03 (parallelizable per Section Dependency Graph at 00-overview.md): the dispatch resolution in function_compiler consumes whatever impl_sig_by_name keying scheme §03 lands. Three §04.2-relative cases per codex blind-spot 2026-05-16 §2:
    • Case A — §03 has shipped first: §04 reads §03’s (method_name, receiver_generic_pattern) key shape (per §03.2 cure surface at monomorphize/mod.rs:73-77). If §03’s pattern stores only the generic shell Option<_>, §04 extends discrimination to the full instantiated Option<[int]> for complex args. §04.2 author MUST cite the §03 commit SHA + key-shape in this checkbox before authoring the unification step.
    • Case B — §04 has shipped first: §04 lands its dedup-predicate cure (§04.1) at the MonoInstance emission/dedup layer in ori_types::check::mod.rs:341-407 — upstream of monomorphize/mod.rs:73-77. §03 later adapts its impl_sig_by_name lookup-chain extension to consume the post-§04 MonoInstance shape. No conflict — §04 owns the upstream emission, §03 owns the downstream dispatch.
    • Case C — landing simultaneously: §04 and §03 authors coordinate at the §04.2 / §03.2 close-out gate to verify the dispatch table is unified (one key shape, both sections’ invariants enforced). The umbrella owner (cluster session) MUST surface this synchronization point at the first §03 or §04 commit and verify at the second.
  • (Replaces the prior unification checkbox.) After classifying Case A/B/C above, author the dispatch wiring inline — §04 keeps the full Receiver type’s interned Idx as the discriminator field (per §04.1 impl_args carrying full substitution). §03’s (method_name, receiver_generic_pattern) key uses this same field; §03 and §04 thus operate on a shared discriminator, eliminating the original “separate dispatch table” risk.
  • Subsection close-out (04.2) — MANDATORY before §04.3:
    • Single-test repro: write a one-off test under compiler/ori_llvm/tests/aot/option_complex_arg.rs calling Option<[int]>.unwrap(); passes.
    • No regression: existing cargo test --release -p ori_llvm --test aot generics green.
    • Run /improve-tooling retrospectively on §04.2.
    • Run compiler_repo/diagnostics/repo-hygiene.sh --check.

04.3 Matrix tests — nested generic receivers

File(s): compiler_repo/compiler/ori_llvm/tests/aot/option_complex_arg.rs (new file)

Matrix:

Receiver shapeMethodTest name
Option<int>.unwrap()test_option_int_unwrap (regression guard — existing-behavior pin)
Option<[int]>.unwrap()test_option_list_int_unwrap
Option<[[int]]>.unwrap()test_option_nested_list_unwrap
Option<{str:int}>.unwrap()test_option_map_unwrap
Option<Box<int>>.unwrap()test_option_box_int_unwrap
Option<[int]>.map(...)test_option_list_map
Option<[int]>.and_then(...)test_option_list_and_then
Result<[int], str>.unwrap()test_result_list_int_unwrap
Result<int, [str]>.unwrap_err()test_result_complex_err_unwrap_err
  • Author all 9 matrix tests.
  • Negative pin: test_option_unsubstituted_var_emits_typeck_errorOption<T> where T not substituted at call site → clean E2xxx, not E5001.
  • Subsection close-out (04.3)status: complete:
    • All 9 matrix tests + 1 negative pin pass.
    • timeout 150 diagnostics/dual-exec-verify.sh tests/aot/option_complex_arg.rs — interpreter/LLVM parity holds.
    • Run /improve-tooling retrospectively on §04.3.
    • Run compiler_repo/diagnostics/repo-hygiene.sh --check.

04.R Third Party Review Findings

Populated by /tpr-review at §04.N.


04.N Completion Checklist

  • All 04.1, 04.2, 04.3 subsections status: complete.
  • /tpr-review clean across reviewer set.
  • /impl-hygiene-review clean after TPR.
  • python -m scripts.plan_corpus check plans/aot-mono-completeness/section-04-complex-generic-arg-mono.md exit 0.
  • cargo st green for tests/spec/options/ + tests/spec/generics/ corpus (Option<[int]>, Option<[[int]]>, Option<{str:int}>) — the dedup predicate §04 hardens is consumed by both JIT and AOT; per overview Mission Success Criteria cargo st regression-guard row + section frontmatter success_criteria row 4.
  • BUG-04-061 tracker entry annotated <!-- delivered-by: plans/aot-mono-completeness/section-04-complex-generic-arg-mono.md -->.
  • Section frontmatter flipped to status: complete, reviewed: true.