@@ -266,6 +266,12 @@ impl<'root, 'tt> DerefMut for MatcherPosHandle<'root, 'tt> {
266266 }
267267}
268268
269+ enum EofItems < ' root , ' tt > {
270+ None ,
271+ One ( MatcherPosHandle < ' root , ' tt > ) ,
272+ Multiple ,
273+ }
274+
269275/// Represents the possible results of an attempted parse.
270276crate enum ParseResult < T > {
271277 /// Parsed successfully.
@@ -449,10 +455,10 @@ fn inner_parse_loop<'root, 'tt>(
449455 sess : & ParseSess ,
450456 cur_items : & mut SmallVec < [ MatcherPosHandle < ' root , ' tt > ; 1 ] > ,
451457 next_items : & mut Vec < MatcherPosHandle < ' root , ' tt > > ,
452- eof_items : & mut SmallVec < [ MatcherPosHandle < ' root , ' tt > ; 1 ] > ,
453458 bb_items : & mut SmallVec < [ MatcherPosHandle < ' root , ' tt > ; 1 ] > ,
459+ eof_items : & mut EofItems < ' root , ' tt > ,
454460 token : & Token ,
455- ) -> ParseResult < ( ) > {
461+ ) -> Result < ( ) , ( rustc_span :: Span , String ) > {
456462 // Pop items from `cur_items` until it is empty.
457463 while let Some ( mut item) = cur_items. pop ( ) {
458464 // When unzipped trees end, remove them. This corresponds to backtracking out of a
@@ -522,7 +528,10 @@ fn inner_parse_loop<'root, 'tt>(
522528 } else {
523529 // If we are not in a repetition, then being at the end of a matcher means that we
524530 // have reached the potential end of the input.
525- eof_items. push ( item) ;
531+ * eof_items = match eof_items {
532+ EofItems :: None => EofItems :: One ( item) ,
533+ EofItems :: One ( _) | EofItems :: Multiple => EofItems :: Multiple ,
534+ }
526535 }
527536 } else {
528537 // We are in the middle of a matcher. Look at what token in the matcher we are trying
@@ -567,7 +576,7 @@ fn inner_parse_loop<'root, 'tt>(
567576 // We need to match a metavar (but the identifier is invalid)... this is an error
568577 TokenTree :: MetaVarDecl ( span, _, None ) => {
569578 if sess. missing_fragment_specifiers . borrow_mut ( ) . remove ( & span) . is_some ( ) {
570- return Error ( span, "missing fragment specifier" . to_string ( ) ) ;
579+ return Err ( ( span, "missing fragment specifier" . to_string ( ) ) ) ;
571580 }
572581 }
573582
@@ -615,7 +624,7 @@ fn inner_parse_loop<'root, 'tt>(
615624 }
616625
617626 // Yay a successful parse (so far)!
618- Success ( ( ) )
627+ Ok ( ( ) )
619628}
620629
621630/// Use the given sequence of token trees (`ms`) as a matcher. Match the token
@@ -638,12 +647,13 @@ pub(super) fn parse_tt(
638647 let mut next_items = Vec :: new ( ) ;
639648
640649 loop {
650+ assert ! ( next_items. is_empty( ) ) ;
651+
641652 // Matcher positions black-box parsed by parser.rs (`parser`)
642653 let mut bb_items = SmallVec :: new ( ) ;
643654
644655 // Matcher positions that would be valid if the macro invocation was over now
645- let mut eof_items = SmallVec :: new ( ) ;
646- assert ! ( next_items. is_empty( ) ) ;
656+ let mut eof_items = EofItems :: None ;
647657
648658 // Process `cur_items` until either we have finished the input or we need to get some
649659 // parsing from the black-box parser done. The result is that `next_items` will contain a
@@ -652,34 +662,34 @@ pub(super) fn parse_tt(
652662 parser. sess ,
653663 & mut cur_items,
654664 & mut next_items,
655- & mut eof_items,
656665 & mut bb_items,
666+ & mut eof_items,
657667 & parser. token ,
658668 ) {
659- Success ( _) => { }
660- Failure ( token, msg) => return Failure ( token, msg) ,
661- Error ( sp, msg) => return Error ( sp, msg) ,
662- ErrorReported => return ErrorReported ,
669+ Ok ( ( ) ) => { }
670+ Err ( ( sp, msg) ) => return Error ( sp, msg) ,
663671 }
664672
665673 // inner parse loop handled all cur_items, so it's empty
666674 assert ! ( cur_items. is_empty( ) ) ;
667675
668- // We need to do some post processing after the `inner_parser_loop `.
676+ // We need to do some post processing after the `inner_parse_loop `.
669677 //
670678 // Error messages here could be improved with links to original rules.
671679
672680 // If we reached the EOF, check that there is EXACTLY ONE possible matcher. Otherwise,
673681 // either the parse is ambiguous (which should never happen) or there is a syntax error.
674682 if parser. token == token:: Eof {
675- return if eof_items. len ( ) == 1 {
676- let matches =
677- eof_items[ 0 ] . matches . iter_mut ( ) . map ( |dv| Lrc :: make_mut ( dv) . pop ( ) . unwrap ( ) ) ;
678- nameize ( parser. sess , ms, matches)
679- } else if eof_items. len ( ) > 1 {
680- Error ( parser. token . span , "ambiguity: multiple successful parses" . to_string ( ) )
681- } else {
682- Failure (
683+ return match eof_items {
684+ EofItems :: One ( mut eof_item) => {
685+ let matches =
686+ eof_item. matches . iter_mut ( ) . map ( |dv| Lrc :: make_mut ( dv) . pop ( ) . unwrap ( ) ) ;
687+ nameize ( parser. sess , ms, matches)
688+ }
689+ EofItems :: Multiple => {
690+ Error ( parser. token . span , "ambiguity: multiple successful parses" . to_string ( ) )
691+ }
692+ EofItems :: None => Failure (
683693 Token :: new (
684694 token:: Eof ,
685695 if parser. token . span . is_dummy ( ) {
@@ -689,12 +699,12 @@ pub(super) fn parse_tt(
689699 } ,
690700 ) ,
691701 "missing tokens in macro arguments" ,
692- )
702+ ) ,
693703 } ;
694704 }
695- // Performance hack: eof_items may share matchers via Rc with other things that we want
696- // to modify. Dropping eof_items now may drop these refcounts to 1, preventing an
697- // unnecessary implicit clone later in Rc::make_mut.
705+ // Performance hack: ` eof_items` may share matchers via `Rc` with other things that we want
706+ // to modify. Dropping ` eof_items` now may drop these refcounts to 1, preventing an
707+ // unnecessary implicit clone later in ` Rc::make_mut` .
698708 drop ( eof_items) ;
699709
700710 // If there are no possible next positions AND we aren't waiting for the black-box parser,
0 commit comments