From 3a2f3b910216cd196deba776c14962fb8459b51e Mon Sep 17 00:00:00 2001 From: Asuna Date: Thu, 9 Jan 2025 03:02:23 +0100 Subject: [PATCH] Fix `proc_macro::quote!` for raw ident --- library/proc_macro/src/quote.rs | 10 ++++++++-- tests/ui/proc-macro/quote/auxiliary/basic.rs | 2 +- tests/ui/proc-macro/quote/debug.rs | 1 + tests/ui/proc-macro/quote/debug.stdout | 19 +++++++++++++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/library/proc_macro/src/quote.rs b/library/proc_macro/src/quote.rs index c53bb09572495..3f845acd1c523 100644 --- a/library/proc_macro/src/quote.rs +++ b/library/proc_macro/src/quote.rs @@ -112,8 +112,14 @@ pub fn quote(stream: TokenStream) -> TokenStream { )), &mut ts);) } TokenTree::Ident(tt) => { - minimal_quote!(crate::ToTokens::to_tokens(&crate::TokenTree::Ident(crate::Ident::new( - (@ TokenTree::from(Literal::string(&tt.to_string()))), + let literal = tt.to_string(); + let (literal, ctor) = if let Some(stripped) = literal.strip_prefix("r#") { + (stripped, minimal_quote!(crate::Ident::new_raw)) + } else { + (literal.as_str(), minimal_quote!(crate::Ident::new)) + }; + minimal_quote!(crate::ToTokens::to_tokens(&crate::TokenTree::Ident((@ ctor)( + (@ TokenTree::from(Literal::string(literal))), (@ quote_span(proc_macro_crate.clone(), tt.span())), )), &mut ts);) } diff --git a/tests/ui/proc-macro/quote/auxiliary/basic.rs b/tests/ui/proc-macro/quote/auxiliary/basic.rs index c49e9380b8fa1..ef726bbfbe3a0 100644 --- a/tests/ui/proc-macro/quote/auxiliary/basic.rs +++ b/tests/ui/proc-macro/quote/auxiliary/basic.rs @@ -34,7 +34,7 @@ pub fn run_tests(_: TokenStream) -> TokenStream { test_inner_block_comment(); test_outer_attr(); test_inner_attr(); - // test_quote_raw_id(); // FIXME: Fix it in a subsequent commit + test_quote_raw_id(); TokenStream::new() } diff --git a/tests/ui/proc-macro/quote/debug.rs b/tests/ui/proc-macro/quote/debug.rs index 11d144d609f5a..ce113079e5678 100644 --- a/tests/ui/proc-macro/quote/debug.rs +++ b/tests/ui/proc-macro/quote/debug.rs @@ -15,5 +15,6 @@ extern crate proc_macro; fn main() { proc_macro::quote! { let hello = "world"; + let r#raw_ident = r#"raw"literal"#; } } diff --git a/tests/ui/proc-macro/quote/debug.stdout b/tests/ui/proc-macro/quote/debug.stdout index 583599ff97524..3eaad9eb96997 100644 --- a/tests/ui/proc-macro/quote/debug.stdout +++ b/tests/ui/proc-macro/quote/debug.stdout @@ -40,6 +40,25 @@ fn main() { }), &mut ts); crate::ToTokens::to_tokens(&crate::TokenTree::Punct(crate::Punct::new(';', crate::Spacing::Alone)), &mut ts); + crate::ToTokens::to_tokens(&crate::TokenTree::Ident(crate::Ident::new("let", + crate::Span::recover_proc_macro_span(3))), &mut ts); + crate::ToTokens::to_tokens(&crate::TokenTree::Ident(crate::Ident::new_raw("raw_ident", + crate::Span::recover_proc_macro_span(4))), &mut ts); + crate::ToTokens::to_tokens(&crate::TokenTree::Punct(crate::Punct::new('=', + crate::Spacing::Alone)), &mut ts); + crate::ToTokens::to_tokens(&crate::TokenTree::Literal({ + let mut iter = + "r#\"raw\"literal\"#".parse::().unwrap().into_iter(); + if let (Some(crate::TokenTree::Literal(mut lit)), None) = + (iter.next(), iter.next()) { + lit.set_span(crate::Span::recover_proc_macro_span(5)); + lit + } else { + ::core::panicking::panic("internal error: entered unreachable code") + } + }), &mut ts); + crate::ToTokens::to_tokens(&crate::TokenTree::Punct(crate::Punct::new(';', + crate::Spacing::Alone)), &mut ts); ts } }