Skip to content

fix(semantic): match a pattern subtree only against a call subtree with the same delimiters - #10303

Open
orizi wants to merge 1 commit into
graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr2-duplicate-placeholder-f3from
graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5
Open

orizi wants to merge 1 commit into
graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr2-duplicate-placeholder-f3from
graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5

Conversation

@orizi

@orizi orizi commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

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.

@reviewable-StarkWare

Copy link
Copy Markdown

This change is Reviewable

orizi commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator Author

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5 branch 2 times, most recently from a53a9fc to e2eb1e2 Compare August 5, 2026 10:54
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr2-duplicate-placeholder-f3 branch from 08026fe to b654579 Compare August 5, 2026 10:54
@orizi
orizi marked this pull request as ready for review August 5, 2026 11:10
@cursor

cursor Bot commented Aug 5, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes core macro rule matching semantics; behavior fixes may break macros that relied on cross-delimiter subtree matching, though that was unintended.

Overview
User-defined inline macro pattern matching now treats subtree delimiters ((), [], {}) as part of the rule, aligned with rustc: a pattern like ([$x:ident]) no longer matches a braced or parenthesized call subtree, and a delimiter mismatch fails that rule so a later rule can still apply.

In is_macro_rule_match_ex, the MacroElement::Subtree arm pairs pattern and input WrappedMacro / WrappedTokenTree kinds before recursing; non-subtree tokens at that position still fail the match. The declaration-time TODO about bracket-terminal consistency is removed—mismatched open/close delimiters are parser errors and unparsed rules are already skipped.

New expansion and diagnostic tests cover multi-rule fallback, nested inner subtrees, non-first subtree elements, empty braced subtrees, lone-rule E2158, and malformed pattern delimiters.

Reviewed by Cursor Bugbot for commit 74aada1. Bugbot is set up for automated code reviews on this repo. Configure here.

@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr2-duplicate-placeholder-f3 branch from b654579 to e8f1e18 Compare August 5, 2026 11:59
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5 branch 2 times, most recently from 09a334a to 9719407 Compare August 5, 2026 15:15
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr2-duplicate-placeholder-f3 branch from e8f1e18 to 7a54e5b Compare August 5, 2026 15:15
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr2-duplicate-placeholder-f3 branch from 80b2e30 to 75c3eb4 Compare August 12, 2026 20:54
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5 branch from e6ca70b to 2dd6ba4 Compare August 12, 2026 20:54

@eytan-starkware eytan-starkware left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5 branch from 2dd6ba4 to 5ca0569 Compare August 16, 2026 11:37
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr2-duplicate-placeholder-f3 branch 2 times, most recently from 33e5dcd to a6418d1 Compare August 17, 2026 18:03
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5 branch from 5ca0569 to 9753276 Compare August 17, 2026 18:03

@orizi orizi left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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_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.

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_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.

Done, as suggested - input tokens matched positionally, the pattern side through get_macro_elements, and a future WrappedMacro variant just never matches.

@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5 branch from 9753276 to 952557f Compare August 23, 2026 08:43
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr2-duplicate-placeholder-f3 branch 2 times, most recently from 0c878f6 to 37a120f Compare August 23, 2026 10:31
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5 branch from 952557f to 365d74c Compare August 23, 2026 10:31
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5 branch from 365d74c to a3ae693 Compare August 25, 2026 12:30
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr2-duplicate-placeholder-f3 branch from 37a120f to 14ed2f7 Compare August 25, 2026 12:30
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5 branch from a3ae693 to d20f422 Compare August 26, 2026 19:59
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr2-duplicate-placeholder-f3 branch 2 times, most recently from c3c400b to e8a781b Compare August 27, 2026 04:32
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5 branch 2 times, most recently from 9bb15db to 8495163 Compare August 27, 2026 13:33
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr2-duplicate-placeholder-f3 branch from e8a781b to 50f49dc Compare August 27, 2026 13:33
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5 branch from 8495163 to 827bc64 Compare August 28, 2026 10:07
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr2-duplicate-placeholder-f3 branch 2 times, most recently from 7758d81 to 5bd7273 Compare August 28, 2026 12:58
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5 branch from 827bc64 to 32b563d Compare August 28, 2026 12:58
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5 branch from 32b563d to dc0804b Compare September 14, 2026 04:51
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr2-duplicate-placeholder-f3 branch from 5bd7273 to 5739b7d Compare September 14, 2026 04:51
…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.
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr3-subtree-delimiters-f5 branch from dc0804b to 74aada1 Compare September 14, 2026 06:56
@orizi
orizi force-pushed the graph-plan/2026-08-03-macro-fixes/matcher-correctness.pr2-duplicate-placeholder-f3 branch from 5739b7d to 99e75ec Compare September 14, 2026 06:56

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants