From: Owen Avery Date: Tue, 30 May 2023 20:24:08 +0000 (-0400) Subject: gccrs: Properly match delimiters X-Git-Tag: basepoints/gcc-15~2507 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=007248a2c48ef3c349204899b325bab574019734;p=thirdparty%2Fgcc.git gccrs: Properly match delimiters gcc/rust/ChangeLog: * expand/rust-macro-expand.cc (MacroExpander::try_match_rule): Don't match delimiters for root matcher. (MacroExpander::match_matcher): Add option to match delimiters. * expand/rust-macro-expand.h (MacroExpander::match_matcher): Likewise. * parse/rust-parse-impl.h (Parser::skip_token): Add zero argument method. * parse/rust-parse.h: (Parser::skip_token): Likewise. gcc/testsuite/ChangeLog: * rust/compile/macro-delim.rs: New test. Signed-off-by: Owen Avery --- diff --git a/gcc/rust/expand/rust-macro-expand.cc b/gcc/rust/expand/rust-macro-expand.cc index f347335f2efe..7229a09f2fe5 100644 --- a/gcc/rust/expand/rust-macro-expand.cc +++ b/gcc/rust/expand/rust-macro-expand.cc @@ -352,7 +352,7 @@ MacroExpander::try_match_rule (AST::MacroRule &match_rule, AST::MacroMatcher &matcher = match_rule.get_matcher (); expansion_depth++; - if (!match_matcher (parser, matcher)) + if (!match_matcher (parser, matcher, false, false)) { expansion_depth--; return false; @@ -437,7 +437,8 @@ MacroExpander::match_fragment (Parser &parser, bool MacroExpander::match_matcher (Parser &parser, - AST::MacroMatcher &matcher, bool in_repetition) + AST::MacroMatcher &matcher, bool in_repetition, + bool match_delim) { if (depth_exceeds_recursion_limit ()) { @@ -447,29 +448,34 @@ MacroExpander::match_matcher (Parser &parser, auto delimiter = parser.peek_current_token (); + auto check_delim = [&matcher, match_delim] (AST::DelimType delim) { + return !match_delim || matcher.get_delim_type () == delim; + }; + // this is used so we can check that we delimit the stream correctly. switch (delimiter->get_id ()) { case LEFT_PAREN: { - if (!parser.skip_token (LEFT_PAREN)) + if (!check_delim (AST::DelimType::PARENS)) return false; } break; case LEFT_SQUARE: { - if (!parser.skip_token (LEFT_SQUARE)) + if (!check_delim (AST::DelimType::SQUARE)) return false; } break; case LEFT_CURLY: { - if (!parser.skip_token (LEFT_CURLY)) + if (!check_delim (AST::DelimType::CURLY)) return false; } break; default: - gcc_unreachable (); + return false; } + parser.skip_token (); const MacroInvocLexer &source = parser.get_token_source (); diff --git a/gcc/rust/expand/rust-macro-expand.h b/gcc/rust/expand/rust-macro-expand.h index ceac8e604057..a24ec4f682c0 100644 --- a/gcc/rust/expand/rust-macro-expand.h +++ b/gcc/rust/expand/rust-macro-expand.h @@ -275,7 +275,8 @@ struct MacroExpander AST::MacroMatchRepetition &rep); bool match_matcher (Parser &parser, - AST::MacroMatcher &matcher, bool in_repetition = false); + AST::MacroMatcher &matcher, bool in_repetition = false, + bool match_delim = true); /** * Match any amount of matches diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 3f2500660df6..9faa374915c6 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -12159,6 +12159,14 @@ Parser::skip_after_semicolon () lexer.skip_token (); } +/* Skips the current token */ +template +void +Parser::skip_token () +{ + lexer.skip_token (); +} + /* Checks if current token has inputted id - skips it and returns true if so, * diagnoses an error and returns false otherwise. */ template diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index 1e7e5262eec5..315d3fcdec6c 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -94,6 +94,11 @@ struct ParseRestrictions template class Parser { public: + /** + * Consume a token + */ + void skip_token (); + /** * Consume a token, reporting an error if it isn't the next token * diff --git a/gcc/testsuite/rust/compile/macro-delim.rs b/gcc/testsuite/rust/compile/macro-delim.rs new file mode 100644 index 000000000000..de4cd5607d94 --- /dev/null +++ b/gcc/testsuite/rust/compile/macro-delim.rs @@ -0,0 +1,8 @@ +macro_rules! foo { + ([]) => {struct Foo;}; + (()) => {struct _A;}; + (bool) => {struct _B;}; +} + +foo! (()); +foo! (bool);