@@ -11,7 +11,7 @@ use crate::mbe::transcribe::transcribe;
11
11
use rustc_ast as ast;
12
12
use rustc_ast:: token:: { self , NonterminalKind , NtTT , Token , TokenKind :: * } ;
13
13
use rustc_ast:: tokenstream:: { DelimSpan , TokenStream } ;
14
- use rustc_ast:: NodeId ;
14
+ use rustc_ast:: { NodeId , DUMMY_NODE_ID } ;
15
15
use rustc_ast_pretty:: pprust;
16
16
use rustc_attr:: { self as attr, TransparencyError } ;
17
17
use rustc_data_structures:: fx:: FxHashMap ;
@@ -471,7 +471,7 @@ pub fn compile_declarative_macro(
471
471
)
472
472
. pop ( )
473
473
. 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) ;
475
475
return tt;
476
476
}
477
477
}
@@ -540,13 +540,13 @@ pub fn compile_declarative_macro(
540
540
fn check_lhs_nt_follows (
541
541
sess : & ParseSess ,
542
542
features : & Features ,
543
- attrs : & [ ast:: Attribute ] ,
543
+ def : & ast:: Item ,
544
544
lhs : & mbe:: TokenTree ,
545
545
) -> bool {
546
546
// lhs is going to be like TokenTree::Delimited(...), where the
547
547
// entire lhs is those tts. Or, it can be a "bare sequence", not wrapped in parens.
548
548
if let mbe:: TokenTree :: Delimited ( _, ref tts) = * lhs {
549
- check_matcher ( sess, features, attrs , & tts. tts )
549
+ check_matcher ( sess, features, def , & tts. tts )
550
550
} else {
551
551
let msg = "invalid macro matcher; matchers must be contained in balanced delimiters" ;
552
552
sess. span_diagnostic . span_err ( lhs. span ( ) , msg) ;
@@ -604,13 +604,13 @@ fn check_rhs(sess: &ParseSess, rhs: &mbe::TokenTree) -> bool {
604
604
fn check_matcher (
605
605
sess : & ParseSess ,
606
606
features : & Features ,
607
- attrs : & [ ast:: Attribute ] ,
607
+ def : & ast:: Item ,
608
608
matcher : & [ mbe:: TokenTree ] ,
609
609
) -> bool {
610
610
let first_sets = FirstSets :: new ( matcher) ;
611
611
let empty_suffix = TokenSet :: empty ( ) ;
612
612
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) ;
614
614
err == sess. span_diagnostic . err_count ( )
615
615
}
616
616
@@ -857,7 +857,7 @@ impl TokenSet {
857
857
fn check_matcher_core (
858
858
sess : & ParseSess ,
859
859
features : & Features ,
860
- attrs : & [ ast:: Attribute ] ,
860
+ def : & ast:: Item ,
861
861
first_sets : & FirstSets ,
862
862
matcher : & [ mbe:: TokenTree ] ,
863
863
follow : & TokenSet ,
@@ -903,7 +903,7 @@ fn check_matcher_core(
903
903
}
904
904
TokenTree :: Delimited ( span, ref d) => {
905
905
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) ;
907
907
// don't track non NT tokens
908
908
last. replace_with_irrelevant ( ) ;
909
909
@@ -936,7 +936,7 @@ fn check_matcher_core(
936
936
// `my_suffix` is some TokenSet that we can use
937
937
// for checking the interior of `seq_rep`.
938
938
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) ;
940
940
if next. maybe_empty {
941
941
last. add_all ( & next) ;
942
942
} else {
@@ -956,29 +956,31 @@ fn check_matcher_core(
956
956
for token in & last. tokens {
957
957
if let TokenTree :: MetaVarDecl ( span, name, Some ( kind) ) = * token {
958
958
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
+ ) ;
982
984
}
983
985
match is_in_follow ( next_token, kind) {
984
986
IsInFollow :: Yes => { }
0 commit comments