@@ -184,17 +184,8 @@ struct MatcherPos<'root, 'tt> {
184
184
/// in this matcher.
185
185
match_hi : usize ,
186
186
187
- // The following fields are used if we are matching a repetition. If we aren't, they should be
188
- // `None`.
189
- /// The KleeneOp of this sequence if we are in a repetition.
190
- seq_op : Option < mbe:: KleeneOp > ,
191
-
192
- /// The separator if we are in a repetition.
193
- sep : Option < Token > ,
194
-
195
- /// The "parent" matcher position if we are in a repetition. That is, the matcher position just
196
- /// before we enter the sequence.
197
- up : Option < MatcherPosHandle < ' root , ' tt > > ,
187
+ /// This field is only used if we are matching a repetition.
188
+ repetition : Option < MatcherPosRepetition < ' root , ' tt > > ,
198
189
199
190
/// Specifically used to "unzip" token trees. By "unzip", we mean to unwrap the delimiters from
200
191
/// a delimited token tree (e.g., something wrapped in `(` `)`) or to get the contents of a doc
@@ -219,6 +210,19 @@ impl<'root, 'tt> MatcherPos<'root, 'tt> {
219
210
}
220
211
}
221
212
213
+ #[ derive( Clone ) ]
214
+ struct MatcherPosRepetition < ' root , ' tt > {
215
+ /// The KleeneOp of this sequence.
216
+ seq_op : mbe:: KleeneOp ,
217
+
218
+ /// The separator.
219
+ sep : Option < Token > ,
220
+
221
+ /// The "parent" matcher position. That is, the matcher position just before we enter the
222
+ /// sequence.
223
+ up : MatcherPosHandle < ' root , ' tt > ,
224
+ }
225
+
222
226
// Lots of MatcherPos instances are created at runtime. Allocating them on the
223
227
// heap is slow. Furthermore, using SmallVec<MatcherPos> to allocate them all
224
228
// on the stack is also slow, because MatcherPos is quite a large type and
@@ -326,10 +330,8 @@ fn initial_matcher_pos<'root, 'tt>(ms: &'tt [TokenTree]) -> MatcherPos<'root, 't
326
330
// Haven't descended into any delimiters, so empty stack
327
331
stack : smallvec ! [ ] ,
328
332
329
- // Haven't descended into any sequences, so both of these are `None`.
330
- seq_op : None ,
331
- sep : None ,
332
- up : None ,
333
+ // Haven't descended into any sequences, so this is `None`.
334
+ repetition : None ,
333
335
}
334
336
}
335
337
@@ -476,7 +478,7 @@ fn inner_parse_loop<'root, 'tt>(
476
478
// We are repeating iff there is a parent. If the matcher is inside of a repetition,
477
479
// then we could be at the end of a sequence or at the beginning of the next
478
480
// repetition.
479
- if item . up . is_some ( ) {
481
+ if let Some ( repetition ) = & item . repetition {
480
482
// At this point, regardless of whether there is a separator, we should add all
481
483
// matches from the complete repetition of the sequence to the shared, top-level
482
484
// `matches` list (actually, `up.matches`, which could itself not be the top-level,
@@ -487,7 +489,7 @@ fn inner_parse_loop<'root, 'tt>(
487
489
// NOTE: removing the condition `idx == len` allows trailing separators.
488
490
if idx == len {
489
491
// Get the `up` matcher
490
- let mut new_pos = item . up . clone ( ) . unwrap ( ) ;
492
+ let mut new_pos = repetition . up . clone ( ) ;
491
493
492
494
// Add matches from this repetition to the `matches` of `up`
493
495
for idx in item. match_lo ..item. match_hi {
@@ -502,14 +504,14 @@ fn inner_parse_loop<'root, 'tt>(
502
504
}
503
505
504
506
// Check if we need a separator.
505
- if idx == len && item . sep . is_some ( ) {
507
+ if idx == len && repetition . sep . is_some ( ) {
506
508
// We have a separator, and it is the current token. We can advance past the
507
509
// separator token.
508
- if item . sep . as_ref ( ) . map_or ( false , |sep| token_name_eq ( token, sep) ) {
510
+ if repetition . sep . as_ref ( ) . map_or ( false , |sep| token_name_eq ( token, sep) ) {
509
511
item. idx += 1 ;
510
512
next_items. push ( item) ;
511
513
}
512
- } else if item . seq_op != Some ( mbe:: KleeneOp :: ZeroOrOne ) {
514
+ } else if repetition . seq_op != mbe:: KleeneOp :: ZeroOrOne {
513
515
// We don't need a separator. Move the "dot" back to the beginning of the
514
516
// matcher and try to match again UNLESS we are only allowed to have _one_
515
517
// repetition.
@@ -548,14 +550,16 @@ fn inner_parse_loop<'root, 'tt>(
548
550
let matches = create_matches ( item. matches . len ( ) ) ;
549
551
cur_items. push ( MatcherPosHandle :: Box ( Box :: new ( MatcherPos {
550
552
stack : smallvec ! [ ] ,
551
- sep : seq. separator . clone ( ) ,
552
- seq_op : Some ( seq. kleene . op ) ,
553
553
idx : 0 ,
554
554
matches,
555
555
match_lo : item. match_cur ,
556
556
match_cur : item. match_cur ,
557
557
match_hi : item. match_cur + seq. num_captures ,
558
- up : Some ( item) ,
558
+ repetition : Some ( MatcherPosRepetition {
559
+ up : item,
560
+ sep : seq. separator . clone ( ) ,
561
+ seq_op : seq. kleene . op ,
562
+ } ) ,
559
563
top_elts : Tt ( TokenTree :: Sequence ( sp, seq) ) ,
560
564
} ) ) ) ;
561
565
}
0 commit comments