@@ -11,7 +11,7 @@ use crate::mbe::transcribe::transcribe;
1111use rustc_ast as ast;
1212use rustc_ast:: token:: { self , NonterminalKind , NtTT , Token , TokenKind :: * } ;
1313use rustc_ast:: tokenstream:: { DelimSpan , TokenStream } ;
14- use rustc_ast:: NodeId ;
14+ use rustc_ast:: { NodeId , DUMMY_NODE_ID } ;
1515use rustc_ast_pretty:: pprust;
1616use rustc_attr:: { self as attr, TransparencyError } ;
1717use rustc_data_structures:: fx:: FxHashMap ;
@@ -471,7 +471,7 @@ pub fn compile_declarative_macro(
471471 )
472472 . pop ( )
473473 . unwrap ( ) ;
474- valid &= check_lhs_nt_follows ( & sess. parse_sess , features, & def. attrs , & tt) ;
474+ valid &= check_lhs_nt_follows ( & sess. parse_sess , features, & def, & tt) ;
475475 return tt;
476476 }
477477 }
@@ -540,13 +540,13 @@ pub fn compile_declarative_macro(
540540fn check_lhs_nt_follows (
541541 sess : & ParseSess ,
542542 features : & Features ,
543- attrs : & [ ast:: Attribute ] ,
543+ def : & ast:: Item ,
544544 lhs : & mbe:: TokenTree ,
545545) -> bool {
546546 // lhs is going to be like TokenTree::Delimited(...), where the
547547 // entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens.
548548 if let mbe:: TokenTree :: Delimited ( _, ref tts) = * lhs {
549- check_matcher ( sess, features, attrs , & tts. tts )
549+ check_matcher ( sess, features, def , & tts. tts )
550550 } else {
551551 let msg = "invalid macro matcher; matchers must be contained in balanced delimiters" ;
552552 sess. span_diagnostic . span_err ( lhs. span ( ) , msg) ;
@@ -604,13 +604,13 @@ fn check_rhs(sess: &ParseSess, rhs: &mbe::TokenTree) -> bool {
604604fn check_matcher (
605605 sess : & ParseSess ,
606606 features : & Features ,
607- attrs : & [ ast:: Attribute ] ,
607+ def : & ast:: Item ,
608608 matcher : & [ mbe:: TokenTree ] ,
609609) -> bool {
610610 let first_sets = FirstSets :: new ( matcher) ;
611611 let empty_suffix = TokenSet :: empty ( ) ;
612612 let err = sess. span_diagnostic . err_count ( ) ;
613- check_matcher_core ( sess, features, attrs , & first_sets, matcher, & empty_suffix) ;
613+ check_matcher_core ( sess, features, def , & first_sets, matcher, & empty_suffix) ;
614614 err == sess. span_diagnostic . err_count ( )
615615}
616616
@@ -857,7 +857,7 @@ impl TokenSet {
857857fn check_matcher_core (
858858 sess : & ParseSess ,
859859 features : & Features ,
860- attrs : & [ ast:: Attribute ] ,
860+ def : & ast:: Item ,
861861 first_sets : & FirstSets ,
862862 matcher : & [ mbe:: TokenTree ] ,
863863 follow : & TokenSet ,
@@ -903,7 +903,7 @@ fn check_matcher_core(
903903 }
904904 TokenTree :: Delimited ( span, ref d) => {
905905 let my_suffix = TokenSet :: singleton ( d. close_tt ( span) ) ;
906- check_matcher_core ( sess, features, attrs , first_sets, & d. tts , & my_suffix) ;
906+ check_matcher_core ( sess, features, def , first_sets, & d. tts , & my_suffix) ;
907907 // don't track non NT tokens
908908 last. replace_with_irrelevant ( ) ;
909909
@@ -936,7 +936,7 @@ fn check_matcher_core(
936936 // `my_suffix` is some TokenSet that we can use
937937 // for checking the interior of `seq_rep`.
938938 let next =
939- check_matcher_core ( sess, features, attrs , first_sets, & seq_rep. tts , my_suffix) ;
939+ check_matcher_core ( sess, features, def , first_sets, & seq_rep. tts , my_suffix) ;
940940 if next. maybe_empty {
941941 last. add_all ( & next) ;
942942 } else {
@@ -956,29 +956,31 @@ fn check_matcher_core(
956956 for token in & last. tokens {
957957 if let TokenTree :: MetaVarDecl ( span, name, Some ( kind) ) = * token {
958958 for next_token in & suffix_first. tokens {
959- // Check if the old pat is used and the next token is `|`.
960- if let NonterminalKind :: PatParam { inferred : true } = kind {
961- if let TokenTree :: Token ( token) = next_token {
962- if let BinOp ( token) = token. kind {
963- if let token:: BinOpToken :: Or = token {
964- // It is suggestion to use pat_param, for example: $x:pat -> $x:pat_param.
965- let suggestion = quoted_tt_to_string ( & TokenTree :: MetaVarDecl (
966- span,
967- name,
968- Some ( NonterminalKind :: PatParam { inferred : false } ) ,
969- ) ) ;
970- sess. buffer_lint_with_diagnostic (
971- & OR_PATTERNS_BACK_COMPAT ,
972- span,
973- ast:: CRATE_NODE_ID ,
974- & * format ! ( "the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro" , ) ,
975- BuiltinLintDiagnostics :: OrPatternsBackCompat (
976- span, suggestion,
977- ) ,
978- ) ;
979- }
980- }
981- }
959+ // Check if the old pat is used and the next token is `|`
960+ // to warn about incompatibility with Rust 2021.
961+ // We only emit this lint if we're parsing the original
962+ // definition of this macro_rules, not while (re)parsing
963+ // the macro when compiling another crate that is using the
964+ // macro. (See #86567.)
965+ // Macros defined in the current crate have a real node id,
966+ // whereas macros from an external crate have a dummy id.
967+ if def. id != DUMMY_NODE_ID
968+ && matches ! ( kind, NonterminalKind :: PatParam { inferred: true } )
969+ && matches ! ( next_token, TokenTree :: Token ( token) if token. kind == BinOp ( token:: BinOpToken :: Or ) )
970+ {
971+ // It is suggestion to use pat_param, for example: $x:pat -> $x:pat_param.
972+ let suggestion = quoted_tt_to_string ( & TokenTree :: MetaVarDecl (
973+ span,
974+ name,
975+ Some ( NonterminalKind :: PatParam { inferred : false } ) ,
976+ ) ) ;
977+ sess. buffer_lint_with_diagnostic (
978+ & OR_PATTERNS_BACK_COMPAT ,
979+ span,
980+ ast:: CRATE_NODE_ID ,
981+ "the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro" ,
982+ BuiltinLintDiagnostics :: OrPatternsBackCompat ( span, suggestion) ,
983+ ) ;
982984 }
983985 match is_in_follow ( next_token, kind) {
984986 IsInFollow :: Yes => { }
0 commit comments