diff --git a/library/proc_macro/src/quote.rs b/library/proc_macro/src/quote.rs index 27c8458a351c..bcb15912bb65 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 c49e9380b8fa..ef726bbfbe3a 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 11d144d609f5..ce113079e567 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 583599ff9752..3eaad9eb9699 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 } }