[gcc r14-7360] gccrs: Add all rust keywords (except priv) to the follow-set of `:vis` when parsing macro rules
Arthur Cohen
cohenarthur@gcc.gnu.org
Tue Jan 16 17:25:28 GMT 2024
https://gcc.gnu.org/g:ef24a5b55876c38c73d8d8813df230b515936466
commit r14-7360-gef24a5b55876c38c73d8d8813df230b515936466
Author: Tage Johansson <frans.tage@gmail.com>
Date: Sat Mar 4 19:43:02 2023 +0100
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 <KEY_WORD>) => { ... };
}
```
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 <frans.tage@gmail.com>
Diff:
---
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(-)
diff --git a/gcc/rust/parse/rust-parse.cc b/gcc/rust/parse/rust-parse.cc
index f1e2caa258b..1b565bc8f45 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 00000000000..36545af7e16
--- /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 00000000000..6b3b369bc3a
--- /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);
+ }
+}
More information about the Gcc-cvs
mailing list