Skip to content

refactor: Milestone 8.2 — Implicit Borrow Liveness & Ownership Pass Refactors - #88

Merged
artefactop merged 18 commits into
mainfrom
feat/m8.2-implicit-borrow-liveness
Jul 14, 2026
Merged

refactor: Milestone 8.2 — Implicit Borrow Liveness & Ownership Pass Refactors#88
artefactop merged 18 commits into
mainfrom
feat/m8.2-implicit-borrow-liveness

Conversation

@artefactop

@artefactop artefactop commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

This PR fully implements Milestone 8.2 (Implicit Borrow Liveness & Ownership Pass Refactors) under Ryo’s implicit Rule 2 borrow model, delivering the core dataflow substrate for borrow-liveness and resolving 7 major architectural issues (ISSUES.md I-048/049/050/059/060/061/067).

Key Deliverables:

  1. Phase A — Architectural Refactors (8.2a):

    • Owner Enum (I-049): Replaces brittle synthetic param-ref encodings with a type-safe Owner enum.
    • Static named_inits Classifier (I-060): Purges named_owners side-set, replacing it with a stateless, recursive, merge-immune scan of VarDecl/Assign initializers.
    • ParamMode & Deleting by_name (I-048 / I-059): Carries parameter conventions in TIR Call payloads; deletes the by_name HashMap; replaces __ryo_panic string-matching with a clean builtin ABI registry.
    • Use-Site UAM Authority (I-050): Inverts use-after-move detection from Var reads to use-site check_use_moved.
    • Snapshot Scoping (I-061) & Loop Extraction (I-051): Limits snapshots to non-monotone fields; loops extracted to analyze_loop_body.
    • continue UAF Gate (I-067): Gates trailing defensive loop Free emits on is_break, preventing UAF on continue jumps.
  2. Phase B — Headline Check (8.2b):

    • E0023 (MoveWhileBorrowedInCall): Implements a two-phase Call argument evaluation (materialize first, partition, check overlap, then commit moves) to reject move-while-borrowed in the same call order-independently, with precise, multi-label Ariadne span notes pointing at the conflicting arguments.
  3. Closing:

    • Resolved the 8 issues in ISSUES.md and marked M8.2 complete in implementation_roadmap.md.

Verification:

  • 510/510 tests pass workspace-wide (11 new ownership-pass unit tests added).
  • cargo clippy --all-targets (zero warnings) and cargo fmt --check are 100% green.

Summary by CodeRabbit

  • Bug Fixes
    • Improved ownership tracking across function calls, branches, loops, and reassignments.
    • Prevented incorrect cleanup behavior for borrowed values.
    • Added clearer diagnostics when a value is moved while borrowed during a call (error code E0031).
    • Improved panic/assert call behavior, including borrowed-scalar argument handling.
    • Better handling of string-typed function parameters during call preparation.
  • Documentation
    • Refreshed the implementation roadmap with updated milestones, examples, and v0.2+ planning.
    • Expanded issue tracking notes and resolutions for upcoming compiler improvements.

…ncoding (I-049)

Replaces the u32::MAX - name.raw() param-key encoding with an explicit
Owner { Param(StringId), Inst(TirRef) } enum. Rekeys states,
current_owner, origin, pending_dead_store, owner_at_read, temp_owners.
Behavior-preserving; named_owners retained pending Task A2 (I-060).
…assifier (I-060)

Replaces the sticky named_owners side-set with a stateless static
derivation: collect_named_inits gathers the init/value TirRef of every
VarDecl/Assign (recursing into control flow), and the anon-temp pass
skips any temp in that set. Merge-immune where the current_owner.values()
draft double-freed loop-rebound temps.
Encoding-only: call_extra gains a MODES slot per arg, CallView exposes
modes, TirBuilder::call takes a &[ParamMode]. Sema stamps Move/Borrow
from the callee signature; builtins are all-Borrow. Ownership still
reads by_name until the next task.
…g (I-048)

Drops the HashMap<StringId, &Tir> threaded through the ownership-pass
signatures. The Call arm reads view.modes[i] directly. Builtins uniform.
The __ryo_panic borrowed-scalar name-match is retained pending Task 5's
ABI registry.
…(I-059)

BuiltinFunction carries borrowed_scalar_params; ownership + codegen
consult is_borrowed_scalar_param instead of pool.str(name) matching.
Codegen's borrowed-scalar Scalar-target tripwire downgrades to debug_assert.
…ved (I-050)

