@@ -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