@@ -184,17 +184,8 @@ struct MatcherPos<'root, 'tt> {
184184 /// in this matcher.
185185 match_hi : usize ,
186186
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 > > ,
198189
199190 /// Specifically used to "unzip" token trees. By "unzip", we mean to unwrap the delimiters from
200191 /// 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> {
219210 }
220211}
221212
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+
222226// Lots of MatcherPos instances are created at runtime. Allocating them on the
223227// heap is slow. Furthermore, using SmallVec<MatcherPos> to allocate them all
224228// 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
326330 // Haven't descended into any delimiters, so empty stack
327331 stack : smallvec ! [ ] ,
328332
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 ,
333335 }
334336}
335337
@@ -476,7 +478,7 @@ fn inner_parse_loop<'root, 'tt>(
476478 // We are repeating iff there is a parent. If the matcher is inside of a repetition,
477479 // then we could be at the end of a sequence or at the beginning of the next
478480 // repetition.
479- if item . up . is_some ( ) {
481+ if let Some ( repetition ) = & item . repetition {
480482 // At this point, regardless of whether there is a separator, we should add all
481483 // matches from the complete repetition of the sequence to the shared, top-level
482484 // `matches` list (actually, `up.matches`, which could itself not be the top-level,
@@ -487,7 +489,7 @@ fn inner_parse_loop<'root, 'tt>(
487489 // NOTE: removing the condition `idx == len` allows trailing separators.
488490 if idx == len {
489491 // Get the `up` matcher
490- let mut new_pos = item . up . clone ( ) . unwrap ( ) ;
492+ let mut new_pos = repetition . up . clone ( ) ;
491493
492494 // Add matches from this repetition to the `matches` of `up`
493495 for idx in item. match_lo ..item. match_hi {
@@ -502,14 +504,14 @@ fn inner_parse_loop<'root, 'tt>(
502504 }
503505
504506 // Check if we need a separator.
505- if idx == len && item . sep . is_some ( ) {
507+ if idx == len && repetition . sep . is_some ( ) {
506508 // We have a separator, and it is the current token. We can advance past the
507509 // 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) ) {
509511 item. idx += 1 ;
510512 next_items. push ( item) ;
511513 }
512- } else if item . seq_op != Some ( mbe:: KleeneOp :: ZeroOrOne ) {
514+ } else if repetition . seq_op != mbe:: KleeneOp :: ZeroOrOne {
513515 // We don't need a separator. Move the "dot" back to the beginning of the
514516 // matcher and try to match again UNLESS we are only allowed to have _one_
515517 // repetition.
@@ -548,14 +550,16 @@ fn inner_parse_loop<'root, 'tt>(
548550 let matches = create_matches ( item. matches . len ( ) ) ;
549551 cur_items. push ( MatcherPosHandle :: Box ( Box :: new ( MatcherPos {
550552 stack : smallvec ! [ ] ,
551- sep : seq. separator . clone ( ) ,
552- seq_op : Some ( seq. kleene . op ) ,
553553 idx : 0 ,
554554 matches,
555555 match_lo : item. match_cur ,
556556 match_cur : item. match_cur ,
557557 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+ } ) ,
559563 top_elts : Tt ( TokenTree :: Sequence ( sp, seq) ) ,
560564 } ) ) ) ;
561565 }
0 commit comments