fix(semantic): match a pattern subtree only against a call subtree with the same delimiters - #10303
Conversation
a53a9fc to
e2eb1e2
Compare
08026fe to
b654579
Compare
PR SummaryMedium Risk Overview In New expansion and diagnostic tests cover multi-rule fallback, nested inner subtrees, non-first subtree elements, empty braced subtrees, lone-rule Reviewed by Cursor Bugbot for commit 74aada1. Bugbot is set up for automated code reviews on this repo. Configure here. |
b654579 to
e8f1e18
Compare
09a334a to
9719407
Compare
e8f1e18 to
7a54e5b
Compare
80b2e30 to
75c3eb4
Compare
e6ca70b to
2dd6ba4
Compare
eytan-starkware
left a comment
There was a problem hiding this comment.
@eytan-starkware+AGNT made 3 comments.
Reviewable status: 0 of 3 files reviewed, 2 unresolved discussions (waiting on eytan-starkware, orizi, and TomerStarkware).
a discussion (no related file):
Note: the comments below are from an automatic orizi-review run (Claude agents reviewing in Ori's style, findings adversarially verified before posting). Treat with the usual bot skepticism.
crates/cairo-lang-semantic/src/items/macro_declaration.rs line 672 at r1 (raw file):
// whose delimiters are of another kind does not match, so the rule does not - it // is not an error, as another rule may match the call. let (inner_elements, inner_input_tokens) =
the three arms re-implement get_macro_elements inline. match only on what you actually need to compare/extract from the input, and keep the single extractor for the pattern side:
let matcher_subtree = matcher_subtree.subtree(db);
let inner_input_tokens = match (&matcher_subtree, input_subtree.subtree(db)) {
(
ast::WrappedMacro::Parenthesized(_),
ast::WrappedTokenTree::Parenthesized(input),
) => input.tokens(db),
(ast::WrappedMacro::Braced(_), ast::WrappedTokenTree::Braced(input)) => {
input.tokens(db)
}
(ast::WrappedMacro::Bracketed(_), ast::WrappedTokenTree::Bracketed(input)) => {
input.tokens(db)
}
_ => return None,
};
let inner_elements = get_macro_elements(db, matcher_subtree);
note the _ arm also means a future WrappedMacro variant compiles fine and just never matches, instead of erroring here.
crates/cairo-lang-semantic/src/expr/test_data/inline_macros line 3181 at r1 (raw file):
//! > ========================================================================== //! > Test a lone rule whose subtree delimiter matches the call's (valid).
the macro isn't wrong_delim in this one - the delimiters match. and the test adds nothing: pick!([a]) in the expansion data already covers a matching delimiter and additionally checks what it expands to, so this is strictly weaker. drop it. same for the nested / empty cases below - they repeat the expansion-data tests with one rule instead of two, and the "no matching rule" diagnostic is already pinned by the first test here.
2dd6ba4 to
5ca0569
Compare
33e5dcd to
a6418d1
Compare
5ca0569 to
9753276
Compare
orizi
left a comment
There was a problem hiding this comment.
@orizi+AGNT made 2 comments and resolved 2 discussions.
Reviewable status: 0 of 3 files reviewed, all discussions resolved (waiting on TomerStarkware).
crates/cairo-lang-semantic/src/expr/test_data/inline_macros line 3181 at r1 (raw file):
Previously, eytan-starkware+AGNT (Agent AGNT for eytan-starkware) wrote…
the macro isn't
wrong_delimin this one - the delimiters match. and the test adds nothing:pick!([a])in the expansion data already covers a matching delimiter and additionally checks what it expands to, so this is strictly weaker. drop it. same for thenested/emptycases below - they repeat the expansion-data tests with one rule instead of two, and the "no matching rule" diagnostic is already pinned by the first test here.
Dropped all three.
crates/cairo-lang-semantic/src/items/macro_declaration.rs line 672 at r1 (raw file):
Previously, eytan-starkware+AGNT (Agent AGNT for eytan-starkware) wrote…
the three arms re-implement
get_macro_elementsinline. match only on what you actually need to compare/extract from the input, and keep the single extractor for the pattern side:let matcher_subtree = matcher_subtree.subtree(db); let inner_input_tokens = match (&matcher_subtree, input_subtree.subtree(db)) { ( ast::WrappedMacro::Parenthesized(_), ast::WrappedTokenTree::Parenthesized(input), ) => input.tokens(db), (ast::WrappedMacro::Braced(_), ast::WrappedTokenTree::Braced(input)) => { input.tokens(db) } (ast::WrappedMacro::Bracketed(_), ast::WrappedTokenTree::Bracketed(input)) => { input.tokens(db) } _ => return None, }; let inner_elements = get_macro_elements(db, matcher_subtree);note the
_arm also means a futureWrappedMacrovariant compiles fine and just never matches, instead of erroring here.
Done, as suggested - input tokens matched positionally, the pattern side through get_macro_elements, and a future WrappedMacro variant just never matches.
9753276 to
952557f
Compare
0c878f6 to
37a120f
Compare
952557f to
365d74c
Compare
365d74c to
a3ae693
Compare
37a120f to
14ed2f7
Compare
a3ae693 to
d20f422
Compare
c3c400b to
e8a781b
Compare
9bb15db to
8495163
Compare
e8a781b to
50f49dc
Compare
8495163 to
827bc64
Compare
7758d81 to
5bd7273
Compare
827bc64 to
32b563d
Compare
32b563d to
dc0804b
Compare
5bd7273 to
5739b7d
Compare
…th the same delimiters
The `MacroElement::Subtree` matching arm never compared the delimiter kind of the pattern subtree
against the input subtree, so a rule `([$x:ident])` matched the call `m!({a})`. Compare the
delimiter kinds, treating a mismatch as a rule-match failure so a later rule may still match, as
rustc does.
Also resolves the adjacent `TODO(Dean)` about bracket terminal consistency: a pattern subtree
cannot have inconsistent delimiters in the AST, and a pattern missing a closing delimiter is
reported by the parser and its rule is already dropped - so no declaration time check is needed.
dc0804b to
74aada1
Compare
5739b7d to
99e75ec
Compare

The
MacroElement::Subtreematching arm never compared the delimiter kind of the pattern subtreeagainst the input subtree, so a rule
([$x:ident])matched the callm!({a}). Compare thedelimiter kinds, treating a mismatch as a rule-match failure so a later rule may still match, as
rustc does.
Also resolves the adjacent
TODO(Dean)about bracket terminal consistency: a pattern subtreecannot have inconsistent delimiters in the AST, and a pattern missing a closing delimiter is
reported by the parser and its rule is already dropped - so no declaration time check is needed.