Skip to content

feat(tribute-passes): implement arena-based evidence passes (#442)#463

Open
Kroisse wants to merge 5 commits intomainfrom
feature/arena-evidence-passes
Open

feat(tribute-passes): implement arena-based evidence passes (#442)#463
Kroisse wants to merge 5 commits intomainfrom
feature/arena-evidence-passes

Conversation

@Kroisse
Copy link
Owner

@Kroisse Kroisse commented Feb 27, 2026

Summary

Ports add_evidence_params and transform_evidence_calls to the arena IR via the Salsa-Arena bridge pattern, closing #442 ("Port Evidence Passes to Arena IR") in the "Bridge & Shared Pass Migration" milestone.

  • trunk-ir: Add prepend_block_arg to IrContext — inserts a new block argument at position 0, shifting all existing arg indices and updating their uses via RAUW
  • tribute-ir: Add arena type helpers to the ability dialect — marker_adt_type_ref, evidence_adt_type_ref, is_marker_type_ref, is_evidence_type_ref (mirrors the Salsa versions)
  • tribute-passes: Implement arena_add_evidence_params and arena_transform_evidence_calls in evidence::arena; update the Salsa entry points (add_evidence_params, transform_evidence_calls) to bridge into arena IR via import_salsa_module/export_to_salsa, run the arena passes, and bridge back; remove the old Salsa pattern-based implementations (AddEvidenceParamPattern, TransformCallsPattern); add unit and integration tests for all new arena functionality

Test plan

  • Unit tests for prepend_block_arg in crates/trunk-ir/src/arena/context.rs
  • Unit tests for arena ability type helpers (marker_adt_type_ref, evidence_adt_type_ref, is_marker_type_ref, is_evidence_type_ref) in crates/tribute-ir/src/arena/dialect/ability.rs
  • Unit tests for is_effectful_type_arena helper
  • Integration tests for the full arena evidence pipeline (arena_add_evidence_params + arena_transform_evidence_calls)
  • All 1428 workspace tests pass (cargo nextest run --workspace)
  • Clippy clean

Closes #442

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Refactor

    • Evidence processing moved to an arena-backed pipeline with bridged staging and updated public exports.
    • Public API surface adjusted to favor arena entry points; pipeline stages now skip work when no effectful functions exist.
    • Added ability-related ADT helpers and a safe block-argument prepend operation.
  • Tests

    • Added coverage for ability types, evidence pipeline (including idempotency and call-site updates), block-arg prepend, and deduplication/integration.

Migrate `add_evidence_params` and `transform_evidence_calls` to the
arena IR via the Salsa-Arena bridge pattern, as part of the
"Bridge & Shared Pass Migration" milestone.

- `trunk-ir`: add `prepend_block_arg` method to `IrContext` for
  inserting a block argument at position 0
- `tribute-ir`: add arena type helpers to the ability dialect —
  `marker_adt_type_ref`, `evidence_adt_type_ref`, `is_marker_type_ref`,
  and `is_evidence_type_ref`
- `tribute-passes`: implement `arena_add_evidence_params` and
  `arena_transform_evidence_calls` in `evidence::arena`; update the
  Salsa entry points to bridge into arena IR, run the arena passes, and
  bridge back; remove the old Salsa pattern-based implementations;
  add tests for all new arena functionality

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 27, 2026

📝 Walkthrough

Walkthrough

Ports evidence insertion to arena IR: adds arena ability ADT helpers, ports evidence passes to operate on ArenaModule with Salsa↔Arena bridging, updates pipeline to invoke arena passes, and adds IrContext::prepend_block_arg for block-arg prepends.

Changes

Cohort / File(s) Summary
Ability Dialect Arena Helpers
crates/tribute-ir/src/arena/dialect/ability.rs
Add ADT helpers and predicates: marker_adt_type_ref, evidence_adt_type_ref, is_marker_type_ref, is_evidence_type_ref and tests for creation, detection, and deduplication.
Evidence Pass Arena Migration
crates/tribute-passes/src/evidence.rs
Replace pattern-based evidence passes with pub mod arena: arena helpers (is_effectful_type_arena, collect_*_arena), arena_add_evidence_params, arena_transform_evidence_calls, build_func_type_with_evidence; remove legacy pattern exports and add arena-centric tests and test utilities.
Pipeline wiring (Salsa↔Arena bridge)
src/pipeline.rs
Bridge to Salsa↔Arena: import/export module, early-exit checks, and calls to arena_add_evidence_params and arena_transform_evidence_calls; adjust imports and stage flow.
Arena Context Block Arg API
crates/trunk-ir/src/arena/context.rs
Add IrContext::prepend_block_arg(block, arg) -> ValueRef to insert a block argument at index 0 and shift existing block-arg indices; includes tests for empty and non-empty blocks.
Public re-exports updated
crates/tribute-passes/src/lib.rs
Update public re-exports: remove legacy add_evidence_params, insert_evidence, transform_evidence_calls; export collect_functions_with_evidence_param (arena-aligned).

Sequence Diagram(s)

sequenceDiagram
  participant Pipeline as Pipeline
  participant SalsaDB as Salsa DB
  participant Bridge as Salsa↔Arena Bridge
  participant ArenaMod as ArenaModule
  participant ArenaPass as Arena Evidence Passes

  Pipeline->>SalsaDB: hold core Module
  Pipeline->>Bridge: import_salsa_module(Module)
  Bridge->>ArenaMod: create ArenaModule
  Pipeline->>ArenaPass: arena_add_evidence_params(ArenaModule)
  ArenaPass->>ArenaMod: mutate module (add evidence params)
  Pipeline->>Bridge: export_to_salsa(ArenaModule)
  Bridge->>SalsaDB: produce modified Module'
  alt evidence call transforms required
    Pipeline->>Bridge: import_salsa_module(Module')
    Bridge->>ArenaMod: create ArenaModule
    Pipeline->>ArenaPass: arena_transform_evidence_calls(ArenaModule)
    ArenaPass->>ArenaMod: mutate module (transform calls)
    Pipeline->>Bridge: export_to_salsa(ArenaModule)
    Bridge->>SalsaDB: produce Module''
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related issues

  • #441 — Salsa↔Arena bridge integration: pipeline changes use the import/export bridge referenced in the issue.
  • #443 — Port evidence passes to arena IR: changes port evidence resolution/insertion logic to arena and add arena helpers.

Possibly related PRs

Poem

🐇 I shaped a Marker, tiny, bright and neat,
Wove Evidence arrays to make the passes meet.
I nudged block args forward, shifted every lane,
Bridged Salsa to Arena, then hopped off to grain.
Code carrots crunch — a rabbit's quiet byte-sized feat.

🚥 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 describes the main change: implementing arena-based evidence passes, which is the core objective of this PR.
Linked Issues check ✅ Passed All acceptance criteria from #442 are met: arena_add_evidence_params and arena_transform_evidence_calls implemented, evidence tests passing, and pipeline integration via bridge pattern completed.
Out of Scope Changes check ✅ Passed All changes are directly related to porting evidence passes to arena IR. No unrelated modifications detected outside the stated objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/arena-evidence-passes

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

@codecov
Copy link

codecov bot commented Feb 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.65%. Comparing base (d9feb84) to head (68b7f37).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #463      +/-   ##
==========================================
+ Coverage   78.54%   78.65%   +0.11%     
==========================================
  Files          10       10              
  Lines        4935     4947      +12     
==========================================
+ Hits         3876     3891      +15     
+ Misses       1059     1056       -3     
Components Coverage Δ
TrunkIR ∅ <ø> (∅)
Frontend ∅ <ø> (∅)
Middle End ∅ <ø> (∅)
Driver 78.65% <100.00%> (+0.11%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Kroisse Kroisse self-assigned this Feb 27, 2026
Kroisse and others added 2 commits February 27, 2026 19:01
….rs to pipeline.rs

Keep evidence.rs as a pure arena pass library with no Salsa bridging.
pipeline.rs now owns all import_salsa_module/export_to_salsa calls,
early-exit checks, and the stage_evidence_params/stage_evidence_calls
wrappers, matching the pattern used by other pipeline stages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The legacy combined evidence pass had no callers after the pipeline
was split into stage_evidence_params and stage_evidence_calls.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/tribute-passes/src/evidence.rs`:
- Around line 309-331: The code currently skips pure functions and also assumes
an evidence first-arg when it may be absent, risking silent corruption; change
the logic so you always traverse function bodies (remove the early continue that
skips pure functions) but only attempt to extract ev_value and call
transform_calls_in_region when has_evidence_first_param(ctx, func_ty) is true;
additionally, if a function is marked in all_effectful but
has_evidence_first_param returns false (i.e., func_name ∈ all_effectful &&
!has_ev_param), fail fast by emitting an explicit error/diagnostic or returning
Err (rather than reading ctx.block_arg) to prevent silent rewrites — adjust the
block that computes is_explicitly_effectful, has_ev_param, ev_value and the call
to transform_calls_in_region accordingly using the symbols all_effectful,
has_evidence_first_param, func_op, body, entry_block, ev_value, and
transform_calls_in_region.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3dcb9f4 and 7668097.

📒 Files selected for processing (3)
  • crates/tribute-passes/src/evidence.rs
  • crates/tribute-passes/src/lib.rs
  • src/pipeline.rs

Remove the `pub mod arena { ... }` wrapper from `evidence.rs`, promoting
all arena functions and tests to the top level of the module. Merge arena
imports into the module-level use declarations, rename `mod arena_tests`
to `mod tests` (dropping the old Salsa-only tests), and rename the two
public arena pass functions:

- `arena::arena_add_evidence_params` → `add_evidence_params`
- `arena::arena_transform_evidence_calls` → `transform_evidence_calls`

Update call sites in `src/pipeline.rs` accordingly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
crates/tribute-passes/src/evidence.rs (1)

296-315: ⚠️ Potential issue | 🔴 Critical

Fail fast when an effectful function is missing the prepended evidence parameter.

At Line 300 onward, is_explicitly_effectful && !has_ev_param still reaches Line 315 and treats arg0 as evidence. That can silently rewrite calls with a non-evidence value if phase 1 was skipped/partial for any function.

🔧 Suggested guard
         if !is_explicitly_effectful && !has_ev_param {
             continue;
         }
+        assert!(
+            !is_explicitly_effectful || has_ev_param,
+            "transform_evidence_calls: `{}` is effectful but missing evidence param; run add_evidence_params first",
+            func_name
+        );

         // Get the evidence value from first block arg
         let body = func_op.body(ctx);
         let blocks = &ctx.region(body).blocks;
         if blocks.is_empty() {
             continue;
         }
         let entry_block = blocks[0];
         let block_args = ctx.block_args(entry_block);
-        if block_args.is_empty() {
-            continue;
-        }
+        assert!(
+            !block_args.is_empty(),
+            "transform_evidence_calls: expected entry block arg[0] evidence in `{}`",
+            func_name
+        );
         let ev_value = ctx.block_arg(entry_block, 0);

Based on learnings: when a pass depends on invariants established by earlier passes, prefer fail-fast instead of silent fallback.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/tribute-passes/src/evidence.rs` around lines 296 - 315, The code
currently proceeds to treat the first block argument as evidence even when
is_explicitly_effectful is true but has_ev_param is false; change this to
fail-fast: after computing is_explicitly_effectful and has_ev_param, detect the
case where is_explicitly_effectful && !has_ev_param and immediately surface a
hard failure (emit a diagnostic/error or return Err) including the function
identifier (func_name) so the pass cannot silently rewrite a non-evidence value
as ev_value; ensure this check is done before accessing body/block args (i.e.,
before using func_op, entry_block, ctx.block_arg).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@crates/tribute-passes/src/evidence.rs`:
- Around line 296-315: The code currently proceeds to treat the first block
argument as evidence even when is_explicitly_effectful is true but has_ev_param
is false; change this to fail-fast: after computing is_explicitly_effectful and
has_ev_param, detect the case where is_explicitly_effectful && !has_ev_param and
immediately surface a hard failure (emit a diagnostic/error or return Err)
including the function identifier (func_name) so the pass cannot silently
rewrite a non-evidence value as ev_value; ensure this check is done before
accessing body/block args (i.e., before using func_op, entry_block,
ctx.block_arg).

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7668097 and f731605.

📒 Files selected for processing (2)
  • crates/tribute-passes/src/evidence.rs
  • src/pipeline.rs

Replace manual op traversal and mutation in `add_evidence_params` and
`transform_evidence_calls` with `AddEvidenceParamPattern` and
`TransformEvidenceCallPattern` driven by `PatternApplicator`.

Add `find_enclosing_evidence` helper that walks the parent chain to
locate the evidence block argument, eliminating the need for the
recursive `transform_calls_in_region` / `transform_calls_in_block`
functions. Public API signatures are unchanged.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
crates/tribute-passes/src/evidence.rs (1)

338-340: ⚠️ Potential issue | 🟠 Major

Fail fast when an effectful call has no enclosing evidence context.

At Line 338, returning false silently skips rewriting a call that is known effectful (callee already matched), which can leave mismatched call signatures and defer the failure to later passes.

Suggested fix
-        let Some(ev_value) = find_enclosing_evidence(ctx, op) else {
-            return false;
-        };
+        let Some(ev_value) = find_enclosing_evidence(ctx, op) else {
+            panic!(
+                "transform_evidence_calls: effectful call to `{}` has no enclosing evidence arg; run add_evidence_params first",
+                callee
+            );
+        };

Based on learnings: when a pass relies on invariants established by a prior pass, prefer fail-fast over silent fallback.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/tribute-passes/src/evidence.rs` around lines 338 - 340, The code
silently returns false when find_enclosing_evidence(ctx, op) yields None, which
hides a violated invariant for effectful calls; change this to a fail-fast
error: replace the early "return false" in the block that reads "let
Some(ev_value) = find_enclosing_evidence(ctx, op) else { return false; }" with
an explicit panic/reporting call that includes the operation span and a clear
message (e.g., via panic!, span_bug!, or ctx's diagnostic API) so the pass fails
immediately when an effectful callee lacks an enclosing evidence context.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@crates/tribute-passes/src/evidence.rs`:
- Around line 338-340: The code silently returns false when
find_enclosing_evidence(ctx, op) yields None, which hides a violated invariant
for effectful calls; change this to a fail-fast error: replace the early "return
false" in the block that reads "let Some(ev_value) =
find_enclosing_evidence(ctx, op) else { return false; }" with an explicit
panic/reporting call that includes the operation span and a clear message (e.g.,
via panic!, span_bug!, or ctx's diagnostic API) so the pass fails immediately
when an effectful callee lacks an enclosing evidence context.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f731605 and 68b7f37.

📒 Files selected for processing (1)
  • crates/tribute-passes/src/evidence.rs

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.

Port evidence passes to arena IR

1 participant