Introduces check_use_moved invoked at every use site (consume, borrow-arg,
StrConcat, and recurse_operands UnOp/BinOp). The Var arm demotes to
pure bookkeeping. Closes the gap where non-Var moved operands bypassed
the check.
…_loop_body (I-061, I-051)

Loop helpers and if-arm analysis snapshot only the non-monotone fields
(states, current_owner, pending_dead_store); union-only fields
(temp_owners, origin, owner_at_read, next_branch_id) stay live. The
while/for near-clones collapse into analyze_loop_body.
The pre-loop owner defensive-emit fired on both break and continue,
but freeing on continue is a use-after-free (next iteration re-reads
the freed buffer). Gate on is_break; accept a potential leak over UAF
until path-relative liveness lands.
Two-phase Call arm: materialise args, partition by underlying owner into
borrowed/moved sets, reject overlap (E0023), then commit moves. Catches
both f(read(x), consume(x)) and f(consume(x), read(x)) order-independently.
M8.2 delivered as implicit-borrow liveness + ownership-pass refactors
(E0023 move-while-borrowed-in-call). Explicit & syntax is M8.3 per spec §5.2.
Adds #[allow(clippy::too_many_arguments)] on consume_underlying, and
updates stale comments in ownership.rs and tir.rs to reflect the completed
M8.2 architecture.
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@artefactop, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 19 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 69ae7f69-6692-49c3-b384-f2d77778818e

📥 Commits

Reviewing files that changed from the base of the PR and between 2b25164 and 57db0fd.

📒 Files selected for processing (4)
  • ISSUES.md
  • ryo-backend/src/codegen.rs
  • ryo-core/src/tir.rs
  • ryo-frontend/src/ownership.rs
📝 Walkthrough

Walkthrough

The PR adds ownership modes to TIR calls, propagates them through semantic analysis and builtins, refactors ownership tracking around allocation owners, updates borrowed-scalar code generation, and substantially revises issue and roadmap documentation.

Changes

Ownership-aware calls

Layer / File(s) Summary
Call mode contract and encoding
ryo-core/src/tir.rs
TIR call payloads now encode and decode per-argument ParamMode values with round-trip coverage.
ABI metadata and semantic call emission
ryo-frontend/src/builtins.rs, ryo-frontend/src/sema.rs, ryo-core/src/diag.rs, ryo-driver/src/pipeline.rs
Borrowed-scalar ABI metadata is registered, call modes are emitted for functions, builtins, and panic calls, and the new diagnostic maps to E0031.
Allocation-keyed ownership analysis
ryo-frontend/src/ownership.rs
Ownership state, control-flow analysis, consumption checks, free scheduling, and regression tests use parameter or instruction owners.
String materialization and scalar free handling
ryo-backend/src/codegen.rs
String parameters are cached as string representations, and borrowed-scalar free handling diagnostics are updated.

Issue and roadmap documentation

Layer / File(s) Summary
Blocking issue registry updates
ISSUES.md
Issue entries from I-004 through I-066 are added or revised.
Current milestone roadmap
docs/dev/implementation_roadmap.md
Phases 1–4 and milestones through v0.1.0 receive updated statuses, examples, design notes, module and standard-library scope, testing, and distribution content.
Future language and tooling plans
docs/dev/implementation_roadmap.md
Phase 5 planning is expanded for concurrency, closures, FFI, generics, diagnostics, contracts, optimization, cancellation, tooling, and QA.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SemanticAnalysis
  participant TirBuilder
  participant OwnershipAnalysis
  participant Codegen
  SemanticAnalysis->>TirBuilder: emit arguments with ParamMode values
  TirBuilder->>OwnershipAnalysis: expose call modes
  OwnershipAnalysis->>Codegen: schedule ownership-based frees
  Codegen->>Codegen: handle borrowed-scalar free targets
Loading

Possibly related PRs

  • ryolang/ryo#79: Related move-parameter handling, ownership tracking, diagnostics, and call-site move/borrow modeling.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main refactor around Milestone 8.2 borrow liveness and ownership-pass changes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/m8.2-implicit-borrow-liveness

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
docs/dev/implementation_roadmap.md (3)

3391-3398: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add the required References footer.

