@@ -122,7 +122,9 @@ struct MatcherPos<'tt> {
122
122
/// submatcher, this is just the contents of that submatcher.
123
123
tts : & ' tt [ TokenTree ] ,
124
124
125
- /// The "dot" position within the current submatcher, i.e. the index into `tts`.
125
+ /// The "dot" position within the current submatcher, i.e. the index into `tts`. Can go one or
126
+ /// two positions past the final elements in `tts` when dealing with sequences, see
127
+ /// `parse_tt_inner` for details.
126
128
idx : usize ,
127
129
128
130
/// This vector ends up with one element per metavar in the *top-level* matcher, even when this
@@ -540,20 +542,26 @@ impl<'tt> TtParser<'tt> {
540
542
}
541
543
} else if let Some ( sequence) = & mp. sequence {
542
544
// We are past the end of a sequence.
543
- debug_assert ! ( idx <= len + 1 ) ;
545
+ // - If it has no separator, we must be only one past the end.
546
+ // - If it has a separator, we may be one past the end, in which case we must
547
+ // look for a separator. Or we may be two past the end, in which case we have
548
+ // already dealt with the separator.
549
+ debug_assert ! ( idx == len || idx == len + 1 && sequence. seq. separator. is_some( ) ) ;
544
550
545
551
if idx == len {
546
- // Add all matches from the sequence to `parent`, and move the "dot" past the
547
- // sequence in `parent`. This allows for the case where the sequence matching
548
- // is finished.
552
+ // Sequence matching may have finished: move the "dot" past the sequence in
553
+ // `parent`. This applies whether a separator is used or not. If sequence
554
+ // matching hasn't finished, this `new_mp` will fail quietly when it is
555
+ // processed next time around the loop.
549
556
let mut new_mp = sequence. parent . clone ( ) ;
550
557
new_mp. matches = mp. matches . clone ( ) ;
551
558
new_mp. match_cur = mp. match_cur ;
552
559
new_mp. idx += 1 ;
553
560
self . cur_mps . push ( new_mp) ;
554
561
}
555
562
556
- if idx == len && sequence. seq . separator . is_some ( ) {
563
+ if sequence. seq . separator . is_some ( ) && idx == len {
564
+ // Look for the separator.
557
565
if sequence
558
566
. seq
559
567
. separator
@@ -566,9 +574,10 @@ impl<'tt> TtParser<'tt> {
566
574
self . next_mps . push ( mp) ;
567
575
}
568
576
} else if sequence. seq . kleene . op != mbe:: KleeneOp :: ZeroOrOne {
569
- // We don't need a separator. Move the "dot" back to the beginning of the
570
- // matcher and try to match again UNLESS we are only allowed to have _one_
571
- // repetition.
577
+ // We don't need to look for a separator: either this sequence doesn't have
578
+ // one, or it does and we've already handled it. Also, we are allowed to have
579
+ // more than one repetition. Move the "dot" back to the beginning of the
580
+ // matcher and try to match again.
572
581
mp. match_cur -= sequence. seq . num_captures ;
573
582
mp. idx = 0 ;
574
583
self . cur_mps . push ( mp) ;
0 commit comments