Intelligence Reconnaissance
Queries run 2026-04-23 (Phase 2 research):
scripts/intel-query.sh --human file-symbols "registry/traits" --repo ori— inventoryTraitRegistrysurface. Result:lookup_method+lookup_method_checkedare the single entry points for trait-method lookup;impls_by_type: FxHashMap<Idx, Vec<ImplEntry>>is the keying structure.scripts/intel-query.sh --human callers "lookup_method_checked" --repo ori—infer/expr/calls/impl_lookup.rs:35is the sole caller from inference paths.scripts/intel-query.sh --human callers "lookup_method" --repo ori—infer/expr/operators.rs:708,759+registry/methods/mod.rs:36(thin wrapperlookup_trait_method).scripts/intel-query.sh --human similar "bound_chain_dispatch" --repo rust,swift --limit 5— Rust’sassemble_inherent_candidates_from_paramatprobe.rs:958scansself.param_env.caller_bounds()forClauseKind::Traitpredicates.scripts/intel-query.sh --human file-symbols "FunctionSig" --repo ori—FunctionSig.type_params: Vec<Name>,FunctionSig.type_param_bounds: Vec<Vec<Name>>,FunctionSig.scheme_var_ids: Vec<u32>— parallel arrays. Bounds are stored HERE, not inTraitRegistry.
Results summary (≤500 chars) [ori]: registry/traits/mod.rs is 765 lines — split prerequisite. method_call.rs is 524 lines — also split. lookup_method_checked keys on receiver Idx; RigidVar Idx is never registered as an impl’s self_type, so dispatch misses. Bounds live on FunctionSig.type_param_bounds parallel to type_params / scheme_var_ids. §10.1’s bound-chain walk consumes FunctionSig + TraitRegistry jointly — retrieve current function’s sig via engine.signatures(), scan type_param_bounds[idx_of_rigid_var] for trait names, call TraitRegistry::get_trait_by_name for each, check that trait’s methods for method_name. Capability handlers at infer_with_capability bind provider type in env without trait-shape validation — §10.2 extends to surface registered trait methods of the capability.
Section 10: Dispatch-on-Rigid-Receiver Gaps
Goal: Close method-dispatch-on-rigid-receiver gaps that block tests/spec/declarations/traits.ori (§10.1) and tests/spec/capabilities/propagation.ori (§10.2). Prerequisite §10.0 splits over-500-line files to satisfy impl-hygiene.md §File Organization before §10.1/§10.2 edit them.
Depends on: §03 (bodies-pass + validator), §04 (codegen assertions), §09 (especially §09.2 def-impl Self — same impl_self_type infrastructure; landing §09.2 first ensures §10.1 RigidVar dispatch doesn’t interact with un-scoped Self fabrication).
Sequencing rule: §10.0 MUST complete before §10.1 or §10.2 touch their target files. §10.1 before §10.2 (Codex 2.6B: capability dispatch wires through the same lookup policy as bound-chain dispatch; §10.1 establishes the policy).
10.0 Prerequisite file splits
Goal: Reduce compiler_repo/compiler/ori_types/src/registry/traits/mod.rs from 765 lines to ≤500 lines AND compiler_repo/compiler/ori_types/src/infer/expr/calls/method_call.rs from 524 to ≤400 lines. Extract cohesive submodules; keep mod.rs as a dispatch hub. Mechanical split — zero semantic change.
10.0.1 Discovery
- Run
wc -l compiler_repo/compiler/ori_types/src/registry/traits/mod.rs— verify 765 lines baseline. - Run
wc -l compiler_repo/compiler/ori_types/src/infer/expr/calls/method_call.rs— verify 524 lines baseline. - Re-read both files end-to-end to identify cohesive extraction boundaries:
registry/traits/mod.rs: publicTraitRegistrystruct + inherent methods; separatelookup_method*paths (lookup) fromregister_impl*+register_trait*paths (registration). Candidate split:registry/traits/lookup.rs(lookup paths) +registry/traits/registration.rs(registration paths) +registry/traits/mod.rs(struct definition + dispatch hub).method_call.rs:infer_method_call+infer_method_call_namedare the public entry points;resolve_receiver_and_builtin,check_positional_args,unify_higher_order_constraints,unify_closure_param_with_iterator_elem,check_range_float_iteration,check_infinite_iterator_consumed,find_infinite_sourceare private helpers. Candidate split:method_call/receiver_dispatch.rs(receiver/builtin resolution + closure-param unification) +method_call/mod.rs(public entry points).
10.0.2 Design
Fix shape (mechanical):
- Create new files with extracted content:
registry/traits/lookup.rs—impl TraitRegistry { pub fn lookup_method(...) { ... } pub fn lookup_method_checked(...) { ... } pub fn impls_for_type(...) { ... } }+ helper private functions.registry/traits/registration.rs—impl TraitRegistry { pub fn register_impl(...) { ... } pub fn register_trait(...) { ... } }+ helper private functions (coherence checks, specificity, conflicting-defaults etc.).registry/traits/mod.rs— struct definition +mod lookup; mod registration;+ re-exports.method_call/receiver_dispatch.rs—resolve_receiver_and_builtin,unify_higher_order_constraints,unify_closure_param_with_iterator_elem,check_range_float_iteration,check_infinite_iterator_consumed,find_infinite_source. Keep thempub(crate)somethod_call/mod.rscan call them.method_call/mod.rs—infer_method_call+infer_method_call_named+check_positional_args.
- Update
usestatements in dependents (none should need changes if re-exports are preserved).
No semantic change: the split is git mv-like at function granularity. Existing behavior preserved; all existing tests pass unchanged.
10.0.3 Implementation
- Create
registry/traits/lookup.rswith extracted content. - Create
registry/traits/registration.rswith extracted content. - Trim
registry/traits/mod.rsto struct + module declarations + re-exports. Verify ≤300 lines. - Create
method_call/receiver_dispatch.rswith extracted content. - Trim
method_call/mod.rs(or rename it tomethod_call.rs, TBD by existing module convention). Verify ≤400 lines. - Run
cargo build— compiles clean. - Run
cargo test -p ori_types— all existing tests pass unchanged. - Run
cargo clippy -p ori_types— clean. - Commit the split as ONE atomic commit (per
compiler.md §Multi-commit sequences). - Post-split line counts: each file ≤500 lines.
10.0.4 Close §10.0
- All §10.0.3 checkboxes marked
[x]. -
cargo t+cargo clippy+cargo fmtall green post-split. -
/tpr-reviewon §10.0 diff → clean (mechanical split should be low-finding). -
/impl-hygiene-reviewon §10.0 diff → BLOAT findings for the two files cleared. - Frontmatter
10.0 status: complete.
10.1 Generic-param method dispatch via bound-chain walk
Goal: Extend TraitRegistry::lookup_method_checked to consult FunctionSig.type_param_bounds when receiver is Tag::RigidVar (generic type parameter). The current behavior keys impls_by_type by concrete Idx, so RigidVar receivers always miss. @f<T: Clone>(val: T) -> str = val.clone() fails E2003 method-not-found despite the declared bound.
Guards (both reviewers 2.6B): visited-set keyed on (rigid_var_idx, trait_idx) to prevent infinite loops on cyclic bounds A: B, B: C, C: A; recursion depth limit 256 per impl-hygiene.md §Panic & Assertion.
Priority (Rust + Swift consensus): bound-chain candidates are inherent-priority — they win over extension-method lookup when receiver is a rigid var. This matches Rust’s WhereClauseCandidate in probe.rs:958.
10.1.1 Discovery + root cause verification
- Re-read
registry/traits/lookup.rs(after §10.0 split) — confirmlookup_method_checkedreturnsNotFoundwhenimpls_by_type.get(rigid_var_idx)is empty. - Re-read
infer/expr/calls/method_call.rs(post-§10.0) +impl_lookup.rs— confirm dispatch path:infer_method_call→resolve_receiver_and_builtin(forTag::RigidVar, falls through toContinue { resolved }) →lookup_impl_method→TraitRegistry::lookup_method_checked(rigid_var_idx, method_name)→NotFound. - Re-read
output/mod.rs:373(FunctionSigstruct) — confirmtype_params,type_param_bounds,scheme_var_idsare parallel Vec<…> with the same length. - Confirm engine access:
InferEngine::signatures()returnsOption<&FxHashMap<Name, FunctionSig>>. Acurrent_function_sig()accessor may or may not exist — verify. - Write TDD matrix BEFORE implementation:
- Positive
test_method_dispatch_on_rigid_var_with_single_bound—@f<T: Clone>(val: T) -> T = val.clone()compiles clean;val.clone()resolves toClone::clone(val). - Positive
test_method_dispatch_on_rigid_var_with_multiple_bounds_different_methods—@f<T: Clone + Debug>(val: T)withval.clone()andval.debug()both resolve. - Negative
test_method_dispatch_on_rigid_var_without_bound_reports_missing—@f<T>(val: T) -> T = val.clone()reports E2003 (or equivalent) with suggestion “addT: Clonebound”. - Negative
test_method_dispatch_on_rigid_var_ambiguous_bounds_reports_ambiguity—@f<T: Foo + Bar>(val: T)where bothFooandBarhavemethod()reports E2023 ambiguous method. - Cyclic guard
test_method_dispatch_cyclic_bounds_does_not_infinite_loop— construct cyclic-bound scenario (if possible within Ori’s surface syntax; else test via direct TraitRegistry fixture) and verify visited-set prevents loop. Test MUST have a bounded timeout (timeout: 5000ms or similar in the harness). - Depth guard
test_method_dispatch_deep_supertrait_chain_respects_depth_limit— construct supertrait chain of ≥256 levels (via fixture), verify error instead of stack overflow.
- Positive
10.1.2 Design
Fix shape:
- In
TraitRegistry(orlookup.rspost-§10.0), add a helperfind_method_via_bound_chain(rigid_var_idx, method_name, signatures, current_fn_sig) -> Option<MethodLookup>:- Retrieve
current_fn_sig.scheme_var_ids.iter().position(|&id| id == pool.data(rigid_var_idx))to find the bound index. - For each trait name in
current_fn_sig.type_param_bounds[bound_idx]:- Call
self.get_trait_by_name(trait_name)→Option<&TraitEntry>. - Check
trait_entry.collected_methodsformethod_name(covers supertrait-inherited methods). - If found: record as
BoundCandidate(trait_idx, method_item).
- Call
- Deduplicate candidates. If 0: return
None. If 1: returnSome(MethodLookup::Trait { trait_idx, impl_idx: /* synthetic */, method }). If 2+: return withAmbiguous { candidates }. - Guard with visited-set keyed on
(rigid_var_idx, trait_idx)passed through the recursion. Max recursion depth 256.
- Retrieve
- In
lookup_method_checked, whenreceiver_idx’s tag isTag::RigidVar, callfind_method_via_bound_chainBEFORE returningNotFound. Priority: bound-chain candidates are inherent-priority (Rust + Swift consensus) — they win over extension-method lookup in the resolved ordering. - In
infer/expr/calls/method_call.rs(orreceiver_dispatch.rspost-§10.0), whenresolve_receiver_and_builtinencountersTag::RigidVarreceiver, fall through tolookup_impl_method(unchanged); the new bound-chain walk runs insidelookup_method_checkedand returns the right method.
Operator dispatch overlap: §10.1’s fix inside lookup_method_checked automatically extends to resolve_binary_op_via_trait at operators.rs:708 and resolve_unary_op_via_trait at operators.rs:759, both of which call lookup_method. No separate operator-dispatch subsection needed. Add one matrix cell to verify val + other where val: T, T: Add works.
10.1.3 Implementation
- Write failing tests FIRST.
- Add
find_method_via_bound_chainhelper inregistry/traits/lookup.rs. - Wire it into
lookup_method_checkedforTag::RigidVarreceivers. - Add visited-set + depth-256 guards.
- Run unit tests — all pass including cyclic-bounds + deep-chain guards.
- Run
timeout 150 cargo stf tests/spec/declarations/traits.ori— green (previously 3 E2005 sites). - Verify operator dispatch overlap: test
@f<T: Add>(val: T, other: T) -> T = val + otherworks. - Matrix: receiver × bound × method:
- Receivers:
Tag::RigidVarfrom@f<T>,Tag::RigidVarfromimpl<T: Bound> Type<T>,Tag::SelfTypein trait default method. - Bounds: single bound, multi-bound (A + B), supertrait chain (A: B: C), bound on trait method’s generic param.
- Methods: trait-required method, trait-default method, supertrait-inherited method, operator (
+,-,==,<).
- Receivers:
- Verify
cargo st tests/green, debug + release parity.
10.1.4 Close §10.1
- All §10.1.3 checkboxes marked
[x]. -
/tpr-reviewon §10.1 diff → clean. -
/impl-hygiene-reviewon §10.1 diff → clean. -
/improve-toolingretrospective (cyclic-guard pattern may generalize to other compiler recursion paths). -
/sync-clauderetrospective — updatetypeck.md §TR-4bound-satisfaction discussion with bound-chain walk specifics. - Frontmatter
10.1 status: complete.
10.2 Capability-method dispatch — trait-method surface for bound handler value
Goal: Extend infer_with_capability at constructors.rs:99-122 to surface the capability trait’s methods for dispatch on the bound handler value. When body calls Http.get(url: "..."), the Http identifier resolves to the handler’s type, and method lookup must find get via the capability trait’s method set (not only via the handler type’s own impls).
Composition with §10.1: §10.1’s bound-chain walk generalizes — §10.2 uses the same TraitRegistry::lookup_method_checked extension plus a capability-specific surface that registers the capability trait’s methods as candidates when the receiver is a capability-bound name.
10.2.1 Discovery + root cause verification
- Re-read
constructors.rs:99-122(infer_with_capability) — confirm it bindscapability → provider_tyin env (line 113) and marks capability provided (line 117-118) but does NOT validate provider’s trait conformance. - Trace
Http.get(url: "...")path:- Parser emits
MethodCall { receiver: Ident("Http"), method: "get", ... }. infer_method_call→infer_ident(receiver)resolvesHttp→provider_ty(the handler’s type).resolve_receiver_and_builtin(provider_ty, "get")→ no builtin match.lookup_impl_method(provider_ty, "get")→TraitRegistry::lookup_method_checked(provider_ty, "get")→ NotFound if handler has no registered impl forget.
- Parser emits
- Confirm whether built-in capability traits (
Http,Logger,Env, etc.) are pre-registered as trait entries inTraitRegistryviaregister_builtin_typesorregister_traitspasses. - Write TDD matrix BEFORE implementation:
- Positive
test_capability_method_dispatch_via_handler_impl—with Http = RealHttp in { Http.get(url: "foo") }resolves viaRealHttp’s registeredimpl Http. - Positive
test_capability_method_dispatch_via_capability_trait_surface— handler provides the right method-shape even without a formalimpl Httpdeclaration (per the stateful-handler-handler formwith Cap = handler(state: S) { method: ... } in ...). - Negative
test_capability_method_missing_on_handler_reports_error— handler doesn’t provideget→ clean error message pointing at the missing trait method, NOT a confusing generic lookup failure.
- Positive
10.2.2 Design
Fix shape:
- At
infer_with_capability, when thecapabilityname resolves to a registered trait (viaTraitRegistry::get_trait_by_name(capability)), wire the bound identifier in scope to also surface that trait’s method set. This may be done via a newCapabilityBinding { trait_idx, provider_ty }TypeEnv entry type, or via aTraitRegistry::lookup_method_checkedextension that checks “is this type currently bound as a capability handler? If yes, try the capability trait’s methods first.” - For method lookup on a capability-bound identifier: try capability-trait method set (from
get_trait_by_name(capability_name).collected_methods) with the handler’s provider_ty as Self; fall back to regular dispatch on provider_ty if not found. - Trait-shape validation (optional for §10.2 core, filed-if-not-done): verify the handler’s type implements the required capability trait methods. If missing, report clean error at the
with ... = handlersite.
10.2.3 Implementation
- Write failing tests FIRST.
- Extend
infer_with_capabilityto register capability-trait-method surface. - Extend method lookup path to consult capability-trait methods before falling through to
NotFound. - Run unit tests — all pass.
- Run
timeout 150 cargo stf tests/spec/capabilities/propagation.ori— green (previously 4[CAPABILITY-METHOD-DISPATCH]sites). - Matrix: capability × handler-shape × method:
- Capabilities:
Http,Logger,FileSystem, user-definedcapability Foo { ... }. - Handler shapes: concrete struct with
impl Http, stateful handlerwith Cap = handler(state: S) { op: (s, ...) -> (s', val) } in ..., default impl. - Methods: required methods, default methods, cross-trait method calls.
- Capabilities:
- Verify
cargo st tests/green, debug + release parity.
10.2.4 Close §10.2
- All §10.2.3 checkboxes marked
[x]. -
/tpr-reviewon §10.2 diff → clean. -
/impl-hygiene-reviewon §10.2 diff → clean. -
/improve-toolingretrospective. -
/sync-clauderetrospective — updatetypeck.md §CP-2/CP-3with capability-method-dispatch specifics. - Frontmatter
10.2 status: complete.
10.R Third Party Review Findings
- None.
10.N Completion Checklist
- 10.0 complete — file splits landed;
registry/traits/*+method_call/*all ≤500 lines; all existing tests pass unchanged. - 10.1 complete — bound-chain dispatch on Tag::RigidVar; cyclic + depth guards;
traits.origreen; operator dispatch overlap verified. - 10.2 complete — capability-method dispatch;
propagation.origreen. - §10 aggregate
/tpr-reviewon full §10 diff → clean. - §10 aggregate
/impl-hygiene-review→ clean. -
/improve-toolingsection-close sweep — cyclic-guard pattern generalization. -
/sync-claudesection-close doc sync —typeck.md §TR-4+ §CP-2/CP-3 updates. - Plan sync — §10 frontmatter
status: complete; §00-overview Quick Reference updates; §index.md section 10 status updated.
Exit criteria: All 3 subsections complete with TPR + hygiene clean; §10-touched test files green (traits.ori, propagation.ori); dual-exec parity preserved. §11 may begin.