From 36f2816a1e070d33c27c07f176e692d87781d228 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 10 Jul 2017 17:49:18 -0700 Subject: [PATCH] proc_macro: Use an item's tokens if available This partly resolves the `FIXME` located in `src/libproc_macro/lib.rs` when interpreting interpolated tokens. All instances of `ast::Item` which have a list of tokens attached to them now use that list of tokens to losslessly get converted into a `TokenTree` instead of going through stringification and losing span information. cc #43081 --- src/libproc_macro/lib.rs | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 12ed4fba402..0f0d4138062 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -509,14 +509,26 @@ fn joint(first: char, rest: Token, is_joint: bool, span: &mut syntax_pos::Span, Ident(ident) | Lifetime(ident) => TokenNode::Term(Term(ident.name)), Literal(..) | DocComment(..) => TokenNode::Literal(self::Literal(token)), - Interpolated(ref nt) => __internal::with_sess(|(sess, _)| { - TokenNode::Group(Delimiter::None, TokenStream(nt.1.force(|| { - // FIXME(jseyfried): Avoid this pretty-print + reparse hack - let name = "".to_owned(); - let source = pprust::token_to_string(&token); - parse_stream_from_source_str(name, source, sess, Some(span)) - }))) - }), + Interpolated(ref nt) => { + let mut node = None; + if let Nonterminal::NtItem(ref item) = nt.0 { + if let Some(ref tokens) = item.tokens { + node = Some(TokenNode::Group(Delimiter::None, + TokenStream(tokens.clone()))); + } + } + + node.unwrap_or_else(|| { + __internal::with_sess(|(sess, _)| { + TokenNode::Group(Delimiter::None, TokenStream(nt.1.force(|| { + // FIXME(jseyfried): Avoid this pretty-print + reparse hack + let name = "".to_owned(); + let source = pprust::token_to_string(&token); + parse_stream_from_source_str(name, source, sess, Some(span)) + }))) + }) + }) + } OpenDelim(..) | CloseDelim(..) => unreachable!(), Whitespace | Comment | Shebang(..) | Eof => unreachable!(), -- GitLab