From: Owen Avery Date: Wed, 17 May 2023 16:32:23 +0000 (-0400) Subject: gccrs: Handle keyword metavariables X-Git-Tag: basepoints/gcc-15~2532 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dfd2e26bda189f573d40eaf1f6b5a44180c31640;p=thirdparty%2Fgcc.git gccrs: Handle keyword metavariables 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 --- diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.cc b/gcc/rust/expand/rust-macro-substitute-ctx.cc index eb0f149b10ad..0a38578bd74a 100644 --- a/gcc/rust/expand/rust-macro-substitute-ctx.cc +++ b/gcc/rust/expand/rust-macro-substitute-ctx.cc @@ -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>, 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? diff --git a/gcc/rust/lex/rust-token.cc b/gcc/rust/lex/rust-token.cc index 777b4e13da97..56177d3d3d38 100644 --- a/gcc/rust/lex/rust-token.cc +++ b/gcc/rust/lex/rust-token.cc @@ -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); diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index f5f3c7bb527a..5d48ba637d7a 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -2146,10 +2146,10 @@ Parser::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 index 000000000000..c94b1147d66f --- /dev/null +++ b/gcc/testsuite/rust/compile/macro-issue2194.rs @@ -0,0 +1,7 @@ +macro_rules! foo {($type:ident) => { + let $type = 12; +}} + +pub fn foo() { + foo!(_a); +}