feat(parser): anthem subject qualifiers "with a mana ability" / "with no abilities"#5452
Conversation
… no abilities"
An anthem subject phrase carrying a "with a mana ability" or "with no
abilities" object qualifier failed to parse: the qualifier was not
recognized by any subject-filter arm, so the whole static line fell
through to Effect::Unimplemented { name: "static_structure", .. } and no
continuous static was produced.
Strip the trailing qualifier in parse_continuous_subject_filter, parse
the base subject recursively, and attach the matching FilterProp. Both
properties are already fully evaluated at runtime by game::filter
(HasManaAbility via the authoritative mana-ability classifier,
HasNoAbilities via object_has_no_abilities), so this is a grammar-only
seam that reuses existing modeling. Placing it on the shared subject
filter covers every subject shape at once:
- Raggadragga, Goregutter "Each creature you control with a mana ability gets +2/+2."
- Muraganda Petroglyphs "Creatures with no abilities get +2/+2."
- Ruxa, Patient Professor "Creatures you control with no abilities get +1/+1."
The qualifier must sit at the very end of the subject phrase so a
mid-phrase "with ..." clause is not misclaimed.
There was a problem hiding this comment.
Code Review
This pull request adds support for parsing trailing subject qualifiers "with a mana ability" and "with no abilities" in continuous subject filters, mapping them to runtime-evaluated filter properties. It also introduces corresponding test cases. Feedback is provided regarding a potential UTF-8 slicing hazard where slicing tp.original using the byte length of the lowercased prefix base_lower can cause panics or character corruption if case conversion alters the byte length of any characters.
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.
Parse changes introduced by this PR · 1 card(s), 2 signature(s) (baseline: main
|
matthewevans
left a comment
There was a problem hiding this comment.
Approved after maintainer fixups. Evidence: current head 9478a74 is CI green; parse-diff refreshed against main 58fa4c7 and shows only Raggadragga gaining the intended continuous static and losing static_structure; Gemini's lower/original slicing concern was resolved by switching the qualifier parser to nom suffix parsing plus lower_subslice_to_original.
Problem
An anthem subject phrase carrying a "with a mana ability" or "with no abilities" object qualifier did not parse. No subject-filter arm recognized the qualifier, so the whole static line fell through to
Effect::Unimplemented { name: "static_structure", .. }and produced no continuous static.Affected real cards:
Each creature you control with a mana ability gets +2/+2.Creatures with no abilities get +2/+2.Creatures you control with no abilities get +1/+1.Fix
Strip the trailing qualifier in
parse_continuous_subject_filter, parse the base subject recursively, and attach the matchingFilterProp. Both properties are already fully evaluated at runtime bygame::filter(HasManaAbilityvia the authoritative mana-ability classifier;HasNoAbilitiesviaobject_has_no_abilities) — so this is a grammar-only seam that reuses existing modeling.Placing it on the shared subject-filter parser covers every subject shape at once — singular (
Each creature you control …), global (Creatures …), controller-scoped plural (Creatures you control …), and subtype (Elf creatures you control …). The qualifier must sit at the very end of the subject phrase (afterempty) so a mid-phrasewith …clause is not misclaimed.Tests
Three new
oracle_tests.rstests (Raggadragga / Ruxa / Muraganda) assert each line produces a continuous static — nostatic_structureUnimplemented — whose affected filter carries the expectedFilterProp.Regression:
parser::oraclemodule 7604 passed, 0 failed.cargo fmt, clippy (-D warnings), and the parser-combinator / engine-authorities gates are clean. The fix lands entirely inoracle_static/shared.rs.