fix(pest_bridge): colon member key misparsed as arrow key on => in value#618
Open
SebastienGllmt wants to merge 1 commit into
Open
fix(pest_bridge): colon member key misparsed as arrow key on => in value#618SebastienGllmt wants to merge 1 commit into
SebastienGllmt wants to merge 1 commit into
Conversation
SebastienGllmt
force-pushed
the
fix-bareword-member-key
branch
from
June 30, 2026 20:26
5ec4363 to
cad07c8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix: bareword (colon) member key mis-parsed as a type-1 (arrow) key when the entry value contains
=>Problem
In the Pest bridge, a colon-form member key (
name: type, RFC 8610 §3.5.1) is silently convertedinto an arrow-form type-1 member key (
type => type) whenever the surrounding group entry's textcontains the substring
=>anywhere — including inside the entry's value.bisMemberKey::Bareword— the text key"b", whose value is the string"=>".bisMemberKey::Type1— a type key namedb.There is no arrow member key anywhere in that entry; the only
=>is two characters inside a stringliteral. The same misfire happens for any entry whose value legitimately contains an arrow, e.g. a
nested map:
This matters because the two forms mean different things (RFC 8610 §3.5.1):
b: Tmatches a fixedfield whose key is the text
"b", whileb => Tmatches any key of typeb. Sincebis usuallynot a defined type, the misparse also turns a well-formed schema into one with an undefined type
reference. Any consumer that distinguishes text keys from type keys (validators, code generators) is
affected.
Root cause and relation to the Pest migration / #536
The grammar is not at fault — it disambiguates correctly. The defect is in the AST conversion,
which re-derives the arrow-vs-colon distinction from a raw substring scan of the whole entry instead
of reading the parse tree:
full_textspans the entire entry, so any=>in the value corrupts the classification.This heuristic is original to the Pest migration (
c3db585"refactor for Pest", finalized inRemove legacy lexer and parser code, complete migration to Pest #339), not new. The bug has existed since the first Pest-based release.
Allow any type1 as an arrow-style member key (RFC 8610 §3.5.1) #536 (
c214c23, "Allow any type1 as an arrow-style member key") is what makes the clean fixpossible. Before it,
member_keyhad notype1alternative, so a colon key and an arrow keyproduced the same child rule and the conversion had no structural signal to read — hence the
substring fallback. Allow any type1 as an arrow-style member key (RFC 8610 §3.5.1) #536 added a lookahead-gated
type1alternative:so a genuine arrow key now always carries a
Rule::type1child and a colon key never does. Allow any type1 as an arrow-style member key (RFC 8610 §3.5.1) #536already applied this principle to its new type-1 arrows (its
Rule::type1conversion arm ignoresthe substring flag), but deliberately left the legacy
bareword/typename/valuepath on the oldheuristic — which is the path that is buggy.
The fix
Decide arrow vs. colon structurally instead of substring checking or based on a boolean parameter to functions
Note: after #536, a
bareword/typename/valuechild ofmember_keycanonly occur in colon context (every arrow routes through the
type1alternative).This means the old
if is_arrow_map { …→Type1 }branches in those arms were unreachable dead code — they only everfired because the substring scan mis-set the flag. Therefore, the minimal correct change is therefore not to re-derive the flag, but to delete it
Conversion is now a pure function of the parse-tree shape, with no footgun left behind.
Other notes
_convert_member_key— an unused (no callers) function that carried the samefull_str.contains("=>")heuristic (keeping it as reference didn't feel like it made sense if it's wrong)Test plan
Added
test_bareword_colon_key_not_misparsed_as_arrowintests/grammar.rs. Existing member-keytests only asserted parse success and so could not catch a wrong variant; this one asserts the
member-key variant:
foo = { b: "=>" }bBareword(wasType1— the bug)foo = { b: { * uint => uint } }bBareword(wasType1— the bug)foo = { b: uint }bBarewordfoo = { 1: uint }1Valuefoo = { b => uint }bType1foo = { 1 => uint }1Type1foo = { b ^ => uint }bType1cargo test --libpasses (full default feature set);cargo fmtclean.