Improve tt
-heavy expansion performance.
This commit is contained in:
parent
7ae083383d
commit
23ad6fdb66
3 changed files with 23 additions and 5 deletions
|
@ -615,7 +615,9 @@ impl<'a> ExtCtxt<'a> {
|
||||||
|
|
||||||
pub fn new_parser_from_tts(&self, tts: &[tokenstream::TokenTree])
|
pub fn new_parser_from_tts(&self, tts: &[tokenstream::TokenTree])
|
||||||
-> parser::Parser<'a> {
|
-> 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 codemap(&self) -> &'a CodeMap { self.parse_sess.codemap() }
|
||||||
pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }
|
pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }
|
||||||
|
|
|
@ -496,10 +496,19 @@ pub fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
|
||||||
match name {
|
match name {
|
||||||
"tt" => {
|
"tt" => {
|
||||||
p.quote_depth += 1; //but in theory, non-quoted tts might be useful
|
p.quote_depth += 1; //but in theory, non-quoted tts might be useful
|
||||||
let res: ::parse::PResult<'a, _> = p.parse_token_tree();
|
let mut tt = panictry!(p.parse_token_tree());
|
||||||
let res = token::NtTT(panictry!(res));
|
|
||||||
p.quote_depth -= 1;
|
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);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,6 +212,7 @@ pub struct Parser<'a> {
|
||||||
pub expected_tokens: Vec<TokenType>,
|
pub expected_tokens: Vec<TokenType>,
|
||||||
pub tts: Vec<(TokenTree, usize)>,
|
pub tts: Vec<(TokenTree, usize)>,
|
||||||
pub desugar_doc_comments: bool,
|
pub desugar_doc_comments: bool,
|
||||||
|
pub allow_interpolated_tts: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
|
@ -301,6 +302,7 @@ impl<'a> Parser<'a> {
|
||||||
expected_tokens: Vec::new(),
|
expected_tokens: Vec::new(),
|
||||||
tts: Vec::new(),
|
tts: Vec::new(),
|
||||||
desugar_doc_comments: desugar_doc_comments,
|
desugar_doc_comments: desugar_doc_comments,
|
||||||
|
allow_interpolated_tts: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
let tok = parser.next_tok();
|
let tok = parser.next_tok();
|
||||||
|
@ -2718,7 +2720,12 @@ impl<'a> Parser<'a> {
|
||||||
if self.tts.last().map(|&(_, i)| i == 1).unwrap_or(false) {
|
if self.tts.last().map(|&(_, i)| i == 1).unwrap_or(false) {
|
||||||
let tt = self.tts.pop().unwrap().0;
|
let tt = self.tts.pop().unwrap().0;
|
||||||
self.bump();
|
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);
|
let parsing_token_tree = ::std::mem::replace(&mut self.parsing_token_tree, true);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue