diff options
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_parser.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 9 |
3 files changed, 23 insertions, 5 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index cc097ab0efa..1f47a91fcc1 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -615,7 +615,9 @@ impl<'a> ExtCtxt<'a> { pub fn new_parser_from_tts(&self, tts: &[tokenstream::TokenTree]) -> parser::Parser<'a> { - parse::tts_to_parser(self.parse_sess, tts.to_vec()) + let mut parser = parse::tts_to_parser(self.parse_sess, tts.to_vec()); + parser.allow_interpolated_tts = false; // FIXME(jseyfried) `quote!` can't handle these yet + parser } pub fn codemap(&self) -> &'a CodeMap { self.parse_sess.codemap() } pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess } diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index fdec7a4c732..1066646aa8e 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -496,10 +496,19 @@ pub fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal { match name { "tt" => { p.quote_depth += 1; //but in theory, non-quoted tts might be useful - let res: ::parse::PResult<'a, _> = p.parse_token_tree(); - let res = token::NtTT(panictry!(res)); + let mut tt = panictry!(p.parse_token_tree()); p.quote_depth -= 1; - return res; + loop { + let nt = match tt { + TokenTree::Token(_, token::Interpolated(ref nt)) => nt.clone(), + _ => break, + }; + match *nt { + token::NtTT(ref sub_tt) => tt = sub_tt.clone(), + _ => break, + } + } + return token::NtTT(tt); } _ => {} } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e5bbeb3c648..b670a738473 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -212,6 +212,7 @@ pub struct Parser<'a> { pub expected_tokens: Vec<TokenType>, pub tts: Vec<(TokenTree, usize)>, pub desugar_doc_comments: bool, + pub allow_interpolated_tts: bool, } #[derive(PartialEq, Eq, Clone)] @@ -301,6 +302,7 @@ impl<'a> Parser<'a> { expected_tokens: Vec::new(), tts: Vec::new(), desugar_doc_comments: desugar_doc_comments, + allow_interpolated_tts: true, }; let tok = parser.next_tok(); @@ -2718,7 +2720,12 @@ impl<'a> Parser<'a> { if self.tts.last().map(|&(_, i)| i == 1).unwrap_or(false) { let tt = self.tts.pop().unwrap().0; self.bump(); - return Ok(tt); + return Ok(if self.allow_interpolated_tts { + // avoid needlessly reparsing token trees in recursive macro expansions + TokenTree::Token(tt.span(), token::Interpolated(Rc::new(token::NtTT(tt)))) + } else { + tt + }); } let parsing_token_tree = ::std::mem::replace(&mut self.parsing_token_tree, true); |
