02 Adapters: Decrement on Discard
With Section 01 complete, every yielded element is owned (+1 RC). Adapters that discard elements (filter rejections, skip’s N elements) must now dec them to prevent leaks. Adapters that pass through elements (take, chain, enumerate) already have correct ownership — the element flows from source to consumer unchanged. Adapters that produce new elements (map, flat_map) already yield owned values.
02.1 Filter: Dec Rejected Elements
File: compiler/ori_rt/src/iterator/next.rs — next_filtered (lines 157-172)
Currently, rejected elements are read into a scratch buffer and silently discarded when the loop re-advances. With owned elements, these must be dec’d.
-
Add
elem_dec_fn: Option<extern "C" fn(*mut u8)>toIterState::Filteredvariant instate.rs -
Update
ori_iter_filterinadapters.rsto accept and storeelem_dec_fn -
In
next_filtered: after predicate returns false, callelem_dec_fn(scratch.as_mut_ptr())on the rejected element -
TDD: AOT test —
[1,2,3,4,5].iter().filter(x -> x % 2 == 0).collect()with str elements, verify zero leaks -
Codegen update (Section 04):
emit_iter_filtermust passget_or_generate_elem_dec_fn(elem_ty) -
Subsection close-out (02.1) — MANDATORY before starting 02.2:
- All tasks above are
[x]and behavior verified - Update this subsection’s
statusin section frontmatter tocomplete - Run
/improve-toolingretrospectively on THIS subsection - Run
/sync-claudeon THIS subsection — check whether code changes invalidated any CLAUDE.md,.claude/rules/*.md, orcanon.mdclaims. If no API/command/phase changes, document briefly. Fix any drift NOW. - Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
- All tasks above are
02.2 Skip: Dec Skipped Elements
File: compiler/ori_rt/src/iterator/next.rs — next_skip (lines 191-206)
Same pattern as filter. Skipped elements are read into scratch and discarded.
-
Add
elem_dec_fn: Option<extern "C" fn(*mut u8)>toIterState::SkipNvariant instate.rs -
Update
ori_iter_skipinadapters.rsto accept and storeelem_dec_fn -
In
next_skip: after each skipped element, callelem_dec_fn(scratch.as_mut_ptr()) -
TDD: AOT test —
["a","b","c","d"].iter().skip(count: 2).join(separator: ",")with str elements, verify zero leaks -
Codegen update (Section 04):
emit_iter_skipmust passget_or_generate_elem_dec_fn(elem_ty) -
Subsection close-out (02.2) — MANDATORY before starting 02.3:
- All tasks above are
[x]and behavior verified - Update this subsection’s
statusin section frontmatter tocomplete - Run
/improve-toolingretrospectively on THIS subsection - Run
/sync-claudeon THIS subsection — check whether code changes invalidated any CLAUDE.md,.claude/rules/*.md, orcanon.mdclaims. If no API/command/phase changes, document briefly. Fix any drift NOW. - Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
- All tasks above are
02.3 Cycle and Rev: Storage Ownership
Files: adapters.rs (ori_iter_cycle, ori_iter_rev), next.rs (next_cycled, next_reversed)
These adapters eagerly collect elements into a Vec<u8> buffer. With owned elements:
-
cycle: First pass stores owned elements into buffer (they were yielded as +1 from source). Buffer now owns them. On replay passes, the buffer yields copies — these need inc (same as list yields). Add
elem_inc_fntoIterState::Cycled. -
rev: Collects all elements into
Vec<u8>, drops source. Elements in the Vec are owned. When yielding backward, the bytes are copied out — but since the Vec will be freed, no additional inc needed (transfer semantics). Verify the Vec cleanup path callselem_dec_fnfor remaining elements if iteration terminates early (break/take). -
TDD: AOT tests for cycle + rev with str elements under leak check
-
Subsection close-out (02.3) — MANDATORY before starting 02.4:
- All tasks above are
[x]and behavior verified - Update this subsection’s
statusin section frontmatter tocomplete - Run
/improve-toolingretrospectively on THIS subsection - Run
/sync-claudeon THIS subsection — check whether code changes invalidated any CLAUDE.md,.claude/rules/*.md, orcanon.mdclaims. If no API/command/phase changes, document briefly. Fix any drift NOW. - Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
- All tasks above are
02.4 Pass-Through Adapters: Verify
Adapters: take, chain, enumerate, zip, flatten, flat_map
These adapters do not discard elements — they pass them through from source to consumer. With owned elements from Section 01, the ownership flows naturally.
-
take: passes through first N elements, then stops. Source’s remaining elements are cleaned up by the source’s Drop (which already handles RC). No change needed. Verify.
-
chain: passes through all elements from
firstthensecond. Ownership flows from each source. No change needed. Verify. -
enumerate: wraps element in
(index, element)tuple. The element’s ownership transfers into the tuple. No change needed. Verify. -
zip: concatenates bytes from two sources. Both sources yield owned elements. The zip output tuple owns both. No change needed. Verify.
-
flatten: yields elements from nested iterators. Inner iterators yield owned elements. No change needed. Verify.
-
flat_map: composition of map + flatten. Both already handle ownership. No change needed. Verify.
-
Subsection close-out (02.4) — MANDATORY before starting Section 03:
- All tasks above are
[x]and behavior verified - Update this subsection’s
statusin section frontmatter tocomplete - Run
/improve-toolingretrospectively on THIS subsection - Run
/sync-claudeon THIS subsection — check whether code changes invalidated any CLAUDE.md,.claude/rules/*.md, orcanon.mdclaims. If no API/command/phase changes, document briefly. Fix any drift NOW. - Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files.
- All tasks above are
02.R Third Party Review Findings
- None.
02.N Completion Checklist
- Filter and skip adapters correctly dec discarded elements
- Cycle correctly handles first-pass storage and replay inc
- Rev correctly handles collected element cleanup
- All pass-through adapters verified (no change needed)
-
timeout 150 ./test-all.shgreen -
timeout 150 ./clippy-all.shgreen -
/commit-push -
/tpr-reviewpassed -
/impl-hygiene-reviewpassed -
/improve-toolingsection-close sweep