]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: Handle keyword metavariables
authorOwen Avery <powerboat9.gamer@gmail.com>
Wed, 17 May 2023 16:32:23 +0000 (12:32 -0400)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 16 Jan 2024 17:37:20 +0000 (18:37 +0100)
gcc/rust/ChangeLog:

* expand/rust-macro-substitute-ctx.cc
(SubstituteCtx::check_repetition_amount): Handle keywords.
(SubstituteCtx::substitute_token): Likewise.
* lex/rust-token.cc
(Token::get_str): Likewise.
* parse/rust-parse-impl.h
(Parser::parse_macro_match_fragment): Likewise.

gcc/testsuite/ChangeLog:

* rust/compile/macro-issue2194.rs: New test.

Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
gcc/rust/expand/rust-macro-substitute-ctx.cc
gcc/rust/lex/rust-token.cc
gcc/rust/parse/rust-parse-impl.h
gcc/testsuite/rust/compile/macro-issue2194.rs [new file with mode: 0644]

index eb0f149b10ad498439598b8293b4a6e76ee30cf7..0a38578bd74a483b13df891ca41b708fb14aa5cd 100644 (file)
@@ -58,7 +58,8 @@ SubstituteCtx::check_repetition_amount (size_t pattern_start,
       if (macro.at (i)->get_id () == DOLLAR_SIGN)
        {
          auto &frag_token = macro.at (i + 1);
-         if (frag_token->get_id () == IDENTIFIER)
+         if (token_id_is_keyword (frag_token->get_id ())
+             || frag_token->get_id () == IDENTIFIER)
            {
              auto it = fragments.find (frag_token->get_str ());
              if (it == fragments.end ())
@@ -199,11 +200,21 @@ std::pair<std::vector<std::unique_ptr<AST::Token>>, size_t>
 SubstituteCtx::substitute_token (size_t token_idx)
 {
   auto &token = macro.at (token_idx);
+
   switch (token->get_id ())
     {
-    case IDENTIFIER:
-      rust_debug ("expanding metavar: %s", token->get_str ().c_str ());
-      return {substitute_metavar (token), 1};
+    default:
+      if (token_id_is_keyword (token->get_id ()))
+       {
+       case IDENTIFIER:
+         rust_debug ("expanding metavar: %s", token->get_str ().c_str ());
+         return {substitute_metavar (token), 1};
+       }
+      rust_error_at (token->get_locus (),
+                    "unexpected token in macro transcribe: expected "
+                    "%<(%> or identifier after %<$%>, got %<%s%>",
+                    get_token_description (token->get_id ()));
+      break;
       case LEFT_PAREN: {
        // We need to parse up until the closing delimiter and expand this
        // fragment->n times.
@@ -279,11 +290,6 @@ SubstituteCtx::substitute_token (size_t token_idx)
       // with no associated fragment and paste the dollar sign in the
       // transcription. Unsure how to do that since we always have at
       // least the closing curly brace after an empty $...
-    default:
-      rust_error_at (token->get_locus (),
-                    "unexpected token in macro transcribe: expected "
-                    "%<(%> or identifier after %<$%>, got %<%s%>",
-                    get_token_description (token->get_id ()));
     }
 
   // FIXME: gcc_unreachable() error case?
index 777b4e13da97a00ae110644a7e607a9803edd4ee..56177d3d3d380f0ec8495748b99220662f4fc0b6 100644 (file)
@@ -152,6 +152,9 @@ Token::get_type_hint_str () const
 const std::string &
 Token::get_str () const
 {
+  if (token_id_is_keyword (token_id))
+    return token_id_keyword_string (token_id);
+
   // FIXME: attempt to return null again
   // gcc_assert(str != NULL);
 
index f5f3c7bb527affa6f03fd196d3405743f2da1609..5d48ba637d7a3da38ae9d6d07d02a5a29e727816 100644 (file)
@@ -2146,10 +2146,10 @@ Parser<ManagedTokenSource>::parse_macro_match_fragment ()
 
   Identifier ident = "";
   auto identifier = lexer.peek_token ();
-  if (identifier->has_str ())
-    ident = identifier->get_str ();
+  if (identifier->get_id () == UNDERSCORE)
+    ident = "_";
   else
-    ident = std::string (token_id_to_str (identifier->get_id ()));
+    ident = identifier->get_str ();
 
   if (ident.empty ())
     {
diff --git a/gcc/testsuite/rust/compile/macro-issue2194.rs b/gcc/testsuite/rust/compile/macro-issue2194.rs
new file mode 100644 (file)
index 0000000..c94b114
--- /dev/null
@@ -0,0 +1,7 @@
+macro_rules! foo {($type:ident) => {
+    let $type = 12;
+}} 
+
+pub fn foo() {
+    foo!(_a);
+}