@@ -540,67 +540,7 @@ fn parse_tt_inner<'root, 'tt>(
540540 let idx = item. idx ;
541541 let len = item. top_elts . len ( ) ;
542542
543- // If `idx >= len`, then we are at or past the end of the matcher of `item`.
544- if idx >= len {
545- // We are repeating iff there is a parent. If the matcher is inside of a repetition,
546- // then we could be at the end of a sequence or at the beginning of the next
547- // repetition.
548- if let Some ( repetition) = & item. repetition {
549- debug_assert ! ( idx <= len + 1 ) ;
550- debug_assert ! ( matches!( item. top_elts, Tt ( TokenTree :: Sequence ( ..) ) ) ) ;
551-
552- // At this point, regardless of whether there is a separator, we should add all
553- // matches from the complete repetition of the sequence to the shared, top-level
554- // `matches` list (actually, `up.matches`, which could itself not be the top-level,
555- // but anyway...). Moreover, we add another item to `cur_items` in which the "dot"
556- // is at the end of the `up` matcher. This ensures that the "dot" in the `up`
557- // matcher is also advanced sufficiently.
558- //
559- // NOTE: removing the condition `idx == len` allows trailing separators.
560- if idx == len {
561- // Get the `up` matcher
562- let mut new_pos = repetition. up . clone ( ) ;
563-
564- // Add matches from this repetition to the `matches` of `up`
565- for idx in item. match_lo ..item. match_hi {
566- let sub = item. matches [ idx] . clone ( ) ;
567- new_pos. push_match ( idx, MatchedSeq ( sub) ) ;
568- }
569-
570- // Move the "dot" past the repetition in `up`
571- new_pos. match_cur = item. match_hi ;
572- new_pos. idx += 1 ;
573- cur_items. push ( new_pos) ;
574- }
575-
576- // Check if we need a separator.
577- if idx == len && repetition. sep . is_some ( ) {
578- // We have a separator, and it is the current token. We can advance past the
579- // separator token.
580- if repetition. sep . as_ref ( ) . map_or ( false , |sep| token_name_eq ( token, sep) ) {
581- item. idx += 1 ;
582- next_items. push ( item) ;
583- }
584- } else if repetition. seq_op != mbe:: KleeneOp :: ZeroOrOne {
585- // We don't need a separator. Move the "dot" back to the beginning of the
586- // matcher and try to match again UNLESS we are only allowed to have _one_
587- // repetition.
588- item. match_cur = item. match_lo ;
589- item. idx = 0 ;
590- cur_items. push ( item) ;
591- }
592- } else {
593- // If we are not in a repetition, then being at the end of a matcher means that we
594- // have reached the potential end of the input.
595- debug_assert_eq ! ( idx, len) ;
596- if * token == token:: Eof {
597- eof_items = match eof_items {
598- EofItems :: None => EofItems :: One ( item) ,
599- EofItems :: One ( _) | EofItems :: Multiple => EofItems :: Multiple ,
600- }
601- }
602- }
603- } else {
543+ if idx < len {
604544 // We are in the middle of a matcher. Look at what token in the matcher we are trying
605545 // to match the current token (`token`) against. Depending on that, we may generate new
606546 // items.
@@ -677,6 +617,60 @@ fn parse_tt_inner<'root, 'tt>(
677617
678618 TokenTree :: MetaVar ( ..) | TokenTree :: MetaVarExpr ( ..) => unreachable ! ( ) ,
679619 }
620+ } else if let Some ( repetition) = & item. repetition {
621+ // We are past the end of a repetition.
622+ debug_assert ! ( idx <= len + 1 ) ;
623+ debug_assert ! ( matches!( item. top_elts, Tt ( TokenTree :: Sequence ( ..) ) ) ) ;
624+
625+ // At this point, regardless of whether there is a separator, we should add all
626+ // matches from the complete repetition of the sequence to the shared, top-level
627+ // `matches` list (actually, `up.matches`, which could itself not be the top-level,
628+ // but anyway...). Moreover, we add another item to `cur_items` in which the "dot"
629+ // is at the end of the `up` matcher. This ensures that the "dot" in the `up`
630+ // matcher is also advanced sufficiently.
631+ //
632+ // NOTE: removing the condition `idx == len` allows trailing separators.
633+ if idx == len {
634+ // Get the `up` matcher
635+ let mut new_pos = repetition. up . clone ( ) ;
636+
637+ // Add matches from this repetition to the `matches` of `up`
638+ for idx in item. match_lo ..item. match_hi {
639+ let sub = item. matches [ idx] . clone ( ) ;
640+ new_pos. push_match ( idx, MatchedSeq ( sub) ) ;
641+ }
642+
643+ // Move the "dot" past the repetition in `up`
644+ new_pos. match_cur = item. match_hi ;
645+ new_pos. idx += 1 ;
646+ cur_items. push ( new_pos) ;
647+ }
648+
649+ // Check if we need a separator.
650+ if idx == len && repetition. sep . is_some ( ) {
651+ // We have a separator, and it is the current token. We can advance past the
652+ // separator token.
653+ if repetition. sep . as_ref ( ) . map_or ( false , |sep| token_name_eq ( token, sep) ) {
654+ item. idx += 1 ;
655+ next_items. push ( item) ;
656+ }
657+ } else if repetition. seq_op != mbe:: KleeneOp :: ZeroOrOne {
658+ // We don't need a separator. Move the "dot" back to the beginning of the
659+ // matcher and try to match again UNLESS we are only allowed to have _one_
660+ // repetition.
661+ item. match_cur = item. match_lo ;
662+ item. idx = 0 ;
663+ cur_items. push ( item) ;
664+ }
665+ } else {
666+ // We are past the end of the matcher, and not in a repetition. Look for end of input.
667+ debug_assert_eq ! ( idx, len) ;
668+ if * token == token:: Eof {
669+ eof_items = match eof_items {
670+ EofItems :: None => EofItems :: One ( item) ,
671+ EofItems :: One ( _) | EofItems :: Multiple => EofItems :: Multiple ,
672+ }
673+ }
680674 }
681675 }
682676
0 commit comments