Skip to content

Commit 23ad6fd

Browse files
committed
Improve tt-heavy expansion performance.
1 parent 7ae0833 commit 23ad6fd

File tree

3 files changed

+23
-5
lines changed

3 files changed

+23
-5
lines changed

src/libsyntax/ext/base.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,9 @@ impl<'a> ExtCtxt<'a> {
615615

616616
pub fn new_parser_from_tts(&self, tts: &[tokenstream::TokenTree])
617617
-> parser::Parser<'a> {
618-
parse::tts_to_parser(self.parse_sess, tts.to_vec())
618+
let mut parser = parse::tts_to_parser(self.parse_sess, tts.to_vec());
619+
parser.allow_interpolated_tts = false; // FIXME(jseyfried) `quote!` can't handle these yet
620+
parser
619621
}
620622
pub fn codemap(&self) -> &'a CodeMap { self.parse_sess.codemap() }
621623
pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }

src/libsyntax/ext/tt/macro_parser.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -496,10 +496,19 @@ pub fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
496496
match name {
497497
"tt" => {
498498
p.quote_depth += 1; //but in theory, non-quoted tts might be useful
499-
let res: ::parse::PResult<'a, _> = p.parse_token_tree();
500-
let res = token::NtTT(panictry!(res));
499+
let mut tt = panictry!(p.parse_token_tree());
501500
p.quote_depth -= 1;
502-
return res;
501+
loop {
502+
let nt = match tt {
503+
TokenTree::Token(_, token::Interpolated(ref nt)) => nt.clone(),
504+
_ => break,
505+
};
506+
match *nt {
507+
token::NtTT(ref sub_tt) => tt = sub_tt.clone(),
508+
_ => break,
509+
}
510+
}
511+
return token::NtTT(tt);
503512
}
504513
_ => {}
505514
}

src/libsyntax/parse/parser.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ pub struct Parser<'a> {
212212
pub expected_tokens: Vec<TokenType>,
213213
pub tts: Vec<(TokenTree, usize)>,
214214
pub desugar_doc_comments: bool,
215+
pub allow_interpolated_tts: bool,
215216
}
216217

217218
#[derive(PartialEq, Eq, Clone)]
@@ -301,6 +302,7 @@ impl<'a> Parser<'a> {
301302
expected_tokens: Vec::new(),
302303
tts: Vec::new(),
303304
desugar_doc_comments: desugar_doc_comments,
305+
allow_interpolated_tts: true,
304306
};
305307

306308
let tok = parser.next_tok();
@@ -2718,7 +2720,12 @@ impl<'a> Parser<'a> {
27182720
if self.tts.last().map(|&(_, i)| i == 1).unwrap_or(false) {
27192721
let tt = self.tts.pop().unwrap().0;
27202722
self.bump();
2721-
return Ok(tt);
2723+
return Ok(if self.allow_interpolated_tts {
2724+
// avoid needlessly reparsing token trees in recursive macro expansions
2725+
TokenTree::Token(tt.span(), token::Interpolated(Rc::new(token::NtTT(tt))))
2726+
} else {
2727+
tt
2728+
});
27222729
}
27232730

27242731
let parsing_token_tree = ::std::mem::replace(&mut self.parsing_token_tree, true);

0 commit comments

Comments
 (0)