@@ -77,9 +77,9 @@ use TokenTreeOrTokenTreeSlice::*;
77
77
use crate :: mbe:: { self , TokenTree } ;
78
78
79
79
use rustc_ast:: token:: { self , DocComment , Nonterminal , Token } ;
80
- use rustc_parse:: parser:: Parser ;
80
+ use rustc_parse:: parser:: { OrPatNonterminalMode , Parser } ;
81
81
use rustc_session:: parse:: ParseSess ;
82
- use rustc_span:: symbol:: MacroRulesNormalizedIdent ;
82
+ use rustc_span:: { edition :: Edition , symbol:: MacroRulesNormalizedIdent } ;
83
83
84
84
use smallvec:: { smallvec, SmallVec } ;
85
85
@@ -414,6 +414,18 @@ fn token_name_eq(t1: &Token, t2: &Token) -> bool {
414
414
}
415
415
}
416
416
417
+ /// In edition 2015/18, `:pat` can only match `pat<no_top_alt>` because otherwise, we have
418
+ /// breakage. As of edition 2021, `:pat` matches `top_pat`.
419
+ ///
420
+ /// See <https://github.com/rust-lang/rust/issues/54883> for more info.
421
+ fn or_pat_mode ( edition : Edition ) -> OrPatNonterminalMode {
422
+ match edition {
423
+ Edition :: Edition2015 | Edition :: Edition2018 => OrPatNonterminalMode :: NoTopAlt ,
424
+ // FIXME(mark-i-m): uncomment this when edition 2021 machinery is added.
425
+ // Edition::Edition2021 => OrPatNonterminalMode::TopPat,
426
+ }
427
+ }
428
+
417
429
/// Process the matcher positions of `cur_items` until it is empty. In the process, this will
418
430
/// produce more items in `next_items`, `eof_items`, and `bb_items`.
419
431
///
@@ -553,10 +565,14 @@ fn inner_parse_loop<'root, 'tt>(
553
565
554
566
// We need to match a metavar with a valid ident... call out to the black-box
555
567
// parser by adding an item to `bb_items`.
556
- TokenTree :: MetaVarDecl ( _, _, kind) => {
557
- // Built-in nonterminals never start with these tokens,
558
- // so we can eliminate them from consideration.
559
- if Parser :: nonterminal_may_begin_with ( kind, token) {
568
+ TokenTree :: MetaVarDecl ( span, _, kind) => {
569
+ // Built-in nonterminals never start with these tokens, so we can eliminate
570
+ // them from consideration.
571
+ //
572
+ // We use the span of the metavariable declaration to determine any
573
+ // edition-specific matching behavior for non-terminals.
574
+ if Parser :: nonterminal_may_begin_with ( kind, token, or_pat_mode ( span. edition ( ) ) )
575
+ {
560
576
bb_items. push ( item) ;
561
577
}
562
578
}
@@ -717,7 +733,10 @@ pub(super) fn parse_tt(parser: &mut Cow<'_, Parser<'_>>, ms: &[TokenTree]) -> Na
717
733
let mut item = bb_items. pop ( ) . unwrap ( ) ;
718
734
if let TokenTree :: MetaVarDecl ( span, _, kind) = item. top_elts . get_tt ( item. idx ) {
719
735
let match_cur = item. match_cur ;
720
- let nt = match parser. to_mut ( ) . parse_nonterminal ( kind) {
736
+ // We use the span of the metavariable declaration to determine any
737
+ // edition-specific matching behavior for non-terminals.
738
+ let nt = match parser. to_mut ( ) . parse_nonterminal ( kind, or_pat_mode ( span. edition ( ) ) )
739
+ {
721
740
Err ( mut err) => {
722
741
err. span_label (
723
742
span,
0 commit comments