@@ -490,7 +490,7 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool {
490490}
491491
492492/// Process the matcher positions of `cur_items` until it is empty. In the process, this will
493- /// produce more items in `next_items`, `eof_items`, and `bb_items`.
493+ /// produce more items in `next_items` and `bb_items`.
494494///
495495/// For more info about the how this happens, see the module-level doc comments and the inline
496496/// comments of this function.
@@ -520,11 +520,10 @@ fn parse_tt_inner<'root, 'tt>(
520520 // `token == Eof`.
521521 let mut eof_items = EofItems :: None ;
522522
523- // Pop items from `cur_items` until it is empty.
524523 while let Some ( mut item) = cur_items. pop ( ) {
525524 // When unzipped trees end, remove them. This corresponds to backtracking out of a
526- // delimited submatcher into which we already descended. In backtracking out again, we need
527- // to advance the "dot" past the delimiters in the outer matcher.
525+ // delimited submatcher into which we already descended. When backtracking out again, we
526+ // need to advance the "dot" past the delimiters in the outer matcher.
528527 while item. idx >= item. top_elts . len ( ) {
529528 match item. stack . pop ( ) {
530529 Some ( MatcherTtFrame { elts, idx } ) => {
@@ -541,19 +540,12 @@ fn parse_tt_inner<'root, 'tt>(
541540 let len = item. top_elts . len ( ) ;
542541
543542 if idx < len {
544- // We are in the middle of a matcher. Look at what token in the matcher we are trying
545- // to match the current token (`token`) against. Depending on that, we may generate new
546- // items.
543+ // We are in the middle of a matcher. Compare the matcher's current tt against `token`.
547544 match item. top_elts . get_tt ( idx) {
548- // Need to descend into a sequence
549545 TokenTree :: Sequence ( sp, seq) => {
550- // Examine the case where there are 0 matches of this sequence. We are
551- // implicitly disallowing OneOrMore from having 0 matches here. Thus, that will
552- // result in a "no rules expected token" error by virtue of this matcher not
553- // working.
554- if seq. kleene . op == mbe:: KleeneOp :: ZeroOrMore
555- || seq. kleene . op == mbe:: KleeneOp :: ZeroOrOne
556- {
546+ let op = seq. kleene . op ;
547+ if op == mbe:: KleeneOp :: ZeroOrMore || op == mbe:: KleeneOp :: ZeroOrOne {
548+ // Allow for the possibility of zero matches of this sequence.
557549 let mut new_item = item. clone ( ) ;
558550 new_item. match_cur += seq. num_captures ;
559551 new_item. idx += 1 ;
@@ -563,20 +555,19 @@ fn parse_tt_inner<'root, 'tt>(
563555 cur_items. push ( new_item) ;
564556 }
565557
558+ // Allow for the possibility of one or more matches of this sequence.
566559 cur_items. push ( MatcherPosHandle :: Box ( Box :: new ( MatcherPos :: repetition (
567560 item, sp, seq,
568561 ) ) ) ) ;
569562 }
570563
571- // We need to match a metavar (but the identifier is invalid)... this is an error
572564 TokenTree :: MetaVarDecl ( span, _, None ) => {
565+ // E.g. `$e` instead of `$e:expr`.
573566 if sess. missing_fragment_specifiers . borrow_mut ( ) . remove ( & span) . is_some ( ) {
574567 return Some ( Error ( span, "missing fragment specifier" . to_string ( ) ) ) ;
575568 }
576569 }
577570
578- // We need to match a metavar with a valid ident... call out to the black-box
579- // parser by adding an item to `bb_items`.
580571 TokenTree :: MetaVarDecl ( _, _, Some ( kind) ) => {
581572 // Built-in nonterminals never start with these tokens, so we can eliminate
582573 // them from consideration.
@@ -588,69 +579,57 @@ fn parse_tt_inner<'root, 'tt>(
588579 }
589580 }
590581
591- // We need to descend into a delimited submatcher or a doc comment. To do this, we
592- // push the current matcher onto a stack and push a new item containing the
593- // submatcher onto `cur_items`.
594- //
595- // At the beginning of the loop, if we reach the end of the delimited submatcher,
596- // we pop the stack to backtrack out of the descent.
597582 seq @ ( TokenTree :: Delimited ( ..)
598583 | TokenTree :: Token ( Token { kind : DocComment ( ..) , .. } ) ) => {
584+ // To descend into a delimited submatcher or a doc comment, we push the current
585+ // matcher onto a stack and push a new item containing the submatcher onto
586+ // `cur_items`.
587+ //
588+ // At the beginning of the loop, if we reach the end of the delimited
589+ // submatcher, we pop the stack to backtrack out of the descent.
599590 let lower_elts = mem:: replace ( & mut item. top_elts , Tt ( seq) ) ;
600591 let idx = item. idx ;
601592 item. stack . push ( MatcherTtFrame { elts : lower_elts, idx } ) ;
602593 item. idx = 0 ;
603594 cur_items. push ( item) ;
604595 }
605596
606- // We just matched a normal token. We can just advance the parser.
607- TokenTree :: Token ( t) if token_name_eq ( & t, token) => {
608- item. idx += 1 ;
609- next_items. push ( item) ;
597+ TokenTree :: Token ( t) => {
598+ // If the token matches, we can just advance the parser. Otherwise, this match
599+ // hash failed, there is nothing to do, and hopefully another item in
600+ // `cur_items` will match.
601+ if token_name_eq ( & t, token) {
602+ item. idx += 1 ;
603+ next_items. push ( item) ;
604+ }
610605 }
611606
612- // There was another token that was not `token`... This means we can't add any
613- // rules. NOTE that this is not necessarily an error unless _all_ items in
614- // `cur_items` end up doing this. There may still be some other matchers that do
615- // end up working out.
616- TokenTree :: Token ( ..) => { }
617-
607+ // These cannot appear in a matcher.
618608 TokenTree :: MetaVar ( ..) | TokenTree :: MetaVarExpr ( ..) => unreachable ! ( ) ,
619609 }
620610 } else if let Some ( repetition) = & item. repetition {
621611 // We are past the end of a repetition.
622612 debug_assert ! ( idx <= len + 1 ) ;
623613 debug_assert ! ( matches!( item. top_elts, Tt ( TokenTree :: Sequence ( ..) ) ) ) ;
624614
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.
633615 if idx == len {
634- // Get the `up` matcher
616+ // Add all matches from the sequence to `up`, and move the "dot" past the
617+ // repetition in `up`. This allows for the case where the sequence matching is
618+ // finished.
635619 let mut new_pos = repetition. up . clone ( ) ;
636-
637- // Add matches from this repetition to the `matches` of `up`
638620 for idx in item. match_lo ..item. match_hi {
639621 let sub = item. matches [ idx] . clone ( ) ;
640622 new_pos. push_match ( idx, MatchedSeq ( sub) ) ;
641623 }
642-
643- // Move the "dot" past the repetition in `up`
644624 new_pos. match_cur = item. match_hi ;
645625 new_pos. idx += 1 ;
646626 cur_items. push ( new_pos) ;
647627 }
648628
649- // Check if we need a separator.
650629 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.
653630 if repetition. sep . as_ref ( ) . map_or ( false , |sep| token_name_eq ( token, sep) ) {
631+ // The matcher has a separator, and it matches the current token. We can
632+ // advance past the separator token.
654633 item. idx += 1 ;
655634 next_items. push ( item) ;
656635 }
@@ -674,8 +653,8 @@ fn parse_tt_inner<'root, 'tt>(
674653 }
675654 }
676655
677- // If we reached the EOF , check that there is EXACTLY ONE possible matcher. Otherwise,
678- // either the parse is ambiguous (which should never happen ) or there is a syntax error.
656+ // If we reached the end of input , check that there is EXACTLY ONE possible matcher. Otherwise,
657+ // either the parse is ambiguous (which is an error ) or there is a syntax error.
679658 if * token == token:: Eof {
680659 Some ( match eof_items {
681660 EofItems :: One ( mut eof_item) => {
@@ -712,20 +691,19 @@ pub(super) fn parse_tt(
712691 // `next_items`. After some post-processing, the contents of `next_items` replenish `cur_items`
713692 // and we start over again.
714693 //
715- // This MatcherPos instance is allocated on the stack. All others -- and
716- // there are frequently *no* others! -- are allocated on the heap.
694+ // This MatcherPos instance is allocated on the stack. All others -- and there are frequently
695+ // *no* others! -- are allocated on the heap.
717696 let mut initial = MatcherPos :: new ( ms) ;
718697 let mut cur_items = smallvec ! [ MatcherPosHandle :: Ref ( & mut initial) ] ;
719698
720699 loop {
721700 let mut next_items = SmallVec :: new ( ) ;
722701
723- // Matcher positions black-box parsed by parser.rs (`parser`)
702+ // Matcher positions black-box parsed by `Parser`.
724703 let mut bb_items = SmallVec :: new ( ) ;
725704
726705 // Process `cur_items` until either we have finished the input or we need to get some
727- // parsing from the black-box parser done. The result is that `next_items` will contain a
728- // bunch of possible next matcher positions in `next_items`.
706+ // parsing from the black-box parser done.
729707 if let Some ( result) = parse_tt_inner (
730708 parser. sess ,
731709 ms,
@@ -740,10 +718,7 @@ pub(super) fn parse_tt(
740718 // `parse_tt_inner` handled all cur_items, so it's empty.
741719 assert ! ( cur_items. is_empty( ) ) ;
742720
743- // We need to do some post processing after the `parse_tt_inner`.
744- //
745721 // Error messages here could be improved with links to original rules.
746-
747722 match ( next_items. len ( ) , bb_items. len ( ) ) {
748723 ( 0 , 0 ) => {
749724 // There are no possible next positions AND we aren't waiting for the black-box
@@ -787,8 +762,7 @@ pub(super) fn parse_tt(
787762 }
788763
789764 ( _, _) => {
790- // We need to call the black-box parser to get some nonterminal, but something is
791- // wrong.
765+ // Too many possibilities!
792766 return bb_items_ambiguity_error (
793767 macro_name,
794768 next_items,
0 commit comments