diff options
author | Owen Avery <powerboat9.gamer@gmail.com> | 2023-05-17 12:32:23 -0400 |
---|---|---|
committer | CohenArthur <arthur.cohen@embecosm.com> | 2023-05-18 20:29:52 +0000 |
commit | ee5b5905deba07104dec5bdbb889b9754c0e9c89 (patch) | |
tree | 1954cb3650f2f864424cbbccfa00e21b1ca6b63a | |
parent | 5c78ef9854b560940aeaf36e74439ce3f10d5eb2 (diff) | |
download | gcc-ee5b5905deba07104dec5bdbb889b9754c0e9c89.zip gcc-ee5b5905deba07104dec5bdbb889b9754c0e9c89.tar.gz gcc-ee5b5905deba07104dec5bdbb889b9754c0e9c89.tar.bz2 |
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 <powerboat9.gamer@gmail.com>
-rw-r--r-- | gcc/rust/expand/rust-macro-substitute-ctx.cc | 24 | ||||
-rw-r--r-- | gcc/rust/lex/rust-token.cc | 3 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 6 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/macro-issue2194.rs | 7 |
4 files changed, 28 insertions, 12 deletions
diff --git a/gcc/rust/expand/rust-macro-substitute-ctx.cc b/gcc/rust/expand/rust-macro-substitute-ctx.cc index eb0f149..0a38578 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<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? diff --git a/gcc/rust/lex/rust-token.cc b/gcc/rust/lex/rust-token.cc index 0b5163c..b6be9ca 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 cf1fd9f..dbb322b 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -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 index 0000000..c94b114 --- /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); +} |