fix(parser): accept U+2019 apostrophe in "unless they're mana abilities" exemption (Pithing Needle, Bound by Moonsilver)#5000
Conversation
…es" exemption MTGJSON oracle text uses the typographic apostrophe (U+2019). The "can't be activated" predicate already accepts both apostrophe forms (shared.rs / evasion.rs), but the trailing "unless they're mana abilities" exemption suffix was straight-apostrophe only, so a U+2019 printing (Pithing Needle, Bound by Moonsilver, and every aura templated "...its activated abilities can't be activated unless they're mana abilities") silently dropped the exemption. The static was built with ActivationExemption::None and the runtime then wrongly blocked the permanent's mana abilities (CR 605.1a violation). Add the U+2019 branch to both exemption-suffix parse sites (parse_activation_exemption_suffix, parse_activation_compound_tail), mirroring the dual-apostrophe pattern already used for the adjacent predicate. Building-block test drives the suffix combinator with both apostrophe forms.
|
Holding review for the current head until the parse-diff evidence is available. This PR changes engine parser code, so I need the |
There was a problem hiding this comment.
Code Review
This pull request updates the static oracle parsers in restriction.rs and shared.rs to support both straight apostrophes and typographic apostrophes (U+2019) in the "unless they're" exemption suffix. This ensures that MTGJSON oracle text containing typographic apostrophes is parsed correctly, preventing exemptions (such as "unless they're mana abilities") from being silently dropped. Unit tests have been added to verify the correct parsing of both apostrophe forms. No review comments were provided, and the changes are fully compliant with the repository's style guide, so there is no additional 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.
|
Holding current head This is still an engine parser PR, and the |
Parse changes introduced by this PRBaseline pending for |
|
Holding current head The current Please update/retrigger the branch so the sticky parse-diff reflects this PR's actual scope, or explain why those unrelated card deltas are expected here. I can't approve a parser PR while the card-level blast-radius evidence is unrelated to the implementation under review. |
matthewevans
left a comment
There was a problem hiding this comment.
[MED] U+2019 suffix support is still behind ASCII-only activation gates. Evidence: crates/engine/src/parser/oracle_static/restriction.rs still requires the ASCII can't be activated phrase before reaching the widened exemption suffix parser, and crates/engine/src/parser/oracle_static/shared.rs still has an ASCII-only scan for activated abilities can't be activated; the new test only exercises the suffix helper. Why it matters: a full production phrase with typographic can’t ... they’re still will not reach the widened suffix parser. Suggested fix: factor/reuse a dual-apostrophe activation-predicate parser across chosen-name, compound, self-ref/scan, and exemption-scanner paths, and add production parse_static_line / parse_static_line_multi tests for full U+2019 lines.
[MED] The parse-diff evidence is still not trustworthy for this PR scope. Evidence: the current coverage-parse-diff sticky reports Drizzt Do’Urden / Conformer Shuriken changes even though this PR only touches activation-restriction parser files, and prior maintainer feedback already flagged that mismatch for this same head. Why it matters: parser PRs need card-level blast-radius evidence tied to the actual implementation before approval/enqueue. Suggested fix: update/retrigger the branch so the sticky reflects this PR’s real parser deltas, or explain why those unrelated card diffs are actually caused by this PR.
Summary
Fixes #4999. The CR 605.1a exemption suffix "unless they're mana abilities" was parsed with the straight ASCII apostrophe only. MTGJSON oracle text uses the typographic apostrophe (U+2019), so a U+2019 printing silently dropped the exemption — the static was built with
ActivationExemption::Noneand the runtime then wrongly blocked the permanent's mana abilities (a rules violation, not just a coverage miss).The adjacent
can't be activatedpredicate already accepts both apostrophe forms; only the exemption suffix was missing the U+2019 branch. This restores parity.Covers a class (every aura/effect templated
…can't be activated unless they're mana abilities), not one card.Affected cards: Pithing Needle, Bound by Moonsilver, Faith's Fetters / Kenrith's Transformation–shaped auras.
Files changed
crates/engine/src/parser/oracle_static/restriction.rs—parse_activation_exemption_suffix:tag(" unless they're ")→alt((tag(" unless they're "), tag(" unless they\u{2019}re "))). Building-block test module added.crates/engine/src/parser/oracle_static/shared.rs—parse_activation_compound_tail: same dual-apostrophe branch on the compound-tail suffix.CR references added/touched
CR 605.1a— mana abilities are defined as a subclass of activated abilities; a "can't be activated" static that carves out "unless they're mana abilities" must leave mana abilities activatable.Track
Non-developer — no local Rust toolchain in this environment, so local
cargoverification was not run. CI runsclippy,test-engine,card-data, and the combinator-purity gate on this PR.LLM
Gate A — nom combinators
Not run locally (no toolchain). Pure-combinator by construction: the change only widens an existing
tag()into a two-branchalt()oftag()s at two sites; nofind/split_once/contains/starts_withor verbatim Oracle-text match introduced. CI's combinator-purity script is authoritative.Gate B — pattern anchoring
The exact dual-apostrophe pattern this PR adds is already used in-tree for the adjacent predicate:
crates/engine/src/parser/oracle_static/shared.rs:693-694—alt((tag("activated abilities can't be activated"), tag("activated abilities can\u{2019}t be activated"))).crates/engine/src/parser/oracle_static/evasion.rs:1204-1205— same dual-apostrophe pair (comment: "the ASCII / U+2019 apostrophe form").Additional precedent for per-tag apostrophe handling:
crates/engine/src/parser/oracle.rs:885-886(can't/can\u{2019}t). There is no global apostrophe normalization in the pipeline (only−/–→-atoracle.rs), which is why these dual-apostrophe branches exist and why the missing suffix branch is a live bug.Scope expansion
None.
Validation failures
None.
CI failures
None.
Tier: Standard