From 8bd1bcad5858eb79bd60f320c9251dd84aa3b017 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 18 Mar 2022 14:09:02 +1100 Subject: [PATCH] Factor out some code into `MatcherPos::repetition`. Also move `create_matches` within `impl MatcherPos`, because it's only used within that impl block. --- compiler/rustc_expand/src/mbe/macro_parser.rs | 65 +++++++++++-------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs index 7e5c2402b90..247327e94ba 100644 --- a/compiler/rustc_expand/src/mbe/macro_parser.rs +++ b/compiler/rustc_expand/src/mbe/macro_parser.rs @@ -74,7 +74,7 @@ crate use NamedMatch::*; crate use ParseResult::*; use TokenTreeOrTokenTreeSlice::*; -use crate::mbe::{self, TokenTree}; +use crate::mbe::{self, DelimSpan, SequenceRepetition, TokenTree}; use rustc_ast::token::{self, DocComment, Nonterminal, Token}; use rustc_parse::parser::Parser; @@ -203,6 +203,17 @@ struct MatcherPos<'root, 'tt> { rustc_data_structures::static_assert_size!(MatcherPos<'_, '_>, 240); impl<'root, 'tt> MatcherPos<'root, 'tt> { + /// `len` `Vec`s (initially shared and empty) that will store matches of metavars. + fn create_matches(len: usize) -> Box<[Lrc]> { + if len == 0 { + vec![] + } else { + let empty_matches = Lrc::new(SmallVec::new()); + vec![empty_matches; len] + } + .into_boxed_slice() + } + /// Generates the top-level matcher position in which the "dot" is before the first token of /// the matcher `ms`. fn new(ms: &'tt [TokenTree]) -> Self { @@ -217,7 +228,7 @@ impl<'root, 'tt> MatcherPos<'root, 'tt> { // Initialize `matches` to a bunch of empty `Vec`s -- one for each metavar in // `top_elts`. `match_lo` for `top_elts` is 0 and `match_hi` is `match_idx_hi`. // `match_cur` is 0 since we haven't actually matched anything yet. - matches: create_matches(match_idx_hi), + matches: Self::create_matches(match_idx_hi), match_lo: 0, match_cur: 0, match_hi: match_idx_hi, @@ -230,6 +241,27 @@ impl<'root, 'tt> MatcherPos<'root, 'tt> { } } + fn repetition( + up: MatcherPosHandle<'root, 'tt>, + sp: DelimSpan, + seq: Lrc, + ) -> Self { + MatcherPos { + stack: smallvec![], + idx: 0, + matches: Self::create_matches(up.matches.len()), + match_lo: up.match_cur, + match_cur: up.match_cur, + match_hi: up.match_cur + seq.num_captures, + repetition: Some(MatcherPosRepetition { + up, + sep: seq.separator.clone(), + seq_op: seq.kleene.op, + }), + top_elts: Tt(TokenTree::Sequence(sp, seq)), + } + } + /// Adds `m` as a named match for the `idx`-th metavar. fn push_match(&mut self, idx: usize, m: NamedMatch) { let matches = Lrc::make_mut(&mut self.matches[idx]); @@ -333,17 +365,6 @@ pub(super) fn count_names(ms: &[TokenTree]) -> usize { }) } -/// `len` `Vec`s (initially shared and empty) that will store matches of metavars. -fn create_matches(len: usize) -> Box<[Lrc]> { - if len == 0 { - vec![] - } else { - let empty_matches = Lrc::new(SmallVec::new()); - vec![empty_matches; len] - } - .into_boxed_slice() -} - /// `NamedMatch` is a pattern-match result for a single `token::MATCH_NONTERMINAL`: /// so it is associated with a single ident in a parse, and all /// `MatchedNonterminal`s in the `NamedMatch` have the same non-terminal type @@ -599,21 +620,9 @@ fn parse_tt_inner<'root, 'tt>( cur_items.push(new_item); } - let matches = create_matches(item.matches.len()); - cur_items.push(MatcherPosHandle::Box(Box::new(MatcherPos { - stack: smallvec![], - idx: 0, - matches, - match_lo: item.match_cur, - match_cur: item.match_cur, - match_hi: item.match_cur + seq.num_captures, - repetition: Some(MatcherPosRepetition { - up: item, - sep: seq.separator.clone(), - seq_op: seq.kleene.op, - }), - top_elts: Tt(TokenTree::Sequence(sp, seq)), - }))); + cur_items.push(MatcherPosHandle::Box(Box::new(MatcherPos::repetition( + item, sp, seq, + )))); } // We need to match a metavar (but the identifier is invalid)... this is an error