From ef24a5b55876c38c73d8d8813df230b515936466 Mon Sep 17 00:00:00 2001 From: Tage Johansson Date: Sat, 4 Mar 2023 19:43:02 +0100 Subject: gccrs: Add all rust keywords (except priv) to the follow-set of `:vis` when parsing macro rules Previously, the following macro rules were rejected by gccrs: ```Rust macro_rules! { ($v:vis ) => { ... }; } ``` This PR fixes so the above code is accepted by the compiler for all key words like `async` or `unsafe`. The only exception is the keyword `priv` which is not allowed. See [this page](https://doc.rust-lang.org/reference/macro-ambiguity.html) for reference. Especially the following excerpt: > FOLLOW(vis) = {,l any keyword or identifier except a non-raw priv; any token that can begin a type; ident, ty, and path nonterminals}. Fixes #1060 gcc/rust/ChangeLog: * parse/rust-parse.cc: fix follow-sets gcc/testsuite/ChangeLog: * rust/compile/macro47.rs: Test that :vis can be followed by some keywords * rust/compile/macro48.rs: Test that :vis cannot be followed by the keyword priv Signed-off-by: Tage Johansson --- gcc/rust/parse/rust-parse.cc | 92 ++++++++++++++++++++++++----------- gcc/testsuite/rust/compile/macro47.rs | 10 ++++ gcc/testsuite/rust/compile/macro48.rs | 10 ++++ 3 files changed, 84 insertions(+), 28 deletions(-) create mode 100644 gcc/testsuite/rust/compile/macro47.rs create mode 100644 gcc/testsuite/rust/compile/macro48.rs (limited to 'gcc') diff --git a/gcc/rust/parse/rust-parse.cc b/gcc/rust/parse/rust-parse.cc index f1e2caa..1b565bc 100644 --- a/gcc/rust/parse/rust-parse.cc +++ b/gcc/rust/parse/rust-parse.cc @@ -17,6 +17,7 @@ along with GCC; see the file COPYING3. If not see #include "rust-parse.h" #include "rust-linemap.h" #include "rust-diagnostics.h" +#include "rust-token.h" namespace Rust { @@ -166,34 +167,69 @@ peculiar_fragment_match_compatible (const AST::MacroMatchFragment &last_match, {MATCH_ARROW, COMMA, EQUAL, PIPE, SEMICOLON, COLON, RIGHT_ANGLE, RIGHT_SHIFT, LEFT_SQUARE, LEFT_CURLY, AS, WHERE}}, {AST::MacroFragSpec::VIS, - { - COMMA, - IDENTIFIER /* FIXME: Other than `priv` */, - LEFT_PAREN, - LEFT_SQUARE, - EXCLAM, - ASTERISK, - AMP, - LOGICAL_AND, - QUESTION_MARK, - LIFETIME, - LEFT_ANGLE, - LEFT_SHIFT, - SUPER, - SELF, - SELF_ALIAS, - EXTERN_TOK, - CRATE, - UNDERSCORE, - FOR, - IMPL, - FN_TOK, - UNSAFE, - TYPEOF, - DYN - // FIXME: Add Non kw identifiers - // FIXME: Add $crate as valid - }}}; + {COMMA, + IDENTIFIER, + LEFT_PAREN, + LEFT_SQUARE, + EXCLAM, + ASTERISK, + AMP, + LOGICAL_AND, + QUESTION_MARK, + LIFETIME, + LEFT_ANGLE, + LEFT_SHIFT, + UNDERSCORE, + ABSTRACT, + AS, + ASYNC, + AUTO, + BECOME, + BOX, + BREAK, + CONST, + CONTINUE, + CRATE, + DO, + DYN, + ELSE, + ENUM_TOK, + EXTERN_TOK, + FALSE_LITERAL, + FINAL_TOK, + FN_TOK, + FOR, + IF, + IMPL, + IN, + LET, + LOOP, + MACRO, + MATCH_TOK, + MOD, + MOVE, + MUT, + OVERRIDE_TOK, + PUB, + REF, + RETURN_TOK, + SELF_ALIAS, + SELF, + STATIC_TOK, + STRUCT_TOK, + SUPER, + TRAIT, + TRUE_LITERAL, + TRY, + TYPE, + TYPEOF, + UNSAFE, + UNSIZED, + USE, + VIRTUAL, + WHERE, + WHILE, + YIELD}}}; Location error_locus = match.get_match_locus (); std::string kind_str = "fragment"; diff --git a/gcc/testsuite/rust/compile/macro47.rs b/gcc/testsuite/rust/compile/macro47.rs new file mode 100644 index 0000000..36545af --- /dev/null +++ b/gcc/testsuite/rust/compile/macro47.rs @@ -0,0 +1,10 @@ +// Check the follow-set of :vis in macro rules. + +macro_rules! my_mac { + ($v:vis async) => { + $v struct Foo(i32); + }; + ($v:vis $i:ident) => { + $v struct $i(i32); + } +} diff --git a/gcc/testsuite/rust/compile/macro48.rs b/gcc/testsuite/rust/compile/macro48.rs new file mode 100644 index 0000000..6b3b369 --- /dev/null +++ b/gcc/testsuite/rust/compile/macro48.rs @@ -0,0 +1,10 @@ +// Check that "priv" is not in the follow set of :vis. + +// { dg-error "token .priv. is not allowed after .vis. fragment" "#359" { target *-*-* } .+4 } +// { dg-error "required first macro rule in macro rules definition could not be parsed" "" { target *-*-* } .+3 } +// { dg-error "failed to parse item in crate" "" { target *-*-* } .+2 } +macro_rules! my_mac { + ($v:vis priv) => { + $v struct Foo(i32); + } +} -- cgit v1.1