Skip to content

Commit 40f54bd

Browse files
committed
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.
1 parent 134f623 commit 40f54bd

File tree

1 file changed

+50
-48
lines changed

1 file changed

+50
-48
lines changed

compiler/rustc_expand/src/mbe/transcribe.rs

+50-48
Original file line numberDiff line numberDiff line change
@@ -39,40 +39,42 @@ impl MutVisitor for Marker {
3939
}
4040

4141
/// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`).
42-
enum Frame<'a> {
43-
Delimited {
44-
tts: &'a [mbe::TokenTree],
45-
idx: usize,
46-
delim: Delimiter,
47-
span: DelimSpan,
48-
spacing: DelimSpacing,
49-
},
50-
Sequence {
51-
tts: &'a [mbe::TokenTree],
52-
idx: usize,
53-
sep: Option<Token>,
54-
kleene_op: KleeneOp,
55-
},
42+
struct Frame<'a> {
43+
tts: &'a [mbe::TokenTree],
44+
idx: usize,
45+
kind: FrameKind,
46+
}
47+
48+
enum FrameKind {
49+
Delimited { delim: Delimiter, span: DelimSpan, spacing: DelimSpacing },
50+
Sequence { sep: Option<Token>, kleene_op: KleeneOp },
5651
}
5752

5853
impl<'a> Frame<'a> {
59-
/// Construct a new frame around the delimited set of tokens.
60-
fn new(src: &'a mbe::Delimited, span: DelimSpan, spacing: DelimSpacing) -> Frame<'a> {
61-
Frame::Delimited { tts: &src.tts, idx: 0, delim: src.delim, span, spacing }
54+
fn new_delimited(src: &'a mbe::Delimited, span: DelimSpan, spacing: DelimSpacing) -> Frame<'a> {
55+
Frame {
56+
tts: &src.tts,
57+
idx: 0,
58+
kind: FrameKind::Delimited { delim: src.delim, span, spacing },
59+
}
60+
}
61+
62+
fn new_sequence(
63+
src: &'a mbe::SequenceRepetition,
64+
sep: Option<Token>,
65+
kleene_op: KleeneOp,
66+
) -> Frame<'a> {
67+
Frame { tts: &src.tts, idx: 0, kind: FrameKind::Sequence { sep, kleene_op } }
6268
}
6369
}
6470

6571
impl<'a> Iterator for Frame<'a> {
6672
type Item = &'a mbe::TokenTree;
6773

6874
fn next(&mut self) -> Option<&'a mbe::TokenTree> {
69-
match self {
70-
Frame::Delimited { tts, idx, .. } | Frame::Sequence { tts, idx, .. } => {
71-
let res = tts.get(*idx);
72-
*idx += 1;
73-
res
74-
}
75-
}
75+
let res = self.tts.get(self.idx);
76+
self.idx += 1;
77+
res
7678
}
7779
}
7880

@@ -111,8 +113,11 @@ pub(super) fn transcribe<'a>(
111113
// We descend into the RHS (`src`), expanding things as we go. This stack contains the things
112114
// we have yet to expand/are still expanding. We start the stack off with the whole RHS. The
113115
// choice of spacing values doesn't matter.
114-
let mut stack: SmallVec<[Frame<'_>; 1]> =
115-
smallvec![Frame::new(src, src_span, DelimSpacing::new(Spacing::Alone, Spacing::Alone))];
116+
let mut stack: SmallVec<[Frame<'_>; 1]> = smallvec![Frame::new_delimited(
117+
src,
118+
src_span,
119+
DelimSpacing::new(Spacing::Alone, Spacing::Alone)
120+
)];
116121

117122
// As we descend in the RHS, we will need to be able to match nested sequences of matchers.
118123
// `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>(
142147

143148
// Otherwise, if we have just reached the end of a sequence and we can keep repeating,
144149
// go back to the beginning of the sequence.
145-
if let Frame::Sequence { idx, sep, .. } = stack.last_mut().unwrap() {
150+
let frame = stack.last_mut().unwrap();
151+
if let FrameKind::Sequence { sep, .. } = &frame.kind {
146152
let (repeat_idx, repeat_len) = repeats.last_mut().unwrap();
147153
*repeat_idx += 1;
148154
if repeat_idx < repeat_len {
149-
*idx = 0;
155+
frame.idx = 0;
150156
if let Some(sep) = sep {
151157
result.push(TokenTree::Token(sep.clone(), Spacing::Alone));
152158
}
@@ -157,16 +163,16 @@ pub(super) fn transcribe<'a>(
157163
// We are done with the top of the stack. Pop it. Depending on what it was, we do
158164
// different things. Note that the outermost item must be the delimited, wrapped RHS
159165
// that was passed in originally to `transcribe`.
160-
match stack.pop().unwrap() {
166+
match stack.pop().unwrap().kind {
161167
// Done with a sequence. Pop from repeats.
162-
Frame::Sequence { .. } => {
168+
FrameKind::Sequence { .. } => {
163169
repeats.pop();
164170
}
165171

166172
// We are done processing a Delimited. If this is the top-level delimited, we are
167173
// done. Otherwise, we unwind the result_stack to append what we have produced to
168174
// any previous results.
169-
Frame::Delimited { delim, span, mut spacing, .. } => {
175+
FrameKind::Delimited { delim, span, mut spacing, .. } => {
170176
// Hack to force-insert a space after `]` in certain case.
171177
// See discussion of the `hex-literal` crate in #114571.
172178
if delim == Delimiter::Bracket {
@@ -192,7 +198,7 @@ pub(super) fn transcribe<'a>(
192198
// We are descending into a sequence. We first make sure that the matchers in the RHS
193199
// and the matches in `interp` have the same shape. Otherwise, either the caller or the
194200
// macro writer has made a mistake.
195-
seq @ mbe::TokenTree::Sequence(_, delimited) => {
201+
seq @ mbe::TokenTree::Sequence(_, seq_rep) => {
196202
match lockstep_iter_size(seq, interp, &repeats) {
197203
LockstepIterSize::Unconstrained => {
198204
return Err(cx
@@ -233,12 +239,11 @@ pub(super) fn transcribe<'a>(
233239
// The first time we encounter the sequence we push it to the stack. It
234240
// then gets reused (see the beginning of the loop) until we are done
235241
// repeating.
236-
stack.push(Frame::Sequence {
237-
idx: 0,
238-
sep: seq.separator.clone(),
239-
tts: &delimited.tts,
240-
kleene_op: seq.kleene.op,
241-
});
242+
stack.push(Frame::new_sequence(
243+
seq_rep,
244+
seq.separator.clone(),
245+
seq.kleene.op,
246+
));
242247
}
243248
}
244249
}
@@ -294,13 +299,7 @@ pub(super) fn transcribe<'a>(
294299
// the previous results (from outside the Delimited).
295300
mbe::TokenTree::Delimited(mut span, spacing, delimited) => {
296301
mut_visit::visit_delim_span(&mut span, &mut marker);
297-
stack.push(Frame::Delimited {
298-
tts: &delimited.tts,
299-
delim: delimited.delim,
300-
idx: 0,
301-
span,
302-
spacing: *spacing,
303-
});
302+
stack.push(Frame::new_delimited(delimited, span, *spacing));
304303
result_stack.push(mem::take(&mut result));
305304
}
306305

@@ -358,10 +357,13 @@ fn maybe_use_metavar_location(
358357
) -> TokenTree {
359358
let undelimited_seq = matches!(
360359
stack.last(),
361-
Some(Frame::Sequence {
360+
Some(Frame {
362361
tts: [_],
363-
sep: None,
364-
kleene_op: KleeneOp::ZeroOrMore | KleeneOp::OneOrMore,
362+
kind: FrameKind::Sequence {
363+
sep: None,
364+
kleene_op: KleeneOp::ZeroOrMore | KleeneOp::OneOrMore,
365+
..
366+
},
365367
..
366368
})
367369
);

0 commit comments

Comments
 (0)