Fix partially consumed tokens in macro matchers.
This commit is contained in:
@@ -476,24 +476,21 @@ pub fn parse(sess: &ParseSess,
|
|||||||
}
|
}
|
||||||
rdr.next_token();
|
rdr.next_token();
|
||||||
} else /* bb_eis.len() == 1 */ {
|
} else /* bb_eis.len() == 1 */ {
|
||||||
let mut rust_parser = Parser::new(sess, cfg.clone(), Box::new(rdr.clone()));
|
rdr.next_tok = {
|
||||||
|
let mut rust_parser = Parser::new(sess, cfg.clone(), Box::new(&mut rdr));
|
||||||
let mut ei = bb_eis.pop().unwrap();
|
let mut ei = bb_eis.pop().unwrap();
|
||||||
match ei.top_elts.get_tt(ei.idx) {
|
if let TokenTree::Token(span, MatchNt(_, ident)) = ei.top_elts.get_tt(ei.idx) {
|
||||||
TokenTree::Token(span, MatchNt(_, ident)) => {
|
|
||||||
let match_cur = ei.match_cur;
|
let match_cur = ei.match_cur;
|
||||||
(&mut ei.matches[match_cur]).push(Rc::new(MatchedNonterminal(
|
(&mut ei.matches[match_cur]).push(Rc::new(MatchedNonterminal(
|
||||||
parse_nt(&mut rust_parser, span, &ident.name.as_str()))));
|
parse_nt(&mut rust_parser, span, &ident.name.as_str()))));
|
||||||
ei.idx += 1;
|
ei.idx += 1;
|
||||||
ei.match_cur += 1;
|
ei.match_cur += 1;
|
||||||
}
|
} else {
|
||||||
_ => panic!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
cur_eis.push(ei);
|
cur_eis.push(ei);
|
||||||
|
Some(TokenAndSpan { tok: rust_parser.token, sp: rust_parser.span })
|
||||||
for _ in 0..rust_parser.tokens_consumed {
|
};
|
||||||
let _ = rdr.next_token();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ pub struct TtReader<'a> {
|
|||||||
/* cached: */
|
/* cached: */
|
||||||
pub cur_tok: Token,
|
pub cur_tok: Token,
|
||||||
pub cur_span: Span,
|
pub cur_span: Span,
|
||||||
|
pub next_tok: Option<TokenAndSpan>,
|
||||||
/// Transform doc comments. Only useful in macro invocations
|
/// Transform doc comments. Only useful in macro invocations
|
||||||
pub desugar_doc_comments: bool,
|
pub desugar_doc_comments: bool,
|
||||||
pub fatal_errs: Vec<DiagnosticBuilder<'a>>,
|
pub fatal_errs: Vec<DiagnosticBuilder<'a>>,
|
||||||
@@ -100,6 +101,7 @@ pub fn new_tt_reader_with_doc_flag(sp_diag: &Handler,
|
|||||||
/* dummy values, never read: */
|
/* dummy values, never read: */
|
||||||
cur_tok: token::Eof,
|
cur_tok: token::Eof,
|
||||||
cur_span: DUMMY_SP,
|
cur_span: DUMMY_SP,
|
||||||
|
next_tok: None,
|
||||||
fatal_errs: Vec::new(),
|
fatal_errs: Vec::new(),
|
||||||
};
|
};
|
||||||
tt_next_token(&mut r); /* get cur_tok and cur_span set up */
|
tt_next_token(&mut r); /* get cur_tok and cur_span set up */
|
||||||
@@ -178,6 +180,9 @@ fn lockstep_iter_size(t: &TokenTree, r: &TtReader) -> LockstepIterSize {
|
|||||||
/// Return the next token from the TtReader.
|
/// Return the next token from the TtReader.
|
||||||
/// EFFECT: advances the reader's token field
|
/// EFFECT: advances the reader's token field
|
||||||
pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
|
pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
|
||||||
|
if let Some(tok) = r.next_tok.take() {
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
// FIXME(pcwalton): Bad copy?
|
// FIXME(pcwalton): Bad copy?
|
||||||
let ret_val = TokenAndSpan {
|
let ret_val = TokenAndSpan {
|
||||||
tok: r.cur_tok.clone(),
|
tok: r.cur_tok.clone(),
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ impl<'a> Reader for StringReader<'a> {
|
|||||||
|
|
||||||
impl<'a> Reader for TtReader<'a> {
|
impl<'a> Reader for TtReader<'a> {
|
||||||
fn is_eof(&self) -> bool {
|
fn is_eof(&self) -> bool {
|
||||||
self.cur_tok == token::Eof
|
self.peek().tok == token::Eof
|
||||||
}
|
}
|
||||||
fn try_next_token(&mut self) -> Result<TokenAndSpan, ()> {
|
fn try_next_token(&mut self) -> Result<TokenAndSpan, ()> {
|
||||||
assert!(self.fatal_errs.is_empty());
|
assert!(self.fatal_errs.is_empty());
|
||||||
@@ -165,10 +165,31 @@ impl<'a> Reader for TtReader<'a> {
|
|||||||
self.fatal_errs.clear();
|
self.fatal_errs.clear();
|
||||||
}
|
}
|
||||||
fn peek(&self) -> TokenAndSpan {
|
fn peek(&self) -> TokenAndSpan {
|
||||||
TokenAndSpan {
|
self.next_tok.clone().unwrap_or(TokenAndSpan {
|
||||||
tok: self.cur_tok.clone(),
|
tok: self.cur_tok.clone(),
|
||||||
sp: self.cur_span,
|
sp: self.cur_span,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, 'b> Reader for &'b mut TtReader<'a> {
|
||||||
|
fn is_eof(&self) -> bool {
|
||||||
|
(**self).is_eof()
|
||||||
|
}
|
||||||
|
fn try_next_token(&mut self) -> Result<TokenAndSpan, ()> {
|
||||||
|
(**self).try_next_token()
|
||||||
|
}
|
||||||
|
fn fatal(&self, m: &str) -> FatalError {
|
||||||
|
(**self).fatal(m)
|
||||||
|
}
|
||||||
|
fn err(&self, m: &str) {
|
||||||
|
(**self).err(m)
|
||||||
|
}
|
||||||
|
fn emit_fatal_errors(&mut self) {
|
||||||
|
(**self).emit_fatal_errors()
|
||||||
|
}
|
||||||
|
fn peek(&self) -> TokenAndSpan {
|
||||||
|
(**self).peek()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user