This docs/dev document ends without a References section containing Spec, Dev, and Milestone links.

As per coding guidelines, every docs/dev/**/*.md file must include a “References” footer with entries for Spec, Dev, and Milestone when applicable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/dev/implementation_roadmap.md` around lines 3391 - 3398, Add a
References footer to implementation_roadmap.md after the existing closing
content, including the required Spec, Dev, and Milestone links using the
document’s applicable project references and standard documentation format.

Source: Coding guidelines


2117-2141: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix the fenced Ryo example’s syntax and indentation.

The if n <= 1 line is missing its colon, and the example uses spaces instead of the required tab indentation, so it is not a valid copyable Ryo example.

Proposed documentation fix
-    if n <= 1
-        return 1
+	if n <= 1:
+		return 1

As per coding guidelines, docs/**/*.md code examples must follow root CLAUDE.md with Python-style colons and tab indentation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/dev/implementation_roadmap.md` around lines 2117 - 2141, Update the
fenced Ryo example containing factorial and its tests: add the required colon to
the if n <= 1 statement and convert all indentation within the code block from
spaces to tabs, preserving the example’s behavior and structure.

Source: Coding guidelines


888-894: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Reconcile the documented range() arities.

This roadmap says both range(end) and range(start, end) are supported, while ISSUES.md I-040 still says only the two-argument form is supported. Align the two documents with the implemented parser behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/dev/implementation_roadmap.md` around lines 888 - 894, Reconcile the
documented range() arities between implementation_roadmap.md and ISSUES.md
I-040. Inspect the parser behavior to determine the implemented supported forms,
then update both documents consistently to describe only those forms and their
loop-header-only usage.
ryo-backend/src/codegen.rs (1)

1394-1435: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Scalar targets should not be debug-only. This branch is documented as an ownership-pass bug, but debug_assert! disappears in release builds, so a bad schedule can be skipped without any diagnostic there. Keep the check unconditional or return Err if you want the invariant enforced outside debug builds.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ryo-backend/src/codegen.rs` around lines 1394 - 1435, Make the Scalar branch
in emit_frees enforce the ownership invariant in all build modes instead of
relying on debug_assert!. Return an Err with the existing diagnostic context, or
otherwise perform an unconditional validation, and do not silently continue when
a borrowed-scalar target is scheduled for freeing.
ryo-driver/src/pipeline.rs (1)

237-247: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

E0023 is duplicated. DiagCode::MoveWhileBorrowedInCall reuses the same stable code already assigned to DiagCode::FloatModulo; use a different unused code so the diagnostics stay unique.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ryo-driver/src/pipeline.rs` around lines 237 - 247, Update the
diagnostic-code mapping near DiagCode::MoveWhileBorrowedInCall so it no longer
uses E0023, which is already assigned to DiagCode::FloatModulo. Assign a
different unused stable code and preserve uniqueness across all DiagCode
mappings.
ryo-frontend/src/ownership.rs (1)

24-113: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Move parameters still need a free path

Owner::Param is excluded from every free-scheduling pass, and pending_dead_store is only populated for VarDecl/Assign. A move parameter that is never consumed — or only consumed on some branches — ends the function in Valid state with no scheduled Free, so the callee leaks the transferred allocation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ryo-frontend/src/ownership.rs` around lines 24 - 113, Add function-end free
scheduling for unconsumed move parameters represented by Owner::Param, including
parameters consumed only on some control-flow branches. Update the ownership
finalization logic rather than relying solely on pending_dead_store, and
schedule a Free only for paths where the parameter remains Valid, avoiding
duplicate frees for Moved parameters.
🧹 Nitpick comments (2)
docs/dev/implementation_roadmap.md (1)

864-865: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Use ATX syntax for this changed heading.

The changed setext-style heading is flagged by markdownlint (MD003). Convert it to an equivalent #/## heading while preserving its level.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/dev/implementation_roadmap.md` around lines 864 - 865, Convert the
changed setext-style heading in the milestone validation section to equivalent
ATX heading syntax, preserving its current heading level and text.

Source: Linters/SAST tools

ryo-core/src/tir.rs (1)

568-594: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Consider assert_eq! instead of debug_assert_eq! for the modes/args length invariant.

