From 21699c41af325786cbda1dba2379710f98613c68 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 30 Mar 2022 11:21:32 +1100 Subject: [PATCH] Simplify exit of `Delimited` submatchers. Currently, we detect an exit from a `Delimited` submatcher when `idx` exceeds the bounds of the current submatcher *and* there is a `stack` entry. This commit changes it to something simpler: just look for a `CloseDelim` token. --- compiler/rustc_expand/src/mbe/macro_parser.rs | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index 18302ffdb8e1..1f86223634f2 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -75,7 +75,7 @@ crate use ParseResult::*; use crate::mbe::{self, SequenceRepetition, TokenTree}; -use rustc_ast::token::{self, DocComment, Nonterminal, Token}; +use rustc_ast::token::{self, DocComment, Nonterminal, Token, TokenKind}; use rustc_parse::parser::{NtOrTt, Parser}; use rustc_session::parse::ParseSess; use rustc_span::symbol::MacroRulesNormalizedIdent; @@ -454,18 +454,6 @@ impl<'tt> TtParser<'tt> { let mut eof_mps = EofMatcherPositions::None; while let Some(mut mp) = self.cur_mps.pop() { - // Backtrack out of delimited submatcher when necessary. When backtracking out again, - // we need to advance the "dot" past the delimiters in the parent matcher(s). - while mp.idx >= mp.tts.len() { - match mp.stack.pop() { - Some(MatcherPosFrame { tts, idx }) => { - mp.tts = tts; - mp.idx = idx + 1; - } - None => break, - } - } - // Get the current position of the "dot" (`idx`) in `mp` and the number of token // trees in the matcher (`len`). let idx = mp.idx; @@ -516,11 +504,10 @@ impl<'tt> TtParser<'tt> { TokenTree::Delimited(_, delimited) => { // To descend into a delimited submatcher, we push the current matcher onto - // a stack and push a new mp containing the submatcher onto `cur_mps`. - // - // At the beginning of the loop, if we reach the end of the delimited - // submatcher, we pop the stack to backtrack out of the descent. Note that - // we use `all_tts` to include the open and close delimiter tokens. + // a stack and push a new mp containing the submatcher onto `cur_mps`. When + // we reach the closing delimiter, we will pop the stack to backtrack out + // of the descent. Note that we use `all_tts` to include the open and close + // delimiter tokens. let tts = mem::replace(&mut mp.tts, &delimited.all_tts); let idx = mp.idx; mp.stack.push(MatcherPosFrame { tts, idx }); @@ -542,6 +529,13 @@ impl<'tt> TtParser<'tt> { mp.idx += 1; self.cur_mps.push(mp); } else if token_name_eq(&t, token) { + if let TokenKind::CloseDelim(_) = token.kind { + // Ascend out of the delimited submatcher. + debug_assert_eq!(idx, len - 1); + let frame = mp.stack.pop().unwrap(); + mp.tts = frame.tts; + mp.idx = frame.idx; + } mp.idx += 1; self.next_mps.push(mp); }