@@ -122,7 +122,7 @@ impl<'tt> TokenTreeOrTokenTreeSlice<'tt> {
122
122
123
123
/// An unzipping of `TokenTree`s... see the `stack` field of `MatcherPos`.
124
124
///
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
126
126
/// descended into.
127
127
#[ derive( Clone ) ]
128
128
struct MatcherTtFrame < ' tt > {
@@ -480,21 +480,24 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool {
480
480
/// successful execution of this function.
481
481
/// - `next_items`: the set of newly generated items. These are used to replenish `cur_items` in
482
482
/// the function `parse`.
483
- /// - `eof_items`: the set of items that would be valid if this was the EOF.
484
483
/// - `bb_items`: the set of items that are waiting for the black-box parser.
485
484
/// - `token`: the current token of the parser.
486
485
///
487
486
/// # Returns
488
487
///
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 > (
491
491
sess : & ParseSess ,
492
+ ms : & [ TokenTree ] ,
492
493
cur_items : & mut SmallVec < [ MatcherPosHandle < ' root , ' tt > ; 1 ] > ,
493
494
next_items : & mut Vec < MatcherPosHandle < ' root , ' tt > > ,
494
495
bb_items : & mut SmallVec < [ MatcherPosHandle < ' root , ' tt > ; 1 ] > ,
495
- eof_items : & mut EofItems < ' root , ' tt > ,
496
496
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
+
498
501
// Pop items from `cur_items` until it is empty.
499
502
while let Some ( mut item) = cur_items. pop ( ) {
500
503
// When unzipped trees end, remove them. This corresponds to backtracking out of a
@@ -566,7 +569,7 @@ fn inner_parse_loop<'root, 'tt>(
566
569
} else {
567
570
// If we are not in a repetition, then being at the end of a matcher means that we
568
571
// have reached the potential end of the input.
569
- * eof_items = match eof_items {
572
+ eof_items = match eof_items {
570
573
EofItems :: None => EofItems :: One ( item) ,
571
574
EofItems :: One ( _) | EofItems :: Multiple => EofItems :: Multiple ,
572
575
}
@@ -614,7 +617,7 @@ fn inner_parse_loop<'root, 'tt>(
614
617
// We need to match a metavar (but the identifier is invalid)... this is an error
615
618
TokenTree :: MetaVarDecl ( span, _, None ) => {
616
619
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 ( ) ) ) ;
618
621
}
619
622
}
620
623
@@ -663,8 +666,29 @@ fn inner_parse_loop<'root, 'tt>(
663
666
}
664
667
}
665
668
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
+ }
668
692
}
669
693
670
694
/// Use the given sequence of token trees (`ms`) as a matcher. Match the token
@@ -675,7 +699,7 @@ pub(super) fn parse_tt(
675
699
macro_name : Ident ,
676
700
) -> NamedParseResult {
677
701
// 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
679
703
// processes all of these possible matcher positions and produces possible next positions into
680
704
// `next_items`. After some post-processing, the contents of `next_items` replenish `cur_items`
681
705
// and we start over again.
@@ -692,61 +716,27 @@ pub(super) fn parse_tt(
692
716
// Matcher positions black-box parsed by parser.rs (`parser`)
693
717
let mut bb_items = SmallVec :: new ( ) ;
694
718
695
- // Matcher positions that would be valid if the macro invocation was over now
696
- let mut eof_items = EofItems :: None ;
697
-
698
719
// Process `cur_items` until either we have finished the input or we need to get some
699
720
// parsing from the black-box parser done. The result is that `next_items` will contain a
700
721
// bunch of possible next matcher positions in `next_items`.
701
- match inner_parse_loop (
722
+ if let Some ( result ) = parse_tt_inner (
702
723
parser. sess ,
724
+ ms,
703
725
& mut cur_items,
704
726
& mut next_items,
705
727
& mut bb_items,
706
- & mut eof_items,
707
728
& parser. token ,
708
729
) {
709
- Ok ( ( ) ) => { }
710
- Err ( ( sp, msg) ) => return Error ( sp, msg) ,
730
+ return result;
711
731
}
712
732
713
- // inner parse loop handled all cur_items, so it's empty
733
+ // `parse_tt_inner` handled all cur_items, so it's empty.
714
734
assert ! ( cur_items. is_empty( ) ) ;
715
735
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 `.
717
737
//
718
738
// Error messages here could be improved with links to original rules.
719
739
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
-
750
740
match ( next_items. len ( ) , bb_items. len ( ) ) {
751
741
( 0 , 0 ) => {
752
742
// There are no possible next positions AND we aren't waiting for the black-box
0 commit comments