debug_assert_eq! is compiled out in release/optimized builds by default. If a future caller ever violates modes.len() == args.len() in a release build, len here is still computed as call_extra::ARGS + 2 * args.len() — i.e. from args.len(), not from however many mode words were actually pushed. The declared ExtraRange would then overrun into whatever gets appended to self.extra next, silently corrupting the decode of a subsequent instruction rather than failing loudly. All current callers (sema.rs) already size modes correctly, so this is latent rather than actively triggered, but for a foundational, pub encoding primitive this seems worth hardening unconditionally.

♻️ Proposed hardening
-        debug_assert_eq!(
-            modes.len(),
-            args.len(),
-            "TirBuilder::call: one ParamMode per arg"
-        );
+        assert_eq!(
+            modes.len(),
+            args.len(),
+            "TirBuilder::call: one ParamMode per arg"
+        );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ryo-core/src/tir.rs` around lines 568 - 594, Replace the debug-only
modes/args length check in TirBuilder::call with an unconditional assert_eq! so
the invariant is enforced in release builds before encoding the call extra data.
Keep the existing length calculation and argument/mode serialization unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/dev/implementation_roadmap.md`:
- Around line 1155-1165: Add Milestone 8.3 to the Dependencies list for the
milestone documenting the explicit &str borrow example, preserving the existing
M8.2 dependency and accurately reflecting the use of explicit & syntax in
first_word(&s).
- Around line 1674-1676: Update the Milestone 21 goal text so it does not claim
string slices shipped; describe `&str` as planned in M8.4, or consistently
update the earlier M8.4 status if it is actually complete.
- Around line 2273-2297: The v0.1 roadmap example uses deferred `catch` and
f-string syntax. Update the `main` example to handle `find_user(42)` with
v0.1-supported `match` and build the greeting with string concatenation,
preserving the demonstrated optional handling and error result.
- Around line 1059-1072: Update the consume_and_print example so its first
parameter is explicitly move-mode or otherwise owning, while keeping the second
parameter borrowing. Ensure the main call consume_and_print(msg, msg) accurately
demonstrates E0023 by moving msg into the first argument while it is still
implicitly borrowed for the second.

---

Outside diff comments:
In `@docs/dev/implementation_roadmap.md`:
- Around line 3391-3398: Add a References footer to implementation_roadmap.md
after the existing closing content, including the required Spec, Dev, and
Milestone links using the document’s applicable project references and standard
documentation format.
- Around line 2117-2141: Update the fenced Ryo example containing factorial and
its tests: add the required colon to the if n <= 1 statement and convert all
indentation within the code block from spaces to tabs, preserving the example’s
behavior and structure.
- Around line 888-894: Reconcile the documented range() arities between
implementation_roadmap.md and ISSUES.md I-040. Inspect the parser behavior to
determine the implemented supported forms, then update both documents
consistently to describe only those forms and their loop-header-only usage.

In `@ryo-backend/src/codegen.rs`:
- Around line 1394-1435: Make the Scalar branch in emit_frees enforce the
ownership invariant in all build modes instead of relying on debug_assert!.
Return an Err with the existing diagnostic context, or otherwise perform an
unconditional validation, and do not silently continue when a borrowed-scalar
target is scheduled for freeing.

In `@ryo-driver/src/pipeline.rs`:
- Around line 237-247: Update the diagnostic-code mapping near
DiagCode::MoveWhileBorrowedInCall so it no longer uses E0023, which is already
assigned to DiagCode::FloatModulo. Assign a different unused stable code and
preserve uniqueness across all DiagCode mappings.

In `@ryo-frontend/src/ownership.rs`:
- Around line 24-113: Add function-end free scheduling for unconsumed move
parameters represented by Owner::Param, including parameters consumed only on
some control-flow branches. Update the ownership finalization logic rather than
relying solely on pending_dead_store, and schedule a Free only for paths where
the parameter remains Valid, avoiding duplicate frees for Moved parameters.

---

Nitpick comments:
In `@docs/dev/implementation_roadmap.md`:
- Around line 864-865: Convert the changed setext-style heading in the milestone
validation section to equivalent ATX heading syntax, preserving its current
heading level and text.

In `@ryo-core/src/tir.rs`:
- Around line 568-594: Replace the debug-only modes/args length check in
TirBuilder::call with an unconditional assert_eq! so the invariant is enforced
in release builds before encoding the call extra data. Keep the existing length
calculation and argument/mode serialization unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fe676e5c-2166-406d-888e-0329c6c92b7c

