Section 21A: LLVM Backend
Current Test Results
| Test Suite | Passed | Failed | Skipped/Ignored | Total |
|---|---|---|---|---|
| Ori spec (evaluator) | 4409+ | 0 | 154 | 4563+ |
| Rust unit tests (ori_llvm lib) | 501+ | 0 | 0 | 501+ |
| AOT integration tests | 2096+ | 0 | 0 | 2096+ |
| ori_rt unit tests | 367+ | 0 | 0 | 367+ |
| Ori spec (LLVM) | 1781+ | 0 | 2475 LCFail | 4256+ |
Known Blocker: BUG-04-030 — 2475 LCFails (high severity)
See plans/bug-tracker/section-04-codegen-llvm.md:198 for full details.
Root causes (6 identified, 3 remaining after JIT EH plan fixes):
- (A) Generalized vars leak to codegen — type checker stores unresolved vars in expr_types. ~279 occurrences. Touches §21.2 (Type Lowering) and §21.7 (Monomorphization).
- (B) Index out of bounds (u32::MAX) in ARC IR — missing block/var ID sentinel. ~50+ files. Touches §21.15 (ARC/Memory Management).
- (C) StructValue vs IntValue type confusion — 4 files. Touches §21.2 (Type Lowering).
(D) Missing JIT runtime functions— fixed in JIT EH plan §06.1.(E) Polymorphic type selection— fixed in JIT EH plan §06.4.(F) List concat calling convention— fixed in JIT EH plan §06.5.
Resolving remaining root causes (A, B, C) would unblock completion of the JIT Exception Handling plan (Sections 04B, 05, 06).
Import Resolution (Unified Pipeline)
Correction callout (2026-04-20): The Import Resolution behavior documented below, plus subsection 21.7 (generic monomorphization) and 21.11 (lambda / closure support), was CORRECTED by
plans/empty-container-typeck-phase-contract/section-08-codegen-poly-lambda.md(resolves BUG-04-042). The “verified 2026-03-29” monomorphization claim below was contradicted by a commit-wall regression whereassert_eq<T>failed to monomorphize in poly-lambda hosts — root cause was cross-module pool-mergevar_idcollision in the JIT test runner’s pool merge (fix landed in §08.3pool/re_intern/) plus scheme-bodyGeneralized→BoundVarcanonicalization (§08.3b / §08.3b.1) plus newtype constructor lowering (§08.3c). Any future §21A resumption MUST consult §08 before modifying generic monomorphization or lambda_mono / poly-lambda paths incompiler/ori_llvm/src/codegen/function_compiler/and the test-runner pool-merge path incompiler/oric/src/test/runner/llvm_backend.rs.
The JIT test runner resolves imports via oric::imports::resolve_imports() and compiles
imported function bodies directly into the JIT module. This uses the same declare_all /
define_all path as main module functions, so most new codegen features automatically
work for imported functions too.
Features that need import-aware changes
When implementing these features, ensure they also work across module boundaries:
-
Generic monomorphization: IMPLEMENTED. 33 generics tests pass including cross-module
assert_eqinstantiation. -
Impl blocks from imported modules: IMPLEMENTED. Imported modules’ impl blocks are compiled via
compile_impls(). -
Type declarations from imported modules: IMPLEMENTED.
register_user_types()processes imported modules’ type declarations. -
Prelude functions: IMPLEMENTED. Sum type codegen works; prelude compilation re-enabled.
21.1 LLVM Setup & Infrastructure
-
Setup: LLVM development environment
- Docker container with LLVM 21 and development headers
- Add
inkwellcrate tocompiler/ori_llvm/Cargo.toml - Verify LLVM bindings compile and link correctly
- Create
compiler/ori_llvm/src/module structure
-
Implement: LLVM context and module initialization
- Rust Tests:
context.rs— SimpleCx, CodegenCx, TypeCache - Create LLVM context, module, and builder abstractions
- Rust Tests:
-
Implement: Basic target configuration
- Support native target detection (JIT)
- Configure data layout and target features (AOT)
21.2 Type Lowering
-
Implement: Primitive type mapping
- Rust Tests:
types.rs,context.rs— type mapping - Map Ori primitives (int → i64, float → f64, bool → i1, char → i32, byte → i8)
- Map strings to
{ i64 len, ptr data }struct - Handle function types
- Rust Tests:
-
Implement: Option/Result types
- Map Option/Result to
{ i8 tag, i64 payload }tagged unions - Tag values: None=0, Some=1; Err=0, Ok=1
- Proper payload handling for non-primitive types
- Map Option/Result to
-
Implement: Collection type representations in
ori_llvm/src/codegen/— list/map/set LLVM struct layouts- Map lists to
{ i64 len, i64 cap, ptr data }struct - Map maps to appropriate hash table representation
- Map sets to appropriate hash set representation
- Map lists to
-
Implement: Duration & Size types
- Map Duration to i64 (nanoseconds)
- Map Size to i64 (bytes)
- Duration arithmetic operations (add, sub, mul, div, mod)
- Size arithmetic operations (add, sub, mul, div, mod)
- Size cross-unit normalization —
512kb + 512kb == 1mbequality fails in AOT (test_op_size_arithmetic) - Mixed-type arithmetic (Duration * int, int * Duration, Duration / Duration → int)
- Size unary negation compile error
- Overflow panic semantics for Duration
- Division by zero panics
- Duration methods:
.nanoseconds(),.microseconds(),.milliseconds(),.seconds(),.minutes(),.hours() - Size methods:
.bytes(),.kilobytes(),.megabytes(),.gigabytes(),.terabytes() - Factory functions:
Duration.from_nanoseconds(ns:),Size.from_bytes(b:)
-
Implement: Newtype codegen in
ori_llvm/src/codegen/— transparent wrapper representation- Newtype type representation (same as wrapped type)
- Constructor codegen:
TypeName(value) .innerfield access- Proper type distinction for trait dispatch
-
Implement: Sum type codegen (beyond Option/Result)
- User-defined sum type representation (tagged union)
- Variant constructor codegen
- Tag-based dispatch in match
- Multi-field variant payloads
- Import note: Once sum types work, re-enable prelude function compilation in
JIT mode (
runner.rs). Currently skipped becausecompare() -> Orderingfails.
-
Implement: Fixed-capacity lists
[T, max N]- Inline allocation strategy
- Compile-time capacity tracking
.capacity(),.is_full(),.remaining()methods.push()with panic on full.try_push()→bool.push_or_drop(),.push_or_oldest().to_dynamic()conversion.to_fixed<$N>()and.try_to_fixed<$N>()
-
Implement: Channel type codegen —
Producer<T>/Consumer<T>LLVM representations and runtime callsProducer<T>andConsumer<T>type representationCloneableProducer<T>andCloneableConsumer<T>Sendabletrait constraint checking- Channel buffer management
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.2) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.2 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.2: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.3 Expression Codegen
-
Implement: Core expression codegen — literals, binary/unary ops, calls, field access in
ori_llvm/src/codegen/- Rust Tests:
tests/arithmetic_tests.rs,tests/operator_tests.rs - Literals (int, float, bool, string, char, byte)
- Binary ops (add, sub, mul, div, mod, comparisons, logical)
- Unary ops (neg, not)
- Function calls and method dispatch
- Field access and basic indexing
- Rust Tests:
-
Implement: Range expressions with step
start..end by stepcodegenstart..=end by stepinclusive ranges- Negative step support (descending:
10..0 by -1) - Infinite ranges:
0..,0.. by step - Zero-step panic
- Empty range detection (mismatched direction)
-
Implement: Spread operator
...- List spread:
[...a, x, ...b] - Map spread:
{...a, key: v, ...b} - Struct spread:
Point { ...orig, x: 10 } - Later-wins merge semantics
- List spread:
-
Implement: Coalesce operator
??option ?? defaultcodegenresult ?? defaultcodegen- Short-circuit evaluation
- Type inference for coalesce chains
-
Implement: Floor division operator
div- Integer floor division codegen
- Distinct from
/(truncating division)
-
Implement: Bitwise operator codegen —
~/&/|/^/<</>>for int and byte types~(BitNot) codegen&,|,^for int and byte types<<,>>shift operators- Shift overflow panics (count < 0 or count >= bit width)
-
Implement: Type conversion codegen —
as/as?/Intotrait dispatch in LLVM IRexpr as Typeinfallible conversion codegenexpr as? Typefallible conversion →Option<T>- Standard conversions: int→float, str→Error, Set
→[T] - Into trait method dispatch
-
Implement: Assignment to complex targets
- Field assignment:
point.x = 10 - Index assignment:
list[0] = value - Nested assignments:
a.b.c = value
- Field assignment:
-
Implement: String operation codegen — indexing, interpolation, escapes, methods via
ori_rtcalls- String indexing with Unicode handling (
str[i]→ single-codepointstr) - String interpolation:
`Hello {name}` - All escape sequences:
\n,\t,\r,\0,\\,\" str.concat()return type tracking — FIXED (test_str_concat_basicpasses)str.to_str()identity return type tracking — FIXED (test_str_to_str_identitypasses)- String ordering (
<,>,<=,>=) — FIXED (test_str_compare_lesspasses) - String methods in builtin table:
contains,starts_with,ends_with,trim,to_uppercase,to_lowercase,replace,split,repeat,chars— FIXED (tests pass) - Struct update (
...spread) with string fields — FIXED (test_struct_update_with_stringpasses)
- String indexing with Unicode handling (
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.3) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.3 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.3: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.4 Operator Trait Dispatch
-
Implement: User-defined impl blocks and associated functions
- Register user-defined struct types with LLVM
- Support user-defined
impl Type { ... }blocks - Generate method dispatch for user-defined methods
- Support associated functions (methods without
selfparameter) - Enable
Type.method()syntax for user-defined types - Import note: Compile imported modules’ impl blocks via
compile_impls() - Import note:
register_user_types()processes imported modules’ type declarations - Tests:
tests/spec/types/associated_functions.ori(9 tests passing)
-
Implement: User-defined operator dispatch
- Rust Tests:
tests/operator_trait_tests.rs - Detect when operand is a user-defined type (struct)
- Generate method calls to trait methods instead of direct LLVM ops
- Arithmetic operators →
.add(),.subtract(),.multiply(),.divide(),.floor_divide(),.remainder() - Unary operators →
.negate(),.not(),.bit_not() - Bitwise operators →
.bit_and(),.bit_or(),.bit_xor(),.shift_left(),.shift_right() - Comparison operators →
.equals(),.compare() - Tuple
==equality — FIXED (test_tuple_equality,test_tuple_equality_triplepass) - Handle generic operator traits with type parameters (e.g.,
Mul<int>) - Files:
ori_llvm/src/operators.rs— trait dispatch logic - Tests:
tests/spec/traits/operators/user_defined.ori(currently skipped)
- Rust Tests:
-
Implement: Overflow and panic semantics
- Integer overflow detection and panic
- Division by zero panic for integers
- Shift count validation (negative or >= bit width → panic)
- Float special cases: Inf, NaN handling
- NaN comparison semantics (NaN > all values)
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.4) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.4 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.4: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.5 Control Flow
-
Implement: Basic control flow
- Rust Tests:
tests/control_flow_tests.rs,tests/advanced_control_flow_tests.rs - Basic block creation and linking
- Phi nodes for SSA form
- Branch and conditional instructions
- Basic break/continue in loops
- Rust Tests:
-
Implement: Labeled loops
loop:namesyntax supportfor:namesyntax supportbreak:nametargeting specific loopcontinue:nametargeting specific loopcontinue:name valuein yield context- No label shadowing enforcement
-
Implement: Break with values
break valuecodegen- Phi node setup in loop exit block
- Type resolution for loop expressions with break values
break:name valuefor labeled loops
-
Implement: For-yield expressions
for x in items yield expr→ list collectionfor x in items if guard yield exprwith filtering- Nested for-yield:
for x in xs for y in ys yield (x, y) continue valuesubstitution in yieldbreak valuefinal element addition{K: V}collection from(K, V)tuples- Bool comparison stored in struct field during for-yield — FIXED (
test_depth_combined_struct_iter_matchpasses) - Mutation of outer variables inside match arms within for-do body — FIXED (
test_depth_combined_match_closure_resultpasses)
-
Implement: Try expression and error propagation
?operator on Result: unwrap or early return?operator on Option: unwrap or early return None- Proper error propagation up call stack
- Result accumulation in try blocks
-
Implement: Catch pattern
catch(expr:)→Result<T, str>codegen- Panic recovery mechanism
- Error message capturing
- BUG:
catch()type inference returnsResult<() -> T, str>instead ofResult<T, str>— blocks 12 AOT tests (type checker bug, not LLVM) - BUG: Inline panic in
catch—invokeonly intercepts callee-function panics, not same-function inline code (e.g.,1 / 0) — blocks 1 AOT test
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.5) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.5 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.5: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.6 Pattern Matching
-
Implement: Basic patterns
- Literal patterns
- Binding patterns
- Wildcard patterns
_ - Basic struct destructuring
- Basic tuple destructuring
-
Implement: Advanced patterns
- Range patterns:
1..10,'a'..'z' - Or-patterns:
A | B | C - At-patterns:
x @ Some(_) - Guard patterns:
x if x > 0 - Struct destructuring with field renaming:
{ x: px, y: py } - List patterns with rest:
[first, ..rest],[..init, last] - Nested patterns
- Range patterns:
-
Implement: Match expression improvements
- Exhaustiveness verification in codegen
- Never variant handling
- Pattern matrix optimization
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.6) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.6 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.6: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.7 Function Sequences & Expressions
-
Implement: Generic function monomorphization
- Collect monomorphization sites (call sites with concrete type args)
- Clone generic function bodies with type substitution
- Re-type-check monomorphized bodies to get concrete expr_types
- Compile specialized instances through normal declare/define path
- Import: collect call sites from calling module and generate specialized versions of imported generic functions (e.g.,
assert_eq<int>) - Implementation plan: Monomorphization (4 sections: type checker, ARC lowering, LLVM pipeline, verification)
- Architecture document:
docs/ori_lang/v2026/design/monomorphization-architecture.md
-
Implement: Basic function codegen
- Rust Tests:
tests/function_tests.rs,tests/function_call_tests.rs - Function signatures and calling conventions
- Local variables
- Return statements
- Rust Tests:
-
Implement: Block expressions and control flow (
{ },try,match){ let x = a \n result }sequential binding via block expressionspre(cond) post(r -> cond)function-level contract declarationstry { let x = f()? \n Ok(x) }error propagationmatch v { P -> e, _ -> d }pattern matching
-
Fix: Block scope variable isolation
- Inner block
let xleaks to outer scope — FIXED (test_scope_shadow_in_nested_blockpasses) let xin for-do body overwrites outerx(test_scope_for_loop_shadow) — no test exists to verify
- Inner block
-
Implement: Recurse pattern
recurse(condition:, base:, step:)basic recursionmemo:memoization supportparallel:parallel recursion flag- Proper state threading
-
Implement: With pattern (RAII)
with(acquire:, use:, release:)codegen- Guaranteed release even on panic
- Resource binding in
use:block - Note: Evaluator has a loud stub in
can_eval.rs— replace stub with real impl when ready
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.7) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.7 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.7: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.8 Concurrency Patterns
Related Proposals:
proposals/approved/parallel-execution-guarantees-proposal.mdproposals/approved/timeout-spawn-patterns-proposal.mdproposals/approved/nursery-cancellation-proposal.mdproposals/approved/sendable-channels-proposal.mdproposals/approved/cache-pattern-proposal.mdproposals/approved/task-async-context-proposal.md
-
Implement: Parallel pattern
parallel(tasks:, max_concurrent:, timeout:)→[Result]- Task spawning using OS threads or async runtime
- Result collection preserving task order
- Timeout handling with cancellation propagation
uses Suspendcapability requirementSendablebound on task return types- Rust Tests:
ori_llvm/src/concurrency/parallel_tests.rs - Evaluator: Replace loud stub in
can_eval.rs:eval_can_function_expwith real parallel eval
-
Implement: Spawn pattern
spawn(tasks:, max_concurrent:)→void- Fire-and-forget semantics (errors logged, not propagated)
- Background execution with structured lifetime
- Tasks must complete before parent scope exits
- Rust Tests:
ori_llvm/src/concurrency/spawn_tests.rs - Evaluator: Replace loud stub in
can_eval.rs:eval_can_function_expwith real spawn eval
-
Implement: Timeout pattern
timeout(op:, after:)→Result<T, TimeoutError>- Operation cancellation on timeout via
is_cancelled()checks - Cleanup: resources released, destructors run
- Cooperative cancellation model (no preemption)
- Rust Tests:
ori_llvm/src/concurrency/timeout_tests.rs - Evaluator: Replace loud stub in
can_eval.rs:eval_can_function_expwith real timeout eval
-
Implement: Cache pattern
cache(key:, op:, ttl:)codegen- Cache key hashing via
Hashabletrait - TTL management with Duration type
- Thread-safe cache access
uses Cachecapability requirement- Rust Tests:
ori_llvm/src/concurrency/cache_tests.rs - Evaluator: Replace loud stub in
can_eval.rs:eval_can_function_expwith real cache eval
-
Implement: Nursery pattern
nursery(body:, on_error:, timeout:)codegenNurseryErrorMode.CancelRemaining: cancel siblings on first failureNurseryErrorMode.CollectAll: run all, collect all errorsNurseryErrorMode.FailFast: return first error immediately- Structured concurrency: all children complete before nursery returns
- Cancellation propagation via
CancellationError - Rust Tests:
ori_llvm/src/concurrency/nursery_tests.rs
-
Implement: Channel operations
channel<T>(buffer:)→(Producer, Consumer)creationT: Sendablebound enforced at compile timechannel_in,channel_out,channel_allselection patterns- Blocking send/receive operations
- Bounded buffer with backpressure
CloneableProducer<T>,CloneableConsumer<T>variants- Rust Tests:
ori_llvm/src/concurrency/channel_tests.rs
-
Implement: Sendable trait enforcement
- Check
Sendablebound for all cross-task data - Compile error for non-Sendable types in parallel contexts
- Interior mutability rules per
sendable-interior-mutability-proposal.md
- Check
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.8) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.8 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.8: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.9 Capabilities & With Pattern
Related Proposals:
proposals/approved/capability-composition-proposal.mdproposals/approved/with-pattern-proposal.mdproposals/approved/default-impl-proposal.mdproposals/approved/default-impl-resolution-proposal.mdproposals/approved/intrinsics-capability-proposal.md
-
Implement: Capability tracking
uses Capabilitydeclaration in function signatures- Capability propagation through call graph
- Compile error if capability not available at call site
- Transitive capability requirements
- Rust Tests:
ori_llvm/src/capabilities/tracking_tests.rs
-
Implement: Capability provision
with Cap = impl in exprcodegen- Multiple capabilities:
with A = a, B = b in expr - Provider vtable generation
- Implicit capability parameter threading
- Scope-based resolution (innermost
withwins) - Rust Tests:
ori_llvm/src/capabilities/provision_tests.rs
-
Implement: Default implementations
def implvtable generation at module level- Resolution order: with scope > imported def impl > local def impl
- Override with explicit
withpattern without defimport to exclude default impl- One def impl per trait per module
- Rust Tests:
ori_llvm/src/capabilities/default_impl_tests.rs
-
Implement: Standard capabilities
Print(default provided, writes to stdout)Http(network requests)FileSystem(file I/O)Clock(time queries)Random(random number generation)Crypto(cryptographic operations)Cache(memoization and caching)Logger(structured logging)Env(environment variables)Intrinsics(SIMD, bit ops per intrinsics-capability-proposal)Suspend(async/concurrency marker)FFI(foreign function interface)- Rust Tests:
ori_llvm/src/capabilities/standard_tests.rs
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.9) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.9 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.9: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.10 Collections & Iterators
Related Proposals:
proposals/approved/iterator-traits-proposal.mdproposals/approved/iterator-performance-semantics-proposal.mdproposals/approved/computed-map-keys-proposal.mdproposals/approved/fixed-capacity-list-proposal.md
-
Implement: List operations
.push(element:)- append to end, grow if needed (test_coll_list_push).pop()→Option<T>- remove and return last element (test_coll_list_pop).first()→Option<T>- return first element (test_coll_list_first).last()→Option<T>- return last element (test_coll_list_last).insert(at:, element:)- insert at index, shift elements.remove(at:)→T- remove at index, shift elements.get(index:)→Option<T>- safe indexed accesslist[index]→T- direct access (panics if out of bounds) (test_coll_list_index)list[# - 1]- length-relative indexing.reverse()- return reversed list (test_coll_list_reverse).contains(element:)→bool(test_coll_list_contains).concat(other:)— FIXED (test_aot_list_concatpasses)- Capacity management: grow by 2x when full
- List iteration:
for x in list do ... - List-of-tuples iteration — FIXED (
test_tuple_in_looppasses) - Rust Tests:
ori_llvm/src/collections/list_tests.rs
-
Implement: Map operations
- Map literal:
{key: value},{"string": value} - Computed keys:
{[expr]: value}where expr is evaluated .get(key:)→Option<V>- lookup by key (test_coll_map_get)map[key]→Option<V>- subscript access.insert(key:, value:)- insert or update (test_coll_map_insert).remove(key:)→Option<V>- remove and return (test_coll_map_remove).is_empty()→bool(test_aot_map_is_empty).contains_key(key:)→bool(test_coll_map_contains_key).keys()→[K]- return list of keys (test_coll_map_keys).values()→[V]- return list of values (test_coll_map_values)- Map iteration: yields
(K, V)tuples - Spread in literals:
{...base, key: value} - Rust Tests:
ori_llvm/src/collections/map_tests.rs
- Map literal:
-
Implement: Set operations [partial]
Set<T>type representation:{i64 len, i64 cap, ptr data}(same as list — sorted flat array, not hash set)- Set creation in AOT:
__collect_setimplemented — intercepts inemit_apply, callsori_iter_collect_setruntime (2026-03-01) .len()→emit_set_length()— extract field 0.is_empty()→emit_set_is_empty()—len == 0.contains(element:)→emit_set_contains()viaori_set_containsruntime.insert(element:)→emit_set_insert()viaori_set_insertruntime (returns new set via sret).remove(element:)→emit_set_remove()viaori_set_removeruntime (returns new set via sret).union(other:)→emit_set_union()viaori_set_unionruntime (sret).intersection(other:)→emit_set_intersection()viaori_set_intersectionruntime (sret).difference(other:)→emit_set_difference()viaori_set_differenceruntime (sret).to_list()→emit_set_to_list()viaori_set_to_listruntime (sret)- Set iteration: yields
Telements (set.iter()codegen) - Runtime functions: 7 functions in
ori_rt/src/lib.rs+ declarations inruntime_decl/mod.rs - AOT Tests:
ori_llvm/tests/aot/sets.rs— 10 tests all passing (2026-03-01)
-
Implement: Iterator trait codegen (partial — 25 iterator tests pass, verified 2026-03-29)
Iteratortrait:type Item; @next (self) -> (Option<Self.Item>, Self)DoubleEndedIteratortrait:@next_back (self) -> (Option<Self.Item>, Self)- Fused iterator semantics:
NonestaysNone .map(transform:)- lazy transformation.filter(predicate:)- lazy filtering.fold(initial:, op:)- eager reduction.collect()into target collection viaCollecttrait.enumerate()- yield(index, item)tuples.zip(other:)- pair with another iterator.chain(other:)- concatenate iterators.take(count:),.skip(count:)- limit iteration.cycle()- repeat infinitely- Copy elision: avoid intermediate allocations
- Rust Tests:
ori_llvm/src/collections/iterator_tests.rs
-
Implement: DoubleEndedIterator methods
.rev()- reverse iteration order.last()- get last element.rfind(predicate:)- find from end.rfold(initial:, op:)- fold from end- Rust Tests:
ori_llvm/src/collections/double_ended_tests.rs
-
Implement: Infinite iterators
repeat(value:)→ infinite iterator yielding value(0..).iter()→ infinite range from 0(0.. by -1).iter()→ infinite descending (requires bound)- Must use
.take(count:)before.collect() - Rust Tests:
ori_llvm/src/collections/infinite_tests.rs
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.10) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.10 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.10: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.11 Lambda & Closure Support
-
Implement: Basic lambdas
- Simple lambda syntax:
x -> x + 1 - Multi-param lambdas:
(a, b) -> a + b - No-param lambdas:
() -> 42
- Simple lambda syntax:
-
Implement: Advanced lambda features
- Typed lambdas:
(x: int) -> int = x * 2 - Proper capture-by-value semantics
- Nested lambdas
- Lambda in lambda captures
- Default parameters in lambdas
- Typed lambdas:
-
Implement: Function references
- Function reference as value
- Higher-order function codegen
- Passing functions to other functions
- Named function → closure coercion — FIXED (
test_hof_apply_identity,test_hof_named_fn_as_argpass)
-
Fix: Closure ABI issues (all fixed, verified 2026-03-29)
(int) -> boolas function parameter — FIXED (test_hof_bool_lambdapasses)- Zero-arg closure capturing 3+ strings — FIXED (
test_depth_closure_capturing_multiple_stringspasses) .map(r -> r.score)closure accessing struct field — FIXED (test_stress_combined_struct_closure_iterationpasses)
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.11) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.11 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.11: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.12 Built-in Functions
-
Implement: Basic built-ins
print(msg:)panic(msg:)→Never- Basic assertions
-
Implement: Comparison built-ins
compare(left:, right:)→Orderingmin(left:, right:)with Comparablemax(left:, right:)with Comparable
-
Implement: Collection built-ins
len(collection:)for all collection typesis_empty(collection:)repeat(value:)→ infinite iteratorhash_combine(seed:, value:)→ int
-
Implement: Developer built-ins
todo()/todo(reason:)→Neverunreachable()/unreachable(reason:)→Neverdbg(value:)/dbg(value:, label:)→Tdrop_early(value:)is_cancelled()→bool
-
Implement: Assertion built-ins
assert_some(option:),assert_none(option:)assert_ok(result:),assert_err(result:)assert_panics(f:)assert_panics_with(f:, msg:)
-
Implement: Option/Result methods
.map(transform:),.and_then(transform:).unwrap_or(default:),.filter(predicate:).ok_or(error:),.ok(),.err().context(msg:)for Result.trace(),.trace_entries(),.has_trace()
-
Fix: Conversion method return type tracking (all fixed, verified 2026-03-29)
int.f()result type — FIXED (test_conv_int_f_shorthandpasses)int.byte()— FIXED (test_conv_int_to_byte_truncatespasses)int.byte().to_int()conversion chain — FIXED (test_conv_int_to_byte,test_conv_int_to_byte_max,test_conv_int_to_byte_to_intpass)
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.12) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.12 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.12: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.13 FFI Support
Related Proposals:
proposals/approved/platform-ffi-proposal.md
-
Implement: C FFI
extern "c" from "lib" { ... }declaration codegen- C type bindings:
c_char,c_short,c_int,c_long,c_longlong - C type bindings:
c_float,c_double,c_size - Function name mapping with
as "native_name" CPtropaque pointer type (size_t sized)Option<CPtr>for nullable pointers (None = null)- C variadic functions:
extern "c" { @printf (fmt: CPtr, ...) -> c_int }- Parse variadic
...in extern function declarations - LLVM codegen: emit variadic function type (
fn_type(..., true)) - Argument promotion rules:
float→double,i8/i16→i32(C ABI) - Variadic calls only allowed for extern declarations (not user-defined)
- Parse variadic
- Library linking:
-l<lib>flag generation - Rust Tests:
ori_llvm/src/ffi/c_ffi_tests.rs
-
Implement: Unsafe expressions
unsafe { ... }block codegen (same as inner expr, marker only)uses FFIcapability requirement at call sites- Pointer operations:
ptr_read<T>(ptr:),ptr_write<T>(ptr:, value:) - Pointer arithmetic (future)
- Rust Tests:
ori_llvm/src/ffi/unsafe_tests.rs
-
Implement: JavaScript FFI (WASM target)
extern "js" { ... }declaration codegenextern "js" from "./file.js"imports with path resolutionJsValuehandle type (index into JS heap slab)JsPromise<T>async handling- Implicit promise resolution at
letbinding sites - String marshalling: Ori str ↔ JS TextEncoder/TextDecoder
- Rust Tests:
ori_llvm/src/ffi/js_ffi_tests.rs
-
Implement: Memory layout control
#repr("c")struct attribute- C-compatible struct layout (field order, padding, alignment)
- Callback support: Ori functions as C function pointers
- Rust Tests:
ori_llvm/src/ffi/layout_tests.rs
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.13) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.13 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.13: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.14 Conditional Compilation
Related Proposals:
proposals/approved/conditional-compilation-proposal.md
-
Implement: Target conditionals
#target(os: "linux")- compile only if target OS matches#target(arch: "x86_64")- compile only if arch matches#target(family: "unix")- compile only if family matchesany_os: ["linux", "macos"]- compile if any matchnot_os: "windows"- compile if OS doesn’t match- File-level:
#!target(...)at top of file - Non-matching branches not emitted to object file
- Rust Tests:
ori_llvm/src/conditional/target_tests.rs
-
Implement: Config conditionals
#cfg(debug)- compile only in debug builds#cfg(release)- compile only in release builds#cfg(feature: "name")- compile if feature enabledany_feature: ["a", "b"]- compile if any feature enablednot_feature: "x"- compile if feature not enablednot_debug- compile only in release- Rust Tests:
ori_llvm/src/conditional/config_tests.rs
-
Implement: Compile-time constants
$target_os→"linux"|"macos"|"windows"| …$target_arch→"x86_64"|"aarch64"|"wasm32"| …$target_family→"unix"|"windows"|"wasm"$debug→truein debug builds,falseotherwise$release→truein release builds,falseotherwise- False branch not type-checked (dead code elimination)
- Rust Tests:
ori_llvm/src/conditional/const_tests.rs
-
Implement: Compile errors
compile_error("msg")emits error at compile time- Used with conditionals for unsupported configurations
- Rust Tests:
ori_llvm/src/conditional/error_tests.rs
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.14) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.14 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.14: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.15 Memory Management (ARC)
Related Proposals:
proposals/approved/drop-trait-proposal.mdproposals/approved/memory-model-edge-cases-proposal.mdproposals/approved/clone-trait-proposal.md
-
Spec: Type classification in
15-memory-model.mdupdated to type-containment model (matchesori_arc) -
Implement: Reference counting
- Heap allocation with atomic refcount header:
{ refcount: AtomicU64, data: T } fetch_add(1, Acquire)on clone/sharefetch_sub(1, Release)on drop- Free when refcount reaches zero (after acquire fence)
- Stack-allocated values: no refcount (moved or copied)
- Rust Tests:
ori_llvm/src/arc/refcount_tests.rs
- Heap allocation with atomic refcount header:
-
Spec: Drop trait in
spec/08-types.md§ Drop Trait DONE- Trait definition, execution timing, LIFO order
- Constraints (no async, must return void, panic during unwind = abort)
- drop_early built-in function
-
Implement: Drop trait codegen
- Detect types implementing
Droptrait - Generate destructor call when refcount reaches zero
- Destructor runs before memory reclamation
@drop (self) -> voidsignature- Drop cannot declare
uses Suspend(compile error) - Rust Tests:
ori_llvm/src/arc/drop_tests.rs
- Detect types implementing
-
Implement: Destruction ordering
- Local bindings: reverse declaration order
- Struct fields: reverse declaration order
- List elements: back-to-front (last element first)
- Tuple elements: right-to-left
(a, b, c)→ c, b, a - Map entries: unspecified order (no guarantees)
- Rust Tests:
ori_llvm/src/arc/order_tests.rs
-
Implement: Panic during destruction
- Single panic in destructor: propagate normally
- Other destructors still run after first panic
- Double panic (destructor panics during unwind): immediate abort
- Abort message: “panic during panic - aborting”
- Rust Tests:
ori_llvm/src/arc/panic_tests.rs
-
Implement: Early drop
drop_early(value:)built-in- Immediately decrements refcount and runs destructor if zero
- Value cannot be used after
drop_early - Compile error if value used after drop
- Rust Tests:
ori_llvm/src/arc/early_drop_tests.rs
-
Implement: Async destructor restriction
- Compile error if Drop.drop declares
uses Suspend - Error code and message for async destructor attempt
- Compile error if Drop.drop declares
-
Implement: Last-reference optimization (in-place mutation when RC=1)
- Detect
isUnique(ref)at runtime (refcount == 1) - When unique, reuse allocation for same-shape value instead of alloc+free
- Applies to struct update, map insert/remove, list push/pop
- Reference: Perceus paper §3.3 “Reuse Analysis”, Koka
CheckFBIP.hs - Rust Tests:
ori_llvm/tests/aot/arc.rs— last-reference reuse tests
- Detect
-
Implement: Reset/reuse optimization (constructing same-shape value after match)
- After pattern match deconstructs a value, reuse its allocation for newly constructed value of same type
- Emit
reset/reuseinstructions in canonical IR (Lean 4 / Koka pattern) - Only applies when matched value has RC=1 (exclusive ownership)
- Reference: Lean 4
ExpandResetReuse.lean, Perceus paper §3.4 - Rust Tests:
ori_llvm/tests/aot/arc.rs— reset/reuse tests
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.15) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.15 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.15: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.16 Optimization Passes
21.16.1 Representation Optimization
Proposal: proposals/approved/representation-optimization-proposal.md
Formalize the compiler’s freedom to optimize machine representations while preserving semantic equivalence. Tier 1 and most Tier 2 optimizations are already implemented. All [x] items verified 2026-03-29 via 65 type_info unit tests + 36 narrowing integration tests.
-
Tier 1: Type-Intrinsic Narrowing —
type_info/mod.rsbool→i1,byte→i8,char→i32,Ordering→i8void→ zero-sized ori64(0)- Range inclusive flag →
i1
-
Tier 2a: Enum Discriminant Narrowing —
type_info/mod.rs- All enum tags use
i8 - Dynamic tag width for >256 variants (i16/i32)
- All enum tags use
-
Tier 2b: All-Unit Enum Elimination —
type_info/mod.rs- Enums with no payload variants omit payload array
-
Tier 2c: Sum Type Payload Sharing —
lower_error_handling.rs- Result uses max(Ok, Err) payload slot
- Alloca+store+load coercion pattern with zero-initialization
-
Tier 2d: ARC Elision —
type_info/mod.rs- Transitive triviality classification with cycle detection
- Two-level check: per-type conservative + transitive walk
-
Tier 2e: Newtype Erasure — already specified in Types § Newtype
-
Tier 2f: Struct Field Reordering — not implemented
- Alignment-aware field ordering to reduce padding
- Respect
#reprattribute constraints - Maintain declaration-order mapping for derived traits
-
Tier 3: LLVM-Delegated Value Range Narrowing — future
- Emit
nsw/nuwflags on overflow-checked arithmetic - Emit
rangemetadata on loads with known value ranges - Emit
nonnull/dereferenceableattributes on pointers
- Emit
-
Known Gaps:
- ABI size computation ignores struct field padding (
abi/mod.rs) TypeInfo::alignment()returns hardcoded values, not representation-aware
- ABI size computation ignores struct field padding (
21.16.2 LLVM Optimization Pipeline
-
Implement: Optimization pipeline
- Configure standard optimization levels (O0, O1, O2, O3)
- Enable inlining, dead code elimination, constant folding
- Loop optimizations
- Tail call optimization
-
Implement: Debug info generation
- Source location tracking
- Variable debug info
- Type debug info
- DWARF/CodeView emission
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.16) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.16 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.16: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.17 Runtime Support
-
Implement: Basic runtime functions
- Rust Tests:
tests/runtime_tests.rs ori_print,ori_print_int,ori_print_float,ori_print_boolori_panic,ori_panic_cstrori_assert,ori_assert_eq_int,ori_assert_eq_bool,ori_assert_eq_strori_str_concat,ori_str_eq,ori_str_neori_str_from_int,ori_str_from_bool,ori_str_from_floatori_list_new,ori_list_free,ori_list_lenori_compare_int,ori_min_int,ori_max_int
- Rust Tests:
-
Implement: Extended runtime
- Map runtime functions
- Set runtime functions
- Channel runtime functions
- Duration/Size runtime functions
- Stack trace capture functions
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (21.17) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.17 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.17: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. -
Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.18 Architecture (Reference)
The LLVM backend follows Rust’s rustc_codegen_llvm patterns:
Context Hierarchy
// Simple context - just LLVM types
pub struct SimpleCx<'ll> {
pub llcx: &'ll Context,
pub llmod: Module<'ll>,
pub ptr_type: PointerType<'ll>,
pub isize_ty: IntType<'ll>,
}
// Full context - adds Ori-specific state
pub struct CodegenCx<'ll, 'tcx> {
pub scx: SimpleCx<'ll>,
pub interner: &'tcx StringInterner,
pub instances: RefCell<HashMap<Name, FunctionValue<'ll>>>,
pub type_cache: RefCell<TypeCache<'ll>>,
}
Builder Pattern
pub struct Builder<'a, 'll, 'tcx> {
llbuilder: &'a inkwell::builder::Builder<'ll>,
cx: &'a CodegenCx<'ll, 'tcx>,
}
Directory Structure
ori_llvm/src/
├── lib.rs # Crate root, re-exports
├── context.rs # SimpleCx, CodegenCx, TypeCache
├── builder.rs # Builder + expression compilation
├── types.rs # Type mapping helpers
├── declare.rs # Function declaration
├── traits.rs # BackendTypes, BuilderMethods traits
├── module.rs # ModuleCompiler (two-phase codegen)
├── runtime.rs # Runtime FFI functions
├── evaluator.rs # JIT evaluator (OwnedLLVMEvaluator)
├── operators.rs # Binary/unary operator codegen
├── control_flow.rs # if/else, loops, break/continue
├── matching.rs # Pattern matching codegen
├── collections/ # Collection codegen (tuples, structs, lists)
│ ├── mod.rs
│ ├── tuples.rs
│ ├── structs.rs
│ ├── lists.rs
│ └── option_result.rs
├── functions/ # Function codegen
│ ├── mod.rs
│ ├── body.rs # Function body compilation
│ ├── calls.rs # Function call codegen
│ ├── lambdas.rs # Lambda/closure codegen
│ ├── builtins.rs # Built-in function codegen
│ ├── sequences.rs # FunctionSeq (run, try, match)
│ └── expressions.rs # FunctionExp (recurse, print, panic)
└── tests/ # Unit tests
├── mod.rs
├── arithmetic_tests.rs
├── collection_tests.rs
├── control_flow_tests.rs
├── function_tests.rs
├── matching_tests.rs
└── ...
-
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. - Subsection close-out (21.18) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.18 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.18: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. - Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.19 Section Completion Checklist
Infrastructure:
Type System:
Expressions:
Control Flow:
Traits & Dispatch:
Concurrency:
Capabilities:
FFI:
Memory:
Optimization:
Verified AOT Gaps (from Section 11.1 verification, updated 2026-02-23):
Resolved:
Resolved:
Open:
Cross-references to existing items:
- Generic monomorphization → § 21.7 — RESOLVED
- Enum variant constructors → § 21.2 (blocks enums, recursive types)
catch(expr:)→ § 21.5 — RESOLVED- String interpolation → § 21.3 — RESOLVED
New AOT tests added (2026-02-23, 13 tests, all passing): derive_eq_struct (un-ignored), derive_eq_struct_not_equal, derive_eq_struct_with_strings, derive_comparable_struct (4 comparisons: <, >, <=, >=), panic_basic, option_unwrap_some, result_unwrap_ok, struct_with_list_and_string, nested_struct_with_strings, for_yield_with_filter, for_yield_transform
New AOT test files added (2026-02-23, Section 11.1 verification — 5 files, 117 tests total):
error_handling.rs— 21 tests (21 pass, 0 ignore): Result/Option basics,?operator, chaining, deep chainshigher_order.rs— 27 tests (23 pass, 4 ignore): HOF apply, composition, closures with captures, nested closures, foldtuples.rs— 29 tests (23 pass, 6 ignore): construction, destructuring, field access, as param/return, nested, strings, closuresstructs.rs— 29 tests (28 pass, 1 ignore): construction, string fields, update syntax, nested, as param/return, closures, derived Eqrecursion.rs— 22 tests (22 pass, 0 ignore): factorial, fibonacci, tail-recursive, mutual, with Result/Option/match, depth tests
Total AOT test counts: 1977 passed, 0 failed, 17 ignored
Remaining known bugs:
- Catch type inference:
catch()returnsResult<() -> T, str>instead ofResult<T, str>— blocks 12 AOT tests (type checker bug, not LLVM) - Inline panic in catch:
invokeonly intercepts callee-function panics, not same-function inline code — blocks 1 test - Chained tuple field access:
t.0.1lexed as float by parser — blocks 2 tests (parser bug, not LLVM; tracked in Section 05) - Nounwind analysis: does not distinguish may-unwind monomorphized callees — blocks 1 test
Exit Criteria: Feature parity with evaluator for all language constructs
- JIT compilation working
- All current Ori tests pass via LLVM
- All Rust unit tests pass (466/466 lib, 0 ignored; verified 2026-03-29)
- Architecture follows Rust patterns
- Unified import pipeline (imports resolved once, compiled into JIT module)
- Generic monomorphization
- AOT compilation (see Section 21B)
- Primitive types
- Option/Result (basic)
- Lists (basic)
- Duration/Size types (partial — basic arithmetic works, methods not implemented)
- Newtypes
- Sum types (general)
- Fixed-capacity lists
- Channels
- Maps (full support)
- Sets
- Basic expressions
- Binary/unary operators (primitives)
- Range with step (
by) - Spread operator (
...) (struct spread works; list/map spread status unclear) - Coalesce operator (
??) - Floor division (
div) - Type conversions (
as,as?) - Complex assignments
- Basic if/else, loops
- Labeled loops
- Break with values
- For-yield expressions
- Try/catch patterns
- Associated functions
- Operator trait dispatch
- Iterator trait methods (partial — map/filter/fold/collect/take/chain work)
- Comparison trait methods
- Parallel pattern
- Spawn pattern
- Channels
- Nursery pattern
- Capability tracking
- With pattern provision
- Default implementations
- C FFI
- JavaScript FFI
- Unsafe blocks
- ARC implementation
- Drop trait
- Destruction ordering
- Representation optimization (Tiers 1-2e done)
- LLVM optimization pipeline
- Debug info generation
- Derive Eq struct codegen:
emit_comparison_via_traitnow dispatches to derivedeqmethod for non-primitive types instead of falling through to scalaricmp - Derive Comparable struct codegen:
emit_ordering_comparisonnow dispatches to derivedcomparemethod and checks Ordering result (0=Less, 1=Equal, 2=Greater) for</>/<=/>= - ARC enum basic drop and string-payload drop:
test_arc_enum_basic_dropandtest_arc_enum_with_string_payloadun-ignored and passing - List mutation methods in AOT builtin table — FIXED (
test_aot_list_push,test_aot_list_first_lastpass) - Map methods in AOT builtin table — FIXED (
test_aot_map_is_emptypasses) -
list[index]subscript resolved — FIXED (test_aot_list_indexpasses) - Closure-returning-closure type inference — FIXED (
test_aot_closure_capturing_closurepasses) - Generic monomorphization in ARC pipeline — FIXED (33 generics tests pass)
-
catch(expr:)lowered through ARC pipeline — FIXED (9 catch tests pass) - String interpolation — FIXED (
test_aot_string_interpolationpasses) - Enum variant constructors not declared as LLVM functions (no test found by listed name, but many enum tests pass via derives and pattern matching)
-
/tpr-reviewpassed — independent Codex review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — implementation hygiene review clean (phase boundaries, SSOT, algorithmic DRY, naming). MUST run AFTER/tpr-reviewis clean. -
/improve-toolingretrospective completed — MANDATORY at section close, after both reviews are clean. Reflect on the section’s debugging journey (whichdiagnostics/scripts you ran, which command sequences you repeated, where you added ad-hocdbg!/tracingcalls, where output was hard to interpret) and identify any tool/log/diagnostic improvement that would have made this section materially easier OR that would help the next section touching this area. Implement every accepted improvement NOW (zero deferral) and commit each via SEPARATE/commit-push. The retrospective is mandatory even when nothing felt painful — that is exactly when blind spots accumulate. See.claude/skills/improve-tooling/SKILL.md“Retrospective Mode” for the full protocol. -
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. - Subsection close-out (21.19) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.19 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.19: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW. - Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
21.20 AIMS Flow-Based RC Realization (Path A’)
This subsection group implements Path A’: Perceus-style flow-based RC emission consuming the existing AIMS lattice as oracle, with inc/dec balance as a structural theorem of the emission algorithm rather than a tested property of lattice output. Refines the existing realize/ pipeline (already documented as “Perceus-inspired RC + reuse” at compiler_repo/compiler/ori_arc/src/aims/realize/mod.rs:13; QTT semiring already encoded at compiler_repo/compiler/ori_arc/src/aims/lattice/dimensions.rs:63-76 per Atkey LICS 2018) without replacing the lattice. Per AIMS Invariant 5: extends MemoryContract.flow_balance (case (b)) and consumes AimsStateMap as typed pre-pass input (case (c)) — no parallel emission path, no shadow uniqueness tracker.
Absorbs:
plans/repr-opt/section-08-escape-analysis.md(6 subsections, 100% not-started) → §21.20.6plans/repr-opt/section-09-arc-header.md(4 subsections, 100% not-started, third_party_review statefindings) → §21.20.7plans/repr-opt/section-10-thread-local-arc.md(4 subsections, 100% not-started) → §21.20.8plans/semantic-optimization-pipeline/section-02-metadata-infra.md(3 subsections, 100% not-started,depends_on: []) → §21.20.9 prerequisiteplans/semantic-optimization-pipeline/section-03-aims-export.md(3 subsections, 100% not-started,depends_on: ["02"]) → §21.20.9
Source plans transition to status: complete with superseded_by: plans/roadmap/section-21A-llvm.md§21.20.X upon their absorbed subsection’s close-out (Phase 5 Step 19 cross-plan invalidation flips overlapping reviewed: true to false in the same operation).
Coordinates-with: plans/roadmap/section-21B-aot.md for ori_rt runtime-primitive changes in §21.20.7 (header layout) and §21.20.8 (non-atomic Rc primitives). The ABI contract between ori_llvm codegen and ori_rt is load-bearing per .claude/rules/missions.md §ori_rt (“ABI drift produces silent memory corruption”); every commit changing ori_rt signatures updates ori_llvm call sites in the same commit.
Provenance: Synthesized from a 5-round dual-source TPR (60+ verified findings, scratch dirs /tmp/tpr-round-ori_lang-{ICT7JdWz, HknXdvOq, j1AElJAe, GQCN3JWi, hhbhCJc4}/) plus a Phase 1D third-party consensus consultation on the expanded mission. The TPR converged on Path A’ as a stable 2-of-3 majority across all rounds; the Phase 1D consultation refined the phase ordering to contract-first (per Codex+Gemini majority) with a FlowBalance schema sketch in §21.20.2 (Opencode’s iterative-design concession). The seed question was “should AIMS adopt Sinkhorn-Knopp doubly stochastic matrix to enforce RC balance”; reviewers rejected DSM (coerces values rather than proving balance) and the deeper instinct (“make invalid states unrepresentable”) was identified as Cousot 1977 abstract interpretation — which AIMS already implements (“the lattice IS a matrix” per Opencode).
Phase ordering (contract-first):
- §21.20.1 Audit + Consolidate decide_rc() Pure Decision Surface
- §21.20.2 Define Proof Obligations + FlowBalance Schema Sketch
- §21.20.3 Extend MemoryContract.flow_balance + Salsa Cache Migration
- §21.20.4 Route emit_unified Through Proof-Carrying decide Records
- §21.20.5 VF-3b verify_flow_balance() Inside aims/verify/oracle.rs
- §21.20.6 Stack Promotion (absorbs repr-opt §08)
- §21.20.7 RC Header Compression (absorbs repr-opt §09; coordinates-with section-21B-aot)
- §21.20.8 Non-Atomic Thread-Local Rc (absorbs repr-opt §10; coordinates-with section-21B-aot)
- §21.20.9 AIMS→LLVM Fact Export (absorbs semantic-optimization-pipeline §02 + §03)
- §21.20.R Third Party Review Findings
- §21.20.N Completion Checklist
Each subsection’s Pre: line declares its concrete dependency on prior subsections.
21.20.1 AIMS Flow Realization — Audit + Consolidate decide_rc() Pure Decision Surface
Goal: Cure LEAK:algorithmic-duplication on realize/walk* + emit_rc/ by consolidating scattered decision logic into the existing canonical decide_rc() pure function (compiler_repo/compiler/ori_arc/src/aims/realize/decide.rs:165); extend the function’s call surface to receive proof-obligation metadata (filled in §21.20.2) without changing emission behavior. Refactor-only — no observable behavior change. RL-1..RL-34 coverage audit lands here per the GAP:spec-vs-realization blocker surfaced in Phase 1D.
Pre: None. Foundation subsection.
Provides to downstream: decide_rc() extension surface that §21.20.2 fills with proof obligations; clean emit_rc/ module boundary for §21.20.4 routing migration; baseline cargo b + ./test-all.sh green for §21.20.X performance gates.
Context (verified by Phase 2 Pass 1)
emit_rc/ module dependency DAG drives consolidation order (leaf → depth-1 → depth-2 → depth-3):
- LEAF (no
emit_rc/deps):helpers.rs(561 lines, most-imported),borrowed_defs.rs(458),queries.rs(203),cow.rs(91),coalesce/mod.rs(229),drop_hints/mod.rs(190),arg_ownership/mod.rs(164),unwind_cleanup/mod.rs(190) - DEPTH-1:
trampoline.rs(146) →mod.rs;take_project/mod.rs(784) →borrowed_defs::is_take_project - DEPTH-2:
forward_walk.rs(233) →helpers + mod.rs;dead_cleanup/mod.rs(396) →helpers + mod.rs - DEPTH-3:
edge_cleanup.rs(522) →trampoline + helpers
decide() at realize/decide.rs:165 is already the pure-function shape:
- Input:
DecisionContext { site: DecisionSite, is_rc_managed: bool }—DecisionSite ∈ {Use {has_future_use, semantics ∈ {Normal, BorrowingProject, TransferProject}}, DefinedDead, LastUse {is_consuming_primop, is_ownership_transfer, is_owned_call_position, has_deferred_children, reuse}} - Output:
InstructionDecisions { rc: RcDecision, reuse: ReuseDecision }—RcDecision ∈ {None, Inc, Dec, Defer, Skip},ReuseDecision ∈ {None, StaticReuse, DynamicReuse}
Extension target: add obligations: ProofObligations to DecisionContext (placeholder type in this subsection; concrete shape lands in §21.20.2’s FlowBalance schema sketch).
Deliverables
- emit_rc/ submodule audit — run
scripts/intel-query.sh callers/calleesacross all 13emit_rc/pub functions; document the inter-module call graph inemit_rc/mod.rs//!module doc. Verifies the dependency DAG above against current code (Pass 1 ground truth). - RL-1..RL-34 coverage audit — for each RL rule in
.claude/rules/aims-rules.md §8, identify the implementing function inrealize/decide.rsoremit_rc/*. Output: a table at the head ofdecide.rsmappingRL-N→file:line. RL-22..26 are explicitly post-pipeline peraims-rules.md §8and don’t count as gaps. RL-27 (selective barriers) and RL-34 (tail-call preservation) are the highest-suspicion candidates per the Phase 1DGAP:spec-vs-realizationfinding — verify each against current code. -
decide_rc()extension surface — addobligations: ProofObligationsfield toDecisionContextstruct indecide.rs; introduce a placeholderProofObligationstype (concrete fields populated by §21.20.2). All call sites (walk.rs:321,walk_dec.rs:104,walk_dec.rs:163, plus any others) updated to passProofObligations::empty(). No behavior change. -
helpers.rs:74dangling-comment fix — repair the///.cross-reference (link target stripped per Pass 1 verify); rewrite as a concrete description of the take-project bypass-safe entry refinement OR delete if no longer relevant. EliminatesCOMMENT_HYGIENE_DRIFT:inaccurate-commentMajor. - Banned-phrase scan — grep
realize/,emit_rc/,aims/contract/,aims/verify/,aims/lattice/, and.claude/rules/aims-rules.mdfor “migration safety”; replace with “migration gate” everywhere. Runpython3 scripts/prose-lint.py .claude/rules/aims-rules.mdclean. -
emit_rc/boundary documentation — add//!module doc toemit_rc/mod.rsexplaining: (a) the 13 submodules are proof-context providers consumed bydecide()+walk_*; (b) §21.20.4 will route emission through proof records, but the submodules themselves stay (per the Phase 1D consensus that “removing them mechanically would beLEAK:algorithmic-duplicationin reverse”).
Success criteria
- 0
LEAK:algorithmic-duplicationfindings onrealize/andemit_rc/per/impl-hygiene-reviewafter this subsection close - All 77 unit tests in
realize/tests.rs(1791 lines, naming convention<subject>_<scenario>_<expected>per Pass 1) pass:cargo t -p ori_arc -- realize::tests cargo bclean (debug + release):cargo b && cargo b --release./test-all.shgreencompiler_repo/clippy-all.shclean on touched files (no new#[expect(clippy::...)]annotations)- RL-1..RL-34 coverage table committed at
decide.rshead withfile:linepointers; anyGAP:spec-vs-realizationitems either resolved here or filed as explicit blockers feeding §21.20.2 helpers.rs:74dangling-comment cleaned; comment passesprose-lint.pyand conveys a concrete invariant- 0 occurrences of “migration safety” in Path A’ scope; “migration gate” used uniformly
Test strategy
Refactor-only subsection; matrix testing applies via the existing test corpus per .claude/rules/tests.md §Matrix Testing Rule:
- Matrix dimensions (already covered by the existing 77 tests in
realize/tests.rs):- Types:
str,[int],[str],Option<int>,Option<str>, structs, enums, closures, maps, sets - Decision sites:
Use {has_future_use=true/false, semantics ∈ {Normal, BorrowingProject, TransferProject}},DefinedDead,LastUse {is_consuming_primop, is_ownership_transfer, is_owned_call_position, has_deferred_children, reuse}
- Types:
- Semantic pin: NONE NEW — this subsection adds no behavior; existing tests serve as regression pins for the refactor
- TDD ordering: For NEW deliverables (
ProofObligationsplaceholder pass-through, RL-coverage table generator), write characterization tests FIRST that capture the placeholder pass-through (ProofObligations::empty()produces identical decisions to the no-obligations baseline); verify failing → passing → regression-anchored - Test types: Rust unit tests in
realize/tests.rs(existing 77 + ~3-5 new forProofObligationsplaceholder pass-through); no Ori spec tests needed (decision-layer is internal toori_arc)
Section-Close Completion Checklist
Running Tests
# LLVM is a default feature — no Docker required (verified 2026-03-29)
# Build all (includes LLVM)
cargo b
# Run all tests (Rust unit + AOT integration + spec)
./test-all.sh
# Run LLVM-specific tests
cargo test -p ori_llvm --lib # 466 unit tests
cargo test -p ori_llvm --test aot_tests # 1977 AOT integration tests
# Run spec tests only
cargo st
# Run with debug output
ORI_DEBUG_LLVM=1 ori test tests/spec/types/primitives.ori
# Legacy Docker workflow still works but is not required:
# ./docker/llvm/build.sh && ./docker/llvm/run.sh ori test
- All deliverables checkboxes above checked
- All success criteria verified green
-
cargo bclean (debug + release):cargo b && cargo b --release -
cargo t -p ori_arcgreen (debug + release) -
./test-all.shgreen -
compiler_repo/clippy-all.shclean -
compiler_repo/fmt-all.shclean -
python3 scripts/prose-lint.py .claude/rules/aims-rules.mdclean (banned-phrase scan) -
python3 -m scripts.plan_corpus check plans/roadmap/section-21A-llvm.mdexit 0 -
compiler_repo/diagnostics/state.sh refresh --dispositions-onlyshows zero new untracked entries on touched files -
/tpr-reviewpassed — independent review found no critical or high findings (or all triaged) -
/impl-hygiene-reviewpassed — hygiene clean. MUST run AFTER/tpr-reviewis clean - Subsection close-out (21.20.1) — MANDATORY before starting §21.20.2. Run
/improve-toolingretrospectively on this subsection’s debugging journey per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”: whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool / log / diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE/commit-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-21.20.1 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 21.20.1: no tooling gaps”. Update this subsection’sstatusin section-21A frontmatter tocomplete. -
/sync-claudesection-close doc sync — verify CLAUDE.md,.claude/rules/aims-rules.md,.claude/rules/arc.md,.claude/rules/canon.mdalignment with the consolidateddecide_rc()shape; fix drift NOW -
compiler_repo/diagnostics/repo-hygiene.sh --checkclean