fix(parser): "for each <TYPE> card <verb> this way" counts only that card type#4703
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements parsing for the ' card this way' clause (e.g., 'creature card put into a graveyard this way') to support CR 608.2c and CR 400.7. It introduces the parse_filtered_tracked_set_this_way helper function using nom combinators, integrates it into the 'for each' clause parser, and adds corresponding unit tests. No review comments were provided, and the implementation adheres to the repository's architectural guidelines, so there is no feedback to provide.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
…card type Dread Summons (phase-rs#4697) — "Each player mills X cards. For each creature card put into a graveyard this way, you create a … Zombie" — created a Zombie for EVERY milled card, not just creature cards. `parse_for_each_clause` recognized the tracked-set "this way" count but dropped the "creature" card-type filter, yielding the unfiltered `QuantityRef::TrackedSetSize`. Add `parse_filtered_tracked_set_this_way`, tried right before the bare `TrackedSetSize` fallback (mirroring the existing `parse_filtered_revealed_this_ way` / `parse_filtered_destroyed_this_way` helpers): a "<TYPE> card <verb> this way" clause with a SPECIFIC card type routes to the already-runtime-supported `QuantityRef::FilteredTrackedSetSize { filter, caused_by: None }`, which counts only the matching members of the most recent tracked set. A bare "card" (or a typeless clause) returns `None` and keeps `TrackedSetSize`. Covers the whole "for each <filter> card <verb> this way" class (creature / land / artifact / … put into a graveyard / milled / exiled). No new engine variant. CR 608.2c (anaphoric tracked set) + CR 400.7 (filtered subset). Tests: "creature card put into a graveyard this way" → FilteredTrackedSetSize (Creature); bare "card put into a graveyard this way" → TrackedSetSize (regression). fmt + clippy + parser combinator gate clean; 204 oracle_quantity + 2308 oracle_effect + 116 token-effect tests green (nonland-discarded / milled / destroyed cause-filtered paths intact). Closes phase-rs#4697 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Parse changes introduced by this PR · 22 card(s), 17 signature(s) (baseline: main
|
matthewevans
left a comment
There was a problem hiding this comment.
Maintainer review: passes the authorized review bar at head 383d737892e51265794e444156dfb2a1a2ddda88.
Closes #4697.
Bug: Dread Summons — "Each player mills X cards. For each creature card put into a graveyard this way, you create a … Zombie" — created a Zombie for every milled card, not just creature cards.
parse_for_each_clauserecognized the tracked-set "this way" count but dropped the "creature" card-type filter, yielding the unfilteredQuantityRef::TrackedSetSize.Fix: add
parse_filtered_tracked_set_this_way, tried right before the bareTrackedSetSizefallback (mirroring the existingparse_filtered_revealed_this_way/parse_filtered_destroyed_this_wayhelpers): a"<TYPE> card <verb> this way"clause with a specific card type routes to the already-runtime-supportedQuantityRef::FilteredTrackedSetSize { filter, caused_by: None }, which counts only the matching members of the most recent tracked set. A bare"card"(or typeless clause) returnsNoneand keepsTrackedSetSize. Covers the whole "for each ⟨filter⟩ card ⟨verb⟩ this way" class (creature / land / artifact / … put into a graveyard / milled / exiled). No new engine variant.CR 608.2c + CR 400.7.
Tests: "creature card put into a graveyard this way" →
FilteredTrackedSetSize(Creature); bare "card …" →TrackedSetSize(regression).cargo fmt+clippy+ parser combinator gate clean; 204 oracle_quantity + 2308 oracle_effect + 116 token-effect tests green (nonland-discarded / milled / destroyed cause-filtered paths intact).🤖 Generated with Claude Code