@@ -744,70 +744,77 @@ pub(super) fn parse_tt(
744
744
// unnecessary implicit clone later in `Rc::make_mut`.
745
745
drop ( eof_items) ;
746
746
747
- // If there are no possible next positions AND we aren't waiting for the black-box parser,
748
- // then there is a syntax error.
749
- if bb_items. is_empty ( ) && next_items. is_empty ( ) {
750
- return Failure ( parser. token . clone ( ) , "no rules expected this token in macro call" ) ;
751
- }
747
+ match ( next_items. len ( ) , bb_items. len ( ) ) {
748
+ ( 0 , 0 ) => {
749
+ // There are no possible next positions AND we aren't waiting for the black-box
750
+ // parser: syntax error.
751
+ return Failure ( parser. token . clone ( ) , "no rules expected this token in macro call" ) ;
752
+ }
752
753
753
- if ( !bb_items. is_empty ( ) && !next_items. is_empty ( ) ) || bb_items. len ( ) > 1 {
754
- // We need to call out to parse some rust nonterminal (black-box) parser. But something
755
- // is wrong, because there is not EXACTLY ONE of these.
756
- let nts = bb_items
757
- . iter ( )
758
- . map ( |item| match item. top_elts . get_tt ( item. idx ) {
759
- TokenTree :: MetaVarDecl ( _, bind, Some ( kind) ) => format ! ( "{} ('{}')" , kind, bind) ,
760
- _ => panic ! ( ) ,
761
- } )
762
- . collect :: < Vec < String > > ( )
763
- . join ( " or " ) ;
764
-
765
- return Error (
766
- parser. token . span ,
767
- format ! (
768
- "local ambiguity when calling macro `{macro_name}`: multiple parsing options: {}" ,
769
- match next_items. len( ) {
770
- 0 => format!( "built-in NTs {}." , nts) ,
771
- 1 => format!( "built-in NTs {} or 1 other option." , nts) ,
772
- n => format!( "built-in NTs {} or {} other options." , nts, n) ,
773
- }
774
- ) ,
775
- ) ;
776
- }
754
+ ( _, 0 ) => {
755
+ // Dump all possible `next_items` into `cur_items` for the next iteration. Then
756
+ // process the next token.
757
+ cur_items. extend ( next_items. drain ( ..) ) ;
758
+ parser. to_mut ( ) . bump ( ) ;
759
+ }
777
760
778
- if !next_items. is_empty ( ) {
779
- // Dump all possible `next_items` into `cur_items` for the next iteration. Then process
780
- // the next token.
781
- cur_items. extend ( next_items. drain ( ..) ) ;
782
- parser. to_mut ( ) . bump ( ) ;
783
- } else {
784
- // Finally, we have the case where we need to call the black-box parser to get some
785
- // nonterminal.
786
- assert_eq ! ( bb_items. len( ) , 1 ) ;
787
-
788
- let mut item = bb_items. pop ( ) . unwrap ( ) ;
789
- if let TokenTree :: MetaVarDecl ( span, _, Some ( kind) ) = item. top_elts . get_tt ( item. idx ) {
790
- let match_cur = item. match_cur ;
791
- // We use the span of the metavariable declaration to determine any
792
- // edition-specific matching behavior for non-terminals.
793
- let nt = match parser. to_mut ( ) . parse_nonterminal ( kind) {
794
- Err ( mut err) => {
795
- err. span_label (
796
- span,
797
- format ! ( "while parsing argument for this `{}` macro fragment" , kind) ,
798
- )
799
- . emit ( ) ;
800
- return ErrorReported ;
801
- }
802
- Ok ( nt) => nt,
803
- } ;
804
- item. push_match ( match_cur, MatchedNonterminal ( Lrc :: new ( nt) ) ) ;
805
- item. idx += 1 ;
806
- item. match_cur += 1 ;
807
- } else {
808
- unreachable ! ( )
761
+ ( 0 , 1 ) => {
762
+ // We need to call the black-box parser to get some nonterminal.
763
+ let mut item = bb_items. pop ( ) . unwrap ( ) ;
764
+ if let TokenTree :: MetaVarDecl ( span, _, Some ( kind) ) = item. top_elts . get_tt ( item. idx )
765
+ {
766
+ let match_cur = item. match_cur ;
767
+ // We use the span of the metavariable declaration to determine any
768
+ // edition-specific matching behavior for non-terminals.
769
+ let nt = match parser. to_mut ( ) . parse_nonterminal ( kind) {
770
+ Err ( mut err) => {
771
+ err. span_label (
772
+ span,
773
+ format ! (
774
+ "while parsing argument for this `{}` macro fragment" ,
775
+ kind
776
+ ) ,
777
+ )
778
+ . emit ( ) ;
779
+ return ErrorReported ;
780
+ }
781
+ Ok ( nt) => nt,
782
+ } ;
783
+ item. push_match ( match_cur, MatchedNonterminal ( Lrc :: new ( nt) ) ) ;
784
+ item. idx += 1 ;
785
+ item. match_cur += 1 ;
786
+ } else {
787
+ unreachable ! ( )
788
+ }
789
+ cur_items. push ( item) ;
790
+ }
791
+
792
+ ( _, _) => {
793
+ // We need to call the black-box parser to get some nonterminal, but something is
794
+ // wrong.
795
+ let nts = bb_items
796
+ . iter ( )
797
+ . map ( |item| match item. top_elts . get_tt ( item. idx ) {
798
+ TokenTree :: MetaVarDecl ( _, bind, Some ( kind) ) => {
799
+ format ! ( "{} ('{}')" , kind, bind)
800
+ }
801
+ _ => panic ! ( ) ,
802
+ } )
803
+ . collect :: < Vec < String > > ( )
804
+ . join ( " or " ) ;
805
+
806
+ return Error (
807
+ parser. token . span ,
808
+ format ! (
809
+ "local ambiguity when calling macro `{macro_name}`: multiple parsing options: {}" ,
810
+ match next_items. len( ) {
811
+ 0 => format!( "built-in NTs {}." , nts) ,
812
+ 1 => format!( "built-in NTs {} or 1 other option." , nts) ,
813
+ n => format!( "built-in NTs {} or {} other options." , nts, n) ,
814
+ }
815
+ ) ,
816
+ ) ;
809
817
}
810
- cur_items. push ( item) ;
811
818
}
812
819
813
820
assert ! ( !cur_items. is_empty( ) ) ;
0 commit comments