📥 Commits

Reviewing files that changed from the base of the PR and between ab521aa and a57e20a.

📒 Files selected for processing (9)
  • ISSUES.md
  • docs/dev/implementation_roadmap.md
  • ryo-backend/src/codegen.rs
  • ryo-core/src/diag.rs
  • ryo-core/src/tir.rs
  • ryo-driver/src/pipeline.rs
  • ryo-frontend/src/builtins.rs
  • ryo-frontend/src/ownership.rs
  • ryo-frontend/src/sema.rs

Comment thread docs/dev/implementation_roadmap.md Outdated
Comment thread docs/dev/implementation_roadmap.md Outdated
Comment thread docs/dev/implementation_roadmap.md Outdated
Comment thread docs/dev/implementation_roadmap.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ryo-backend/src/codegen.rs (1)

1410-1413: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update the documentation to reflect the new error behavior.

The doc comment explicitly claims that a Scalar-cached target "trips a debug_assert! and is skipped rather than aborting codegen". However, the code below was changed to return an Err(...), which aborts compilation. Please update the documentation to match the current abort behavior.

📝 Proposed fix for the doc comment
     /// each index as fired in `ctx.freed_at`. A `Scalar`-cached target
-    /// (borrowed-scalar ABI, never heap-owned) trips a `debug_assert!` and
-    /// is skipped rather than aborting codegen — the ABI registry is
+    /// (borrowed-scalar ABI, never heap-owned) returns an `Err` and aborts
+    /// codegen — the ABI registry is
     /// supposed to keep such args out of `temp_owners`. See I-057/I-059.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ryo-backend/src/codegen.rs` around lines 1410 - 1413, Update the doc comment
immediately above the affected code to state that encountering a Scalar-cached
target returns an error and aborts code generation, rather than triggering a
debug assertion and being skipped. Preserve the existing ABI registry context
and references while removing the inaccurate skip behavior description.
🧹 Nitpick comments (1)
ryo-backend/src/codegen.rs (1)

521-521: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Encapsulate the parameter TirRef mapping. u32::MAX - idx as u32 is a hidden convention here; a dedicated helper such as TirRef::param(idx) would make the ownership/codegen contract explicit and reduce the chance of divergence.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ryo-backend/src/codegen.rs` at line 521, Encapsulate the parameter reference
mapping used in the codegen path by adding or reusing a dedicated TirRef helper
such as TirRef::param, and replace the inline u32::MAX - idx as u32 construction
in the virtual_ref assignment with that helper. Keep the resulting parameter
mapping unchanged while making the convention explicit.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@ryo-backend/src/codegen.rs`:
- Around line 1410-1413: Update the doc comment immediately above the affected
code to state that encountering a Scalar-cached target returns an error and
aborts code generation, rather than triggering a debug assertion and being
skipped. Preserve the existing ABI registry context and references while
removing the inaccurate skip behavior description.

---

Nitpick comments:
In `@ryo-backend/src/codegen.rs`:
- Line 521: Encapsulate the parameter reference mapping used in the codegen path
by adding or reusing a dedicated TirRef helper such as TirRef::param, and
replace the inline u32::MAX - idx as u32 construction in the virtual_ref
assignment with that helper. Keep the resulting parameter mapping unchanged
while making the convention explicit.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 458a5500-11fe-46ca-a905-c8e4e51d26dd

📥 Commits

Reviewing files that changed from the base of the PR and between a57e20a and 2b25164.

📒 Files selected for processing (5)
  • docs/dev/implementation_roadmap.md
  • ryo-backend/src/codegen.rs
  • ryo-core/src/tir.rs
  • ryo-driver/src/pipeline.rs
  • ryo-frontend/src/ownership.rs
🚧 Files skipped from review as they are similar to previous changes (4)
  • ryo-driver/src/pipeline.rs
  • ryo-core/src/tir.rs
  • docs/dev/implementation_roadmap.md
  • ryo-frontend/src/ownership.rs

@artefactop
artefactop force-pushed the feat/m8.2-implicit-borrow-liveness branch from 6b5c7f3 to 57db0fd Compare July 14, 2026 17:53
@artefactop
artefactop merged commit fc35925 into main Jul 14, 2026
8 checks passed
@artefactop
artefactop deleted the feat/m8.2-implicit-borrow-liveness branch July 14, 2026 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant