Skip to content

refactor(parser): route Frozen-in-Ice replacement through IR lowering (05b tranche 2) - #6328

Merged
matthewevans merged 1 commit into
mainfrom
ship/p05b-tranche-2-replacement-ir
Jul 22, 2026
Merged

refactor(parser): route Frozen-in-Ice replacement through IR lowering (05b tranche 2)#6328
matthewevans merged 1 commit into
mainfrom
ship/p05b-tranche-2-replacement-ir

Conversation

@matthewevans

@matthewevans matthewevans commented Jul 22, 2026

Copy link
Copy Markdown
Member

Plan 05b — Tranche 2: Frozen-in-Ice replacement → IR lowering

Routes the single try_split_and_cant_become_untapped replacement producer (Frozen-in-Ice
class) from the legacy DocEmitter::replacement_at through the IR path, via a new
ReplacementIr::from_definition(source_text, definition) seam and DocEmitter::replacement_ir_at.

Behavioral no-op: pure routing, no new parsing logic. replacement_ir_at emits only —
unlike static_at, replacement_at never maintained a last_* peek. execute_ir: None
mirrors StaticIr's body_ir: None (the untap-prevention replacement has no execute body).
The IR Replacement node is already a live lowered path (tranche 1's compound-static path
emits it), so this routes one more producer into a proven node type.

Correctness evidence

  • Byte-identity: full-pool card-data.json regen is sha256-identical to baseline (b6c79b7a…).
  • Snapshots: zero churn — no IR snapshot test covers this path.
  • Gates: clippy -D warnings clean; engine lib 17,479 passed / 0 failed; integration 3,702 / 0.

Scope guard: the two out-of-scope replacement_at sites (drain_result_vectors, ETB) are
untouched — they belong to later tranches. Second of the 05b tranches feeding the Plan-05
gate-1 zero-hit ratchet.

Summary by CodeRabbit

  • Bug Fixes
    • Improved parsing of continuous grants or restrictions that prevent permanents from becoming untapped.
    • Ensured replacement effects are consistently represented and applied during rules processing.

…ering (05b T2 row 51)

Adds ReplacementIr::from_definition (execute_ir: None, mirroring StaticIr's
body_ir: None) and DocEmitter::replacement_ir_at (emit-only; replacement_at
never maintained a last_* peek). Routes the single try_split_and_cant_become_untapped
replacement producer (Frozen-in-Ice class) through OracleNodeIr::Replacement.

Behavioral no-op: full-pool card-data.json regen is byte-identical to baseline
(sha256 b6c79b7a…); no IR snapshot test covers this path (0 churn); engine lib
17479 passed. The IR Replacement node is already a live lowered path (tranche 1's
compound-static path emits it). Out-of-scope replacement_at sites (drain, ETB) untouched.
@matthewevans
matthewevans enabled auto-merge July 22, 2026 07:55
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f25dcba0-24c3-4392-9f1e-0bff0cef02fd

📥 Commits

Reviewing files that changed from the base of the PR and between 67dbf2d and 36d19d6.

📒 Files selected for processing (2)
  • crates/engine/src/parser/oracle.rs
  • crates/engine/src/parser/oracle_ir/replacement.rs

📝 Walkthrough

Walkthrough

The Oracle parser adds a ReplacementIr constructor and a DocEmitter helper for direct replacement IR emission. The cross-layer “can’t become untapped” handling now uses this path with the current source line as context.

Changes

Oracle replacement IR emission

Layer / File(s) Summary
Construct and emit replacement IR
crates/engine/src/parser/oracle_ir/replacement.rs, crates/engine/src/parser/oracle.rs
ReplacementIr::from_definition wraps a replacement definition with source text and no effect-chain body; DocEmitter::replacement_ir_at emits it, and the untap-prevention parser path uses both helpers.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: carlos4s

🚥 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 routing of the Frozen-in-Ice replacement through IR lowering, which matches the main change.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ship/p05b-tranche-2-replacement-ir

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

@matthewevans
matthewevans added this pull request to the merge queue Jul 22, 2026
@github-actions

Copy link
Copy Markdown

Parse changes introduced by this PR

✓ No card-parse changes detected.

Merged via the queue into main with commit f77fcfb Jul 22, 2026
15 checks passed
@matthewevans
matthewevans deleted the ship/p05b-tranche-2-replacement-ir branch July 22, 2026 08:35
jsdevninja pushed a commit to jsdevninja/phase that referenced this pull request Jul 24, 2026
…ering (05b T2 row 51) (phase-rs#6328)

Adds ReplacementIr::from_definition (execute_ir: None, mirroring StaticIr's
body_ir: None) and DocEmitter::replacement_ir_at (emit-only; replacement_at
never maintained a last_* peek). Routes the single try_split_and_cant_become_untapped
replacement producer (Frozen-in-Ice class) through OracleNodeIr::Replacement.

Behavioral no-op: full-pool card-data.json regen is byte-identical to baseline
(sha256 b6c79b7a…); no IR snapshot test covers this path (0 churn); engine lib
17479 passed. The IR Replacement node is already a live lowered path (tranche 1's
compound-static path emits it). Out-of-scope replacement_at sites (drain, ETB) untouched.

Co-authored-by: matthewevans <matthewevans@users.noreply.github.com>
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