mirror of https://github.com/rust-lang/rust.git
Refactor `Frame`.
It is currently an enum and the `tts` and `idx` fields are repeated across the two variants. This commit splits it into a struct `Frame` and an enum `FrameKind`, to factor out the duplication. The commit also renames `Frame::new` as `Frame::new_delimited` and adds `Frame::new_sequence`. I.e. both variants now have a constructor.
This commit is contained in:
parent
5ac017e772
commit
3a3a15d753
|
@ -39,26 +39,32 @@ impl MutVisitor for Marker {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`).
|
/// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`).
|
||||||
enum Frame<'a> {
|
struct Frame<'a> {
|
||||||
Delimited {
|
tts: &'a [mbe::TokenTree],
|
||||||
tts: &'a [mbe::TokenTree],
|
idx: usize,
|
||||||
idx: usize,
|
kind: FrameKind,
|
||||||
delim: Delimiter,
|
}
|
||||||
span: DelimSpan,
|
|
||||||
spacing: DelimSpacing,
|
enum FrameKind {
|
||||||
},
|
Delimited { delim: Delimiter, span: DelimSpan, spacing: DelimSpacing },
|
||||||
Sequence {
|
Sequence { sep: Option<Token>, kleene_op: KleeneOp },
|
||||||
tts: &'a [mbe::TokenTree],
|
|
||||||
idx: usize,
|
|
||||||
sep: Option<Token>,
|
|
||||||
kleene_op: KleeneOp,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Frame<'a> {
|
impl<'a> Frame<'a> {
|
||||||
/// Construct a new frame around the delimited set of tokens.
|
fn new_delimited(src: &'a mbe::Delimited, span: DelimSpan, spacing: DelimSpacing) -> Frame<'a> {
|
||||||
fn new(src: &'a mbe::Delimited, span: DelimSpan, spacing: DelimSpacing) -> Frame<'a> {
|
Frame {
|
||||||
Frame::Delimited { tts: &src.tts, idx: 0, delim: src.delim, span, spacing }
|
tts: &src.tts,
|
||||||
|
idx: 0,
|
||||||
|
kind: FrameKind::Delimited { delim: src.delim, span, spacing },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_sequence(
|
||||||
|
src: &'a mbe::SequenceRepetition,
|
||||||
|
sep: Option<Token>,
|
||||||
|
kleene_op: KleeneOp,
|
||||||
|
) -> Frame<'a> {
|
||||||
|
Frame { tts: &src.tts, idx: 0, kind: FrameKind::Sequence { sep, kleene_op } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,13 +72,9 @@ impl<'a> Iterator for Frame<'a> {
|
||||||
type Item = &'a mbe::TokenTree;
|
type Item = &'a mbe::TokenTree;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<&'a mbe::TokenTree> {
|
fn next(&mut self) -> Option<&'a mbe::TokenTree> {
|
||||||
match self {
|
let res = self.tts.get(self.idx);
|
||||||
Frame::Delimited { tts, idx, .. } | Frame::Sequence { tts, idx, .. } => {
|
self.idx += 1;
|
||||||
let res = tts.get(*idx);
|
res
|
||||||
*idx += 1;
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,8 +113,11 @@ pub(super) fn transcribe<'a>(
|
||||||
// We descend into the RHS (`src`), expanding things as we go. This stack contains the things
|
// We descend into the RHS (`src`), expanding things as we go. This stack contains the things
|
||||||
// we have yet to expand/are still expanding. We start the stack off with the whole RHS. The
|
// we have yet to expand/are still expanding. We start the stack off with the whole RHS. The
|
||||||
// choice of spacing values doesn't matter.
|
// choice of spacing values doesn't matter.
|
||||||
let mut stack: SmallVec<[Frame<'_>; 1]> =
|
let mut stack: SmallVec<[Frame<'_>; 1]> = smallvec![Frame::new_delimited(
|
||||||
smallvec![Frame::new(src, src_span, DelimSpacing::new(Spacing::Alone, Spacing::Alone))];
|
src,
|
||||||
|
src_span,
|
||||||
|
DelimSpacing::new(Spacing::Alone, Spacing::Alone)
|
||||||
|
)];
|
||||||
|
|
||||||
// As we descend in the RHS, we will need to be able to match nested sequences of matchers.
|
// As we descend in the RHS, we will need to be able to match nested sequences of matchers.
|
||||||
// `repeats` keeps track of where we are in matching at each level, with the last element being
|
// `repeats` keeps track of where we are in matching at each level, with the last element being
|
||||||
|
@ -142,11 +147,12 @@ pub(super) fn transcribe<'a>(
|
||||||
|
|
||||||
// Otherwise, if we have just reached the end of a sequence and we can keep repeating,
|
// Otherwise, if we have just reached the end of a sequence and we can keep repeating,
|
||||||
// go back to the beginning of the sequence.
|
// go back to the beginning of the sequence.
|
||||||
if let Frame::Sequence { idx, sep, .. } = stack.last_mut().unwrap() {
|
let frame = stack.last_mut().unwrap();
|
||||||
|
if let FrameKind::Sequence { sep, .. } = &frame.kind {
|
||||||
let (repeat_idx, repeat_len) = repeats.last_mut().unwrap();
|
let (repeat_idx, repeat_len) = repeats.last_mut().unwrap();
|
||||||
*repeat_idx += 1;
|
*repeat_idx += 1;
|
||||||
if repeat_idx < repeat_len {
|
if repeat_idx < repeat_len {
|
||||||
*idx = 0;
|
frame.idx = 0;
|
||||||
if let Some(sep) = sep {
|
if let Some(sep) = sep {
|
||||||
result.push(TokenTree::Token(sep.clone(), Spacing::Alone));
|
result.push(TokenTree::Token(sep.clone(), Spacing::Alone));
|
||||||
}
|
}
|
||||||
|
@ -157,16 +163,16 @@ pub(super) fn transcribe<'a>(
|
||||||
// We are done with the top of the stack. Pop it. Depending on what it was, we do
|
// We are done with the top of the stack. Pop it. Depending on what it was, we do
|
||||||
// different things. Note that the outermost item must be the delimited, wrapped RHS
|
// different things. Note that the outermost item must be the delimited, wrapped RHS
|
||||||
// that was passed in originally to `transcribe`.
|
// that was passed in originally to `transcribe`.
|
||||||
match stack.pop().unwrap() {
|
match stack.pop().unwrap().kind {
|
||||||
// Done with a sequence. Pop from repeats.
|
// Done with a sequence. Pop from repeats.
|
||||||
Frame::Sequence { .. } => {
|
FrameKind::Sequence { .. } => {
|
||||||
repeats.pop();
|
repeats.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are done processing a Delimited. If this is the top-level delimited, we are
|
// We are done processing a Delimited. If this is the top-level delimited, we are
|
||||||
// done. Otherwise, we unwind the result_stack to append what we have produced to
|
// done. Otherwise, we unwind the result_stack to append what we have produced to
|
||||||
// any previous results.
|
// any previous results.
|
||||||
Frame::Delimited { delim, span, mut spacing, .. } => {
|
FrameKind::Delimited { delim, span, mut spacing, .. } => {
|
||||||
// Hack to force-insert a space after `]` in certain case.
|
// Hack to force-insert a space after `]` in certain case.
|
||||||
// See discussion of the `hex-literal` crate in #114571.
|
// See discussion of the `hex-literal` crate in #114571.
|
||||||
if delim == Delimiter::Bracket {
|
if delim == Delimiter::Bracket {
|
||||||
|
@ -192,7 +198,7 @@ pub(super) fn transcribe<'a>(
|
||||||
// We are descending into a sequence. We first make sure that the matchers in the RHS
|
// We are descending into a sequence. We first make sure that the matchers in the RHS
|
||||||
// and the matches in `interp` have the same shape. Otherwise, either the caller or the
|
// and the matches in `interp` have the same shape. Otherwise, either the caller or the
|
||||||
// macro writer has made a mistake.
|
// macro writer has made a mistake.
|
||||||
seq @ mbe::TokenTree::Sequence(_, delimited) => {
|
seq @ mbe::TokenTree::Sequence(_, seq_rep) => {
|
||||||
match lockstep_iter_size(seq, interp, &repeats) {
|
match lockstep_iter_size(seq, interp, &repeats) {
|
||||||
LockstepIterSize::Unconstrained => {
|
LockstepIterSize::Unconstrained => {
|
||||||
return Err(cx
|
return Err(cx
|
||||||
|
@ -233,12 +239,11 @@ pub(super) fn transcribe<'a>(
|
||||||
// The first time we encounter the sequence we push it to the stack. It
|
// The first time we encounter the sequence we push it to the stack. It
|
||||||
// then gets reused (see the beginning of the loop) until we are done
|
// then gets reused (see the beginning of the loop) until we are done
|
||||||
// repeating.
|
// repeating.
|
||||||
stack.push(Frame::Sequence {
|
stack.push(Frame::new_sequence(
|
||||||
idx: 0,
|
seq_rep,
|
||||||
sep: seq.separator.clone(),
|
seq.separator.clone(),
|
||||||
tts: &delimited.tts,
|
seq.kleene.op,
|
||||||
kleene_op: seq.kleene.op,
|
));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -294,13 +299,7 @@ pub(super) fn transcribe<'a>(
|
||||||
// the previous results (from outside the Delimited).
|
// the previous results (from outside the Delimited).
|
||||||
mbe::TokenTree::Delimited(mut span, spacing, delimited) => {
|
mbe::TokenTree::Delimited(mut span, spacing, delimited) => {
|
||||||
mut_visit::visit_delim_span(&mut span, &mut marker);
|
mut_visit::visit_delim_span(&mut span, &mut marker);
|
||||||
stack.push(Frame::Delimited {
|
stack.push(Frame::new_delimited(delimited, span, *spacing));
|
||||||
tts: &delimited.tts,
|
|
||||||
delim: delimited.delim,
|
|
||||||
idx: 0,
|
|
||||||
span,
|
|
||||||
spacing: *spacing,
|
|
||||||
});
|
|
||||||
result_stack.push(mem::take(&mut result));
|
result_stack.push(mem::take(&mut result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -358,10 +357,13 @@ fn maybe_use_metavar_location(
|
||||||
) -> TokenTree {
|
) -> TokenTree {
|
||||||
let undelimited_seq = matches!(
|
let undelimited_seq = matches!(
|
||||||
stack.last(),
|
stack.last(),
|
||||||
Some(Frame::Sequence {
|
Some(Frame {
|
||||||
tts: [_],
|
tts: [_],
|
||||||
sep: None,
|
kind: FrameKind::Sequence {
|
||||||
kleene_op: KleeneOp::ZeroOrMore | KleeneOp::OneOrMore,
|
sep: None,
|
||||||
|
kleene_op: KleeneOp::ZeroOrMore | KleeneOp::OneOrMore,
|
||||||
|
..
|
||||||
|
},
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue