@@ -266,6 +266,12 @@ impl<'root, 'tt> DerefMut for MatcherPosHandle<'root, 'tt> {
266
266
}
267
267
}
268
268
269
+ enum EofItems < ' root , ' tt > {
270
+ None ,
271
+ One ( MatcherPosHandle < ' root , ' tt > ) ,
272
+ Multiple ,
273
+ }
274
+
269
275
/// Represents the possible results of an attempted parse.
270
276
crate enum ParseResult < T > {
271
277
/// Parsed successfully.
@@ -449,10 +455,10 @@ fn inner_parse_loop<'root, 'tt>(
449
455
sess : & ParseSess ,
450
456
cur_items : & mut SmallVec < [ MatcherPosHandle < ' root , ' tt > ; 1 ] > ,
451
457
next_items : & mut Vec < MatcherPosHandle < ' root , ' tt > > ,
452
- eof_items : & mut SmallVec < [ MatcherPosHandle < ' root , ' tt > ; 1 ] > ,
453
458
bb_items : & mut SmallVec < [ MatcherPosHandle < ' root , ' tt > ; 1 ] > ,
459
+ eof_items : & mut EofItems < ' root , ' tt > ,
454
460
token : & Token ,
455
- ) -> ParseResult < ( ) > {
461
+ ) -> Result < ( ) , ( rustc_span :: Span , String ) > {
456
462
// Pop items from `cur_items` until it is empty.
457
463
while let Some ( mut item) = cur_items. pop ( ) {
458
464
// When unzipped trees end, remove them. This corresponds to backtracking out of a
@@ -522,7 +528,10 @@ fn inner_parse_loop<'root, 'tt>(
522
528
} else {
523
529
// If we are not in a repetition, then being at the end of a matcher means that we
524
530
// 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
+ }
526
535
}
527
536
} else {
528
537
// 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>(
567
576
// We need to match a metavar (but the identifier is invalid)... this is an error
568
577
TokenTree :: MetaVarDecl ( span, _, None ) => {
569
578
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 ( ) ) ) ;
571
580
}
572
581
}
573
582
@@ -615,7 +624,7 @@ fn inner_parse_loop<'root, 'tt>(
615
624
}
616
625
617
626
// Yay a successful parse (so far)!
618
- Success ( ( ) )
627
+ Ok ( ( ) )
619
628
}
620
629
621
630
/// Use the given sequence of token trees (`ms`) as a matcher. Match the token
@@ -638,12 +647,13 @@ pub(super) fn parse_tt(
638
647
let mut next_items = Vec :: new ( ) ;
639
648
640
649
loop {
650
+ assert ! ( next_items. is_empty( ) ) ;
651
+
641
652
// Matcher positions black-box parsed by parser.rs (`parser`)
642
653
let mut bb_items = SmallVec :: new ( ) ;
643
654
644
655
// 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 ;
647
657
648
658
// Process `cur_items` until either we have finished the input or we need to get some
649
659
// 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(
652
662
parser. sess ,
653
663
& mut cur_items,
654
664
& mut next_items,
655
- & mut eof_items,
656
665
& mut bb_items,
666
+ & mut eof_items,
657
667
& parser. token ,
658
668
) {
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) ,
663
671
}
664
672
665
673
// inner parse loop handled all cur_items, so it's empty
666
674
assert ! ( cur_items. is_empty( ) ) ;
667
675
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 `.
669
677
//
670
678
// Error messages here could be improved with links to original rules.
671
679
672
680
// If we reached the EOF, check that there is EXACTLY ONE possible matcher. Otherwise,
673
681
// either the parse is ambiguous (which should never happen) or there is a syntax error.
674
682
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 (
683
693
Token :: new (
684
694
token:: Eof ,
685
695
if parser. token . span . is_dummy ( ) {
@@ -689,12 +699,12 @@ pub(super) fn parse_tt(
689
699
} ,
690
700
) ,
691
701
"missing tokens in macro arguments" ,
692
- )
702
+ ) ,
693
703
} ;
694
704
}
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` .
698
708
drop ( eof_items) ;
699
709
700
710
// If there are no possible next positions AND we aren't waiting for the black-box parser,
0 commit comments