Skip to content

Commit ee5b590

Browse files
powerboat9CohenArthur
authored andcommitted
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 <[email protected]>
1 parent 5c78ef9 commit ee5b590

File tree

4 files changed

+28
-12
lines changed

4 files changed

+28
-12
lines changed

gcc/rust/expand/rust-macro-substitute-ctx.cc

+15-9
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ SubstituteCtx::check_repetition_amount (size_t pattern_start,
5858
if (macro.at (i)->get_id () == DOLLAR_SIGN)
5959
{
6060
auto &frag_token = macro.at (i + 1);
61-
if (frag_token->get_id () == IDENTIFIER)
61+
if (token_id_is_keyword (frag_token->get_id ())
62+
|| frag_token->get_id () == IDENTIFIER)
6263
{
6364
auto it = fragments.find (frag_token->get_str ());
6465
if (it == fragments.end ())
@@ -199,11 +200,21 @@ std::pair<std::vector<std::unique_ptr<AST::Token>>, size_t>
199200
SubstituteCtx::substitute_token (size_t token_idx)
200201
{
201202
auto &token = macro.at (token_idx);
203+
202204
switch (token->get_id ())
203205
{
204-
case IDENTIFIER:
205-
rust_debug ("expanding metavar: %s", token->get_str ().c_str ());
206-
return {substitute_metavar (token), 1};
206+
default:
207+
if (token_id_is_keyword (token->get_id ()))
208+
{
209+
case IDENTIFIER:
210+
rust_debug ("expanding metavar: %s", token->get_str ().c_str ());
211+
return {substitute_metavar (token), 1};
212+
}
213+
rust_error_at (token->get_locus (),
214+
"unexpected token in macro transcribe: expected "
215+
"%<(%> or identifier after %<$%>, got %<%s%>",
216+
get_token_description (token->get_id ()));
217+
break;
207218
case LEFT_PAREN: {
208219
// We need to parse up until the closing delimiter and expand this
209220
// fragment->n times.
@@ -279,11 +290,6 @@ SubstituteCtx::substitute_token (size_t token_idx)
279290
// with no associated fragment and paste the dollar sign in the
280291
// transcription. Unsure how to do that since we always have at
281292
// least the closing curly brace after an empty $...
282-
default:
283-
rust_error_at (token->get_locus (),
284-
"unexpected token in macro transcribe: expected "
285-
"%<(%> or identifier after %<$%>, got %<%s%>",
286-
get_token_description (token->get_id ()));
287293
}
288294

289295
// FIXME: gcc_unreachable() error case?

gcc/rust/lex/rust-token.cc

+3
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ Token::get_type_hint_str () const
152152
const std::string &
153153
Token::get_str () const
154154
{
155+
if (token_id_is_keyword (token_id))
156+
return token_id_keyword_string (token_id);
157+
155158
// FIXME: attempt to return null again
156159
// gcc_assert(str != NULL);
157160

gcc/rust/parse/rust-parse-impl.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -2146,10 +2146,10 @@ Parser<ManagedTokenSource>::parse_macro_match_fragment ()
21462146

21472147
Identifier ident = "";
21482148
auto identifier = lexer.peek_token ();
2149-
if (identifier->has_str ())
2150-
ident = identifier->get_str ();
2149+
if (identifier->get_id () == UNDERSCORE)
2150+
ident = "_";
21512151
else
2152-
ident = std::string (token_id_to_str (identifier->get_id ()));
2152+
ident = identifier->get_str ();
21532153

21542154
if (ident.empty ())
21552155
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
macro_rules! foo {($type:ident) => {
2+
let $type = 12;
3+
}}
4+
5+
pub fn foo() {
6+
foo!(_a);
7+
}

0 commit comments

Comments
 (0)