Factor out some code into MatcherPos::repetition.

Also move `create_matches` within `impl MatcherPos`, because it's only
used within that impl block.
This commit is contained in:
Nicholas Nethercote 2022-03-18 14:09:02 +11:00
parent 5bbbee5ba7
commit 8bd1bcad58

View file

@ -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<NamedMatchVec>]> {
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<SequenceRepetition>,
) -> 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<NamedMatchVec>]> {
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