0%

01 Sources: Increment on Yield

The foundation of the ownership protocol. Source iterators that yield borrowed copies of collection elements must increment the element’s RC so the yielded copy is independently owned. Source iterators that yield fresh values (Range yields ints, Option yields a copy) already produce owned elements.

01.1 Extend IterState::List with elem_inc_fn

File: compiler/ori_rt/src/iterator/state.rs

The List variant of IterState currently stores data, len, cap, elem_size (line ~53). It needs an elem_inc_fn: Option<extern "C" fn(*mut u8)> field.

  • Add elem_inc_fn: Option<extern "C" fn(*mut u8)> to IterState::List variant

  • Update the Drop impl for List — no change needed (it already uses ori_buffer_rc_dec which reads elem_dec_fn from the V5 header)

  • Verify IterState size doesn’t blow the cache line budget (currently fits in ~128 bytes for largest variant)

  • Subsection close-out (01.1) — MANDATORY before starting 01.2:

    • All tasks above are [x] and behavior verified
    • Update this subsection’s status in section frontmatter to complete
    • Run /improve-tooling retrospectively on THIS subsection
    • Run /sync-claude on THIS subsection — check whether code changes invalidated any CLAUDE.md, .claude/rules/*.md, or canon.md claims. If no API/command/phase changes, document briefly. Fix any drift NOW.
    • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.

01.2 Extend ori_iter_from_list Signature

File: compiler/ori_rt/src/iterator/sources.rs

ori_iter_from_list (line 28) currently takes (data: *mut u8, len: i64, cap: i64, elem_size: i64). Add elem_inc_fn.

  • Change signature to (data, len, cap, elem_size, elem_inc_fn: Option<extern "C" fn(*mut u8)>)
  • Store elem_inc_fn in the IterState::List variant
  • Update all callers in ori_llvmemit_iter_from_list in compiler/ori_llvm/src/codegen/arc_emitter/builtins/iterator.rs must pass the new parameter
  • Runtime tests in compiler/ori_rt/src/iterator/tests.rs — update ori_iter_from_list calls to pass None (existing tests use int elements = scalar = no inc needed)

C ABI contract: elem_inc_fn is Option<extern "C" fn(*mut u8)> — same type as elem_dec_fn. Null for scalar elements. For RC elements (str, lists, closures), it’s the same function generated by get_or_generate_elem_inc_fn() in element_fn_gen.rs.

  • Subsection close-out (01.2) — MANDATORY before starting 01.3:
    • All tasks above are [x] and behavior verified
    • Update this subsection’s status in section frontmatter to complete
    • Run /improve-tooling retrospectively on THIS subsection
    • Run /sync-claude on THIS subsection — check whether code changes invalidated any CLAUDE.md, .claude/rules/*.md, or canon.md claims. If no API/command/phase changes, document briefly. Fix any drift NOW.
    • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.

01.3 Implement Inc in next_list

File: compiler/ori_rt/src/iterator/next.rs

next_list (lines 96-104) currently does a raw ptr::copy_nonoverlapping from the list buffer to out_ptr. After the copy, call elem_inc_fn on the destination pointer (the yielded copy).

  • After ptr::copy_nonoverlapping(data.add(offset as usize), out_ptr, es as usize) at line 101, add:
    if let Some(inc) = self.elem_inc_fn() {
        inc(out_ptr);
    }
    where elem_inc_fn() is a method on IterState that returns the stored function pointer for List variants (or None for others).
  • TDD: Write failing test FIRST — create an AOT test that joins mapped strings from a list, verifying zero leaks under ORI_CHECK_LEAKS=1. This test currently leaks; after the inc fix + consumer dec fix (Section 03), it will pass.
  • Verify next_list for scalar elements (int, float, bool) — elem_inc_fn is null, so the null-check short-circuits. Zero overhead for scalars.

Important: This change alone will cause DOUBLE RC for elements — the list still owns them AND the yielded copy now owns them. This is correct! The consumer will dec after use (Section 03), and the list’s Drop will dec the originals. Net effect: balanced.

  • Subsection close-out (01.3) — MANDATORY before starting 01.4:
    • All tasks above are [x] and behavior verified
    • Update this subsection’s status in section frontmatter to complete
    • Run /improve-tooling retrospectively on THIS subsection
    • Run /sync-claude on THIS subsection — check whether code changes invalidated any CLAUDE.md, .claude/rules/*.md, or canon.md claims. If no API/command/phase changes, document briefly. Fix any drift NOW.
    • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.

01.4 Verify Other Sources (Range, Str, Map, Option)

Files: compiler/ori_rt/src/iterator/sources.rs, next.rs

  • Range (next_range, line 106-140): yields i64 values. Scalar — no RC. No change needed. Verify.

  • Str (next_str): yields individual characters/codepoints. These are scalar values extracted from the string. No RC on individual chars. No change needed. Verify.

  • Map (next_map, state.rs Map variant): yields (key, value) pairs from map entries. The Map variant already stores key_dec_fn and val_dec_fn. Need to also store key_inc_fn and val_inc_fn and call them in next_map. Update ori_iter_from_map signature.

  • Option (ori_iter_from_option, sources.rs line 165-195): yields a single element from Some. The element is already copied into a 1-element buffer with elem_dec_fn stored in the header. Need to add inc on yield from that buffer (same pattern as list).

  • Subsection close-out (01.4) — MANDATORY before starting Section 02:

    • All tasks above are [x] and behavior verified
    • Update this subsection’s status in section frontmatter to complete
    • Run /improve-tooling retrospectively on THIS subsection
    • Run /sync-claude on THIS subsection — check whether code changes invalidated any CLAUDE.md, .claude/rules/*.md, or canon.md claims. If no API/command/phase changes, document briefly. Fix any drift NOW.
    • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.

01.R Third Party Review Findings

  • None.

01.N Completion Checklist

  • All source next_* functions yield owned elements
  • timeout 150 ./test-all.sh green (note: some tests may temporarily leak MORE because consumers don’t dec yet — this is expected until Section 03)
  • timeout 150 ./clippy-all.sh green
  • /commit-push
  • /tpr-review passed
  • /impl-hygiene-review passed
  • /improve-tooling section-close sweep