]> git.lizzy.rs Git - rust.git/blobdiff - compiler/rustc_expand/src/mbe/macro_rules.rs
Rollup merge of #87596 - jesyspa:issue-87318-hidden-whitespace, r=estebank
[rust.git] / compiler / rustc_expand / src / mbe / macro_rules.rs
index 7f985af364d7dbf34369be8461e25bb690d69a91..9aee86c9e57ddec76967dae4e2276312e1b17ac1 100644 (file)
     /// The ident of the macro we're parsing
     macro_ident: Ident,
     lint_node_id: NodeId,
+    is_trailing_mac: bool,
     arm_span: Span,
+    /// Whether or not this macro is defined in the current crate
+    is_local: bool,
 }
 
 crate fn annotate_err_with_kind(
@@ -116,8 +119,15 @@ fn emit_frag_parse_err(
 
 impl<'a> ParserAnyMacro<'a> {
     crate fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
-        let ParserAnyMacro { site_span, macro_ident, ref mut parser, lint_node_id, arm_span } =
-            *self;
+        let ParserAnyMacro {
+            site_span,
+            macro_ident,
+            ref mut parser,
+            lint_node_id,
+            arm_span,
+            is_trailing_mac,
+            is_local,
+        } = *self;
         let snapshot = &mut parser.clone();
         let fragment = match parse_ast_fragment(parser, kind) {
             Ok(f) => f,
@@ -131,12 +141,15 @@ impl<'a> ParserAnyMacro<'a> {
         // `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
         // but `m!()` is allowed in expression positions (cf. issue #34706).
         if kind == AstFragmentKind::Expr && parser.token == token::Semi {
-            parser.sess.buffer_lint(
-                SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
-                parser.token.span,
-                lint_node_id,
-                "trailing semicolon in macro used in expression position",
-            );
+            if is_local {
+                parser.sess.buffer_lint_with_diagnostic(
+                    SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
+                    parser.token.span,
+                    lint_node_id,
+                    "trailing semicolon in macro used in expression position",
+                    BuiltinLintDiagnostics::TrailingMacro(is_trailing_mac, macro_ident),
+                );
+            }
             parser.bump();
         }
 
@@ -154,6 +167,7 @@ struct MacroRulesMacroExpander {
     lhses: Vec<mbe::TokenTree>,
     rhses: Vec<mbe::TokenTree>,
     valid: bool,
+    is_local: bool,
 }
 
 impl TTMacroExpander for MacroRulesMacroExpander {
@@ -175,6 +189,7 @@ fn expand<'cx>(
             input,
             &self.lhses,
             &self.rhses,
+            self.is_local,
         )
     }
 }
@@ -202,6 +217,7 @@ fn generic_extension<'cx>(
     arg: TokenStream,
     lhses: &[mbe::TokenTree],
     rhses: &[mbe::TokenTree],
+    is_local: bool,
 ) -> Box<dyn MacResult + 'cx> {
     let sess = &cx.sess.parse_sess;
 
@@ -301,7 +317,9 @@ fn generic_extension<'cx>(
                     site_span: sp,
                     macro_ident: name,
                     lint_node_id: cx.current_expansion.lint_node_id,
+                    is_trailing_mac: cx.current_expansion.is_trailing_mac,
                     arm_span,
+                    is_local,
                 });
             }
             Failure(token, msg) => match best_failure {
@@ -535,6 +553,9 @@ pub fn compile_declarative_macro(
         lhses,
         rhses,
         valid,
+        // Macros defined in the current crate have a real node id,
+        // whereas macros from an external crate have a dummy id.
+        is_local: def.id != DUMMY_NODE_ID,
     }))
 }