about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorblyxyas <blyxyas@gmail.com>2023-02-11 00:53:19 +0100
committerMichael Goulet <michael@errs.io>2023-02-22 21:53:16 +0000
commite39fe374df14334be3b5eb081a006fad8e4419f7 (patch)
tree231e42a28035a481a79f1271407cf3a21fcda562 /compiler
parentfdbc4329cb781c7768ffa6d76c8fa2d032d3fe20 (diff)
downloadrust-e39fe374df14334be3b5eb081a006fad8e4419f7.tar.gz
rust-e39fe374df14334be3b5eb081a006fad8e4419f7.zip
Add check for invalid \`#[macro_export]\` arguments
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs30
-rw-r--r--compiler/rustc_passes/locales/en-US.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs31
-rw-r--r--compiler/rustc_passes/src/errors.rs12
4 files changed, 73 insertions, 4 deletions
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 9d8ad9d9ed9..46ec1a2dca1 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -4103,3 +4103,33 @@ declare_lint! {
     };
     report_in_external_macro
 }
+
+declare_lint! {
+    /// The `invalid_macro_export_arguments` lint detects cases where `#[macro_export]` is being used with invalid arguments.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(invalid_macro_export_arguments)]
+    ///
+    /// #[macro_export(invalid_parameter)]
+    /// macro_rules! myMacro {
+    ///    () => {
+    ///         // [...]
+    ///    }
+    /// }
+    ///
+    /// #[macro_export(too, many, items)]
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// The only valid argument is `#[macro_export(local_inner_macros)]` or no argument (`#[macro_export]`).
+    /// You can't have multiple arguments in a `#[macro_export(..)]`, or mention arguments other than `local_inner_macros`.
+    ///
+    pub INVALID_MACRO_EXPORT_ARGUMENTS,
+    Warn,
+    "\"invalid_parameter\" isn't a valid argument for `#[macro_export]`",
+}
diff --git a/compiler/rustc_passes/locales/en-US.ftl b/compiler/rustc_passes/locales/en-US.ftl
index 0c7e02912d4..789a7cef4ae 100644
--- a/compiler/rustc_passes/locales/en-US.ftl
+++ b/compiler/rustc_passes/locales/en-US.ftl
@@ -745,3 +745,7 @@ passes_proc_macro_invalid_abi = proc macro functions may not be `extern "{$abi}"
 passes_proc_macro_unsafe = proc macro functions may not be `unsafe`
 
 passes_skipping_const_checks = skipping const checks
+
+passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]` argument
+
+passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index bb09dcbdd69..5ef3e13eff8 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -23,7 +23,8 @@ use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{ParamEnv, TyCtxt};
 use rustc_session::lint::builtin::{
-    CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, UNUSED_ATTRIBUTES,
+    CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
+    UNUSED_ATTRIBUTES,
 };
 use rustc_session::parse::feature_err;
 use rustc_span::symbol::{kw, sym, Symbol};
@@ -2102,7 +2103,33 @@ impl CheckAttrVisitor<'_> {
 
     fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) {
         if target != Target::MacroDef {
-            self.tcx.emit_spanned_lint(UNUSED_ATTRIBUTES, hir_id, attr.span, errors::MacroExport);
+            self.tcx.emit_spanned_lint(
+                UNUSED_ATTRIBUTES,
+                hir_id,
+                attr.span,
+                errors::MacroExport::Normal,
+            );
+        } else if let Some(meta_item_list) = attr.meta_item_list() &&
+        !meta_item_list.is_empty() {
+            if meta_item_list.len() > 1 {
+                self.tcx.emit_spanned_lint(
+                    INVALID_MACRO_EXPORT_ARGUMENTS,
+                    hir_id,
+                    attr.span,
+                    errors::MacroExport::TooManyItems,
+                );
+            } else {
+                if meta_item_list[0].name_or_empty() != sym::local_inner_macros {
+                    self.tcx.emit_spanned_lint(
+                        INVALID_MACRO_EXPORT_ARGUMENTS,
+                        hir_id,
+                        meta_item_list[0].span(),
+                        errors::MacroExport::UnknownItem {
+                            name: meta_item_list[0].name_or_empty(),
+                        },
+                    );
+                }
+            }
         }
     }
 
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 82fc3eeff94..2c0d21b4798 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -641,8 +641,16 @@ pub struct MacroUse {
 }
 
 #[derive(LintDiagnostic)]
-#[diag(passes_macro_export)]
-pub struct MacroExport;
+pub enum MacroExport {
+    #[diag(passes_macro_export)]
+    Normal,
+
+    #[diag(passes_invalid_macro_export_arguments)]
+    UnknownItem { name: Symbol },
+
+    #[diag(passes_invalid_macro_export_arguments_too_many_items)]
+    TooManyItems,
+}
 
 #[derive(LintDiagnostic)]
 #[diag(passes_plugin_registrar)]