From d10d0b3e9eb5c72b651c52b6fd38f1db20589b47 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Sat, 21 Apr 2018 22:16:55 +0300 Subject: proc_macro: don't try to reflect literals in quasi-quoting. --- src/libproc_macro/lib.rs | 2 +- src/libproc_macro/quote.rs | 109 +++++++-------------------------------------- 2 files changed, 16 insertions(+), 95 deletions(-) (limited to 'src/libproc_macro') diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index f5a7c88a1b7..ea4ca03a0a1 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -1364,7 +1364,7 @@ impl TokenTree { #[unstable(feature = "proc_macro_internals", issue = "27812")] #[doc(hidden)] pub mod __internal { - pub use quote::{LiteralKind, SpannedSymbol, Quoter, unquote}; + pub use quote::{Quoter, unquote}; use std::cell::Cell; use std::ptr; diff --git a/src/libproc_macro/quote.rs b/src/libproc_macro/quote.rs index 73a66640c59..8ae1d7b8525 100644 --- a/src/libproc_macro/quote.rs +++ b/src/libproc_macro/quote.rs @@ -17,8 +17,6 @@ use {Delimiter, Literal, Spacing, Span, Ident, Punct, Group, TokenStream, TokenTree}; use syntax::ext::base::{ExtCtxt, ProcMacro}; -use syntax::parse::token; -use syntax::symbol::Symbol; use syntax::tokenstream; /// This is the actual quote!() proc macro @@ -42,6 +40,7 @@ macro_rules! quote_tok { (,) => { tt2ts!(Punct::new(',', Spacing::Alone)) }; (.) => { tt2ts!(Punct::new('.', Spacing::Alone)) }; (:) => { tt2ts!(Punct::new(':', Spacing::Alone)) }; + (;) => { tt2ts!(Punct::new(';', Spacing::Alone)) }; (|) => { tt2ts!(Punct::new('|', Spacing::Alone)) }; (::) => { [ @@ -61,6 +60,7 @@ macro_rules! quote_tok { (_) => { tt2ts!(Punct::new('_', Spacing::Alone)) }; (0) => { tt2ts!(Literal::i8_unsuffixed(0)) }; (&) => { tt2ts!(Punct::new('&', Spacing::Alone)) }; + (=) => { tt2ts!(Punct::new('=', Spacing::Alone)) }; ($i:ident) => { tt2ts!(Ident::new(stringify!($i), Span::def_site())) }; } @@ -92,15 +92,6 @@ impl ProcMacro for Quoter { } } -impl Quote for Option { - fn quote(self) -> TokenStream { - match self { - Some(t) => quote!(Some((quote t))), - None => quote!(None), - } - } -} - impl Quote for TokenStream { fn quote(self) -> TokenStream { if self.is_empty() { @@ -194,93 +185,23 @@ impl Quote for Span { } } -macro_rules! literals { - ($($i:ident),*; $($raw:ident),*) => { - pub struct SpannedSymbol { - sym: Symbol, - span: Span, - } - - impl SpannedSymbol { - pub fn new(string: &str, span: Span) -> SpannedSymbol { - SpannedSymbol { sym: Symbol::intern(string), span } - } - } - - impl Quote for SpannedSymbol { - fn quote(self) -> TokenStream { - quote!(::__internal::SpannedSymbol::new((quote self.sym.as_str()), - (quote self.span))) - } - } - - pub enum LiteralKind { - $($i,)* - $($raw(u16),)* - } - - impl LiteralKind { - pub fn with_contents_and_suffix(self, contents: SpannedSymbol, - suffix: Option) -> Literal { - let sym = contents.sym; - let suffix = suffix.map(|t| t.sym); - match self { - $(LiteralKind::$i => { - Literal { - lit: token::Lit::$i(sym), - suffix, - span: contents.span, - } - })* - $(LiteralKind::$raw(n) => { - Literal { - lit: token::Lit::$raw(sym, n), - suffix, - span: contents.span, - } - })* - } - } - } - - impl Literal { - fn kind_contents_and_suffix(self) -> (LiteralKind, SpannedSymbol, Option) - { - let (kind, contents) = match self.lit { - $(token::Lit::$i(contents) => (LiteralKind::$i, contents),)* - $(token::Lit::$raw(contents, n) => (LiteralKind::$raw(n), contents),)* - }; - let suffix = self.suffix.map(|sym| SpannedSymbol::new(&sym.as_str(), self.span())); - (kind, SpannedSymbol::new(&contents.as_str(), self.span()), suffix) - } - } - - impl Quote for LiteralKind { - fn quote(self) -> TokenStream { - match self { - $(LiteralKind::$i => quote! { - ::__internal::LiteralKind::$i - },)* - $(LiteralKind::$raw(n) => quote! { - ::__internal::LiteralKind::$raw((quote n)) - },)* - } - } - } - - impl Quote for Literal { - fn quote(self) -> TokenStream { - let (kind, contents, suffix) = self.kind_contents_and_suffix(); - quote! { - (quote kind).with_contents_and_suffix((quote contents), (quote suffix)) - } +impl Quote for Literal { + fn quote(self) -> TokenStream { + quote! {{ + let mut iter = (quote self.to_string()) + .parse::<::TokenStream>() + .unwrap() + .into_iter(); + if let (Some(::TokenTree::Literal(mut lit)), None) = (iter.next(), iter.next()) { + lit.set_span((quote self.span)); + lit + } else { + unreachable!() } - } + }} } } -literals!(Byte, Char, Float, Str_, Integer, ByteStr; StrRaw, ByteStrRaw); - impl Quote for Delimiter { fn quote(self) -> TokenStream { macro_rules! gen_match { -- cgit 1.4.1-3-g733a5