@@ -122,7 +122,7 @@ impl<'tt> TokenTreeOrTokenTreeSlice<'tt> {
122122
123123/// An unzipping of `TokenTree`s... see the `stack` field of `MatcherPos`.
124124///
125- /// This is used by `inner_parse_loop ` to keep track of delimited submatchers that we have
125+ /// This is used by `parse_tt_inner ` to keep track of delimited submatchers that we have
126126/// descended into.
127127#[ derive( Clone ) ]
128128struct MatcherTtFrame < ' tt > {
@@ -480,21 +480,24 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool {
480480/// successful execution of this function.
481481/// - `next_items`: the set of newly generated items. These are used to replenish `cur_items` in
482482/// the function `parse`.
483- /// - `eof_items`: the set of items that would be valid if this was the EOF.
484483/// - `bb_items`: the set of items that are waiting for the black-box parser.
485484/// - `token`: the current token of the parser.
486485///
487486/// # Returns
488487///
489- /// A `ParseResult`. Note that matches are kept track of through the items generated.
490- fn inner_parse_loop < ' root , ' tt > (
488+ /// `Some(result)` if everything is finished, `None` otherwise. Note that matches are kept track of
489+ /// through the items generated.
490+ fn parse_tt_inner < ' root , ' tt > (
491491 sess : & ParseSess ,
492+ ms : & [ TokenTree ] ,
492493 cur_items : & mut SmallVec < [ MatcherPosHandle < ' root , ' tt > ; 1 ] > ,
493494 next_items : & mut Vec < MatcherPosHandle < ' root , ' tt > > ,
494495 bb_items : & mut SmallVec < [ MatcherPosHandle < ' root , ' tt > ; 1 ] > ,
495- eof_items : & mut EofItems < ' root , ' tt > ,
496496 token : & Token ,
497- ) -> Result < ( ) , ( rustc_span:: Span , String ) > {
497+ ) -> Option < NamedParseResult > {
498+ // Matcher positions that would be valid if the macro invocation was over now
499+ let mut eof_items = EofItems :: None ;
500+
498501 // Pop items from `cur_items` until it is empty.
499502 while let Some ( mut item) = cur_items. pop ( ) {
500503 // When unzipped trees end, remove them. This corresponds to backtracking out of a
@@ -566,7 +569,7 @@ fn inner_parse_loop<'root, 'tt>(
566569 } else {
567570 // If we are not in a repetition, then being at the end of a matcher means that we
568571 // have reached the potential end of the input.
569- * eof_items = match eof_items {
572+ eof_items = match eof_items {
570573 EofItems :: None => EofItems :: One ( item) ,
571574 EofItems :: One ( _) | EofItems :: Multiple => EofItems :: Multiple ,
572575 }
@@ -614,7 +617,7 @@ fn inner_parse_loop<'root, 'tt>(
614617 // We need to match a metavar (but the identifier is invalid)... this is an error
615618 TokenTree :: MetaVarDecl ( span, _, None ) => {
616619 if sess. missing_fragment_specifiers . borrow_mut ( ) . remove ( & span) . is_some ( ) {
617- return Err ( ( span, "missing fragment specifier" . to_string ( ) ) ) ;
620+ return Some ( Error ( span, "missing fragment specifier" . to_string ( ) ) ) ;
618621 }
619622 }
620623
@@ -663,8 +666,29 @@ fn inner_parse_loop<'root, 'tt>(
663666 }
664667 }
665668
666- // Yay a successful parse (so far)!
667- Ok ( ( ) )
669+ // If we reached the EOF, check that there is EXACTLY ONE possible matcher. Otherwise,
670+ // either the parse is ambiguous (which should never happen) or there is a syntax error.
671+ if * token == token:: Eof {
672+ Some ( match eof_items {
673+ EofItems :: One ( mut eof_item) => {
674+ let matches =
675+ eof_item. matches . iter_mut ( ) . map ( |dv| Lrc :: make_mut ( dv) . pop ( ) . unwrap ( ) ) ;
676+ nameize ( sess, ms, matches)
677+ }
678+ EofItems :: Multiple => {
679+ Error ( token. span , "ambiguity: multiple successful parses" . to_string ( ) )
680+ }
681+ EofItems :: None => Failure (
682+ Token :: new (
683+ token:: Eof ,
684+ if token. span . is_dummy ( ) { token. span } else { token. span . shrink_to_hi ( ) } ,
685+ ) ,
686+ "missing tokens in macro arguments" ,
687+ ) ,
688+ } )
689+ } else {
690+ None
691+ }
668692}
669693
670694/// Use the given sequence of token trees (`ms`) as a matcher. Match the token
@@ -675,7 +699,7 @@ pub(super) fn parse_tt(
675699 macro_name : Ident ,
676700) -> NamedParseResult {
677701 // A queue of possible matcher positions. We initialize it with the matcher position in which
678- // the "dot" is before the first token of the first token tree in `ms`. `inner_parse_loop ` then
702+ // the "dot" is before the first token of the first token tree in `ms`. `parse_tt_inner ` then
679703 // processes all of these possible matcher positions and produces possible next positions into
680704 // `next_items`. After some post-processing, the contents of `next_items` replenish `cur_items`
681705 // and we start over again.
@@ -692,61 +716,27 @@ pub(super) fn parse_tt(
692716 // Matcher positions black-box parsed by parser.rs (`parser`)
693717 let mut bb_items = SmallVec :: new ( ) ;
694718
695- // Matcher positions that would be valid if the macro invocation was over now
696- let mut eof_items = EofItems :: None ;
697-
698719 // Process `cur_items` until either we have finished the input or we need to get some
699720 // parsing from the black-box parser done. The result is that `next_items` will contain a
700721 // bunch of possible next matcher positions in `next_items`.
701- match inner_parse_loop (
722+ if let Some ( result ) = parse_tt_inner (
702723 parser. sess ,
724+ ms,
703725 & mut cur_items,
704726 & mut next_items,
705727 & mut bb_items,
706- & mut eof_items,
707728 & parser. token ,
708729 ) {
709- Ok ( ( ) ) => { }
710- Err ( ( sp, msg) ) => return Error ( sp, msg) ,
730+ return result;
711731 }
712732
713- // inner parse loop handled all cur_items, so it's empty
733+ // `parse_tt_inner` handled all cur_items, so it's empty.
714734 assert ! ( cur_items. is_empty( ) ) ;
715735
716- // We need to do some post processing after the `inner_parse_loop `.
736+ // We need to do some post processing after the `parse_tt_inner `.
717737 //
718738 // Error messages here could be improved with links to original rules.
719739
720- // If we reached the EOF, check that there is EXACTLY ONE possible matcher. Otherwise,
721- // either the parse is ambiguous (which should never happen) or there is a syntax error.
722- if parser. token == token:: Eof {
723- return match eof_items {
724- EofItems :: One ( mut eof_item) => {
725- let matches =
726- eof_item. matches . iter_mut ( ) . map ( |dv| Lrc :: make_mut ( dv) . pop ( ) . unwrap ( ) ) ;
727- nameize ( parser. sess , ms, matches)
728- }
729- EofItems :: Multiple => {
730- Error ( parser. token . span , "ambiguity: multiple successful parses" . to_string ( ) )
731- }
732- EofItems :: None => Failure (
733- Token :: new (
734- token:: Eof ,
735- if parser. token . span . is_dummy ( ) {
736- parser. token . span
737- } else {
738- parser. token . span . shrink_to_hi ( )
739- } ,
740- ) ,
741- "missing tokens in macro arguments" ,
742- ) ,
743- } ;
744- }
745- // Performance hack: `eof_items` may share matchers via `Rc` with other things that we want
746- // to modify. Dropping `eof_items` now may drop these refcounts to 1, preventing an
747- // unnecessary implicit clone later in `Rc::make_mut`.
748- drop ( eof_items) ;
749-
750740 match ( next_items. len ( ) , bb_items. len ( ) ) {
751741 ( 0 , 0 ) => {
752742 // There are no possible next positions AND we aren't waiting for the black-box
0 commit comments