From bdf4e3de9c4634af517c05c58f049eda0c28ea5f Mon Sep 17 00:00:00 2001 From: Arthur Cohen Date: Wed, 2 Aug 2023 20:08:28 +0200 Subject: [PATCH] check_attrs: Warn when #[macro_export] is used on macros 2.0 The compiler should emit a more specific error when the `#[macro_export]` attribute is present on a decl macro, instead of silently ignoring it. This commit adds the required error message in rustc_passes/messages.ftl, as well as a note. A new variant is added to the `errors::MacroExport` enum, specifically for the case where the attribute is added to a macro 2.0. --- compiler/rustc_passes/messages.ftl | 4 ++++ compiler/rustc_passes/src/check_attr.rs | 14 ++++++++++++++ compiler/rustc_passes/src/errors.rs | 4 ++++ .../ui/attributes/macro_export_on_decl_macro.rs | 9 +++++++++ .../attributes/macro_export_on_decl_macro.stderr | 16 ++++++++++++++++ 5 files changed, 47 insertions(+) create mode 100644 tests/ui/attributes/macro_export_on_decl_macro.rs create mode 100644 tests/ui/attributes/macro_export_on_decl_macro.stderr diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 5b3cc5d99cc78..6eacbebe75f41 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -428,6 +428,10 @@ passes_link_section = passes_macro_export = `#[macro_export]` only has an effect on macro definitions +passes_macro_export_on_decl_macro = + `#[macro_export]` has no effect on declarative macro definitions + .note = declarative macros follow the same exporting rules as regular items + passes_macro_use = `#[{$name}]` only has an effect on `extern crate` and modules diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index cbb030958c693..4f9b362e23796 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -2133,6 +2133,20 @@ impl CheckAttrVisitor<'_> { ); } } + } else { + // special case when `#[macro_export]` is applied to a macro 2.0 + let (macro_definition, _) = + self.tcx.hir().find(hir_id).unwrap().expect_item().expect_macro(); + let is_decl_macro = !macro_definition.macro_rules; + + if is_decl_macro { + self.tcx.emit_spanned_lint( + UNUSED_ATTRIBUTES, + hir_id, + attr.span, + errors::MacroExport::OnDeclMacro, + ); + } } } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 4f5514372d1ec..683717344cecc 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -690,6 +690,10 @@ pub enum MacroExport { #[diag(passes_macro_export)] Normal, + #[diag(passes_macro_export_on_decl_macro)] + #[note] + OnDeclMacro, + #[diag(passes_invalid_macro_export_arguments)] UnknownItem { name: Symbol }, diff --git a/tests/ui/attributes/macro_export_on_decl_macro.rs b/tests/ui/attributes/macro_export_on_decl_macro.rs new file mode 100644 index 0000000000000..e6fe66ac6c30e --- /dev/null +++ b/tests/ui/attributes/macro_export_on_decl_macro.rs @@ -0,0 +1,9 @@ +// Using #[macro_export] on a decl macro has no effect and should warn + +#![feature(decl_macro)] +#![deny(unused)] + +#[macro_export] //~ ERROR `#[macro_export]` has no effect on declarative macro definitions +pub macro foo() {} + +fn main() {} diff --git a/tests/ui/attributes/macro_export_on_decl_macro.stderr b/tests/ui/attributes/macro_export_on_decl_macro.stderr new file mode 100644 index 0000000000000..565e07919bc2c --- /dev/null +++ b/tests/ui/attributes/macro_export_on_decl_macro.stderr @@ -0,0 +1,16 @@ +error: `#[macro_export]` has no effect on declarative macro definitions + --> $DIR/macro_export_on_decl_macro.rs:6:1 + | +LL | #[macro_export] + | ^^^^^^^^^^^^^^^ + | + = note: declarative macros follow the same exporting rules as regular items +note: the lint level is defined here + --> $DIR/macro_export_on_decl_macro.rs:4:9 + | +LL | #![deny(unused)] + | ^^^^^^ + = note: `#[deny(unused_attributes)]` implied by `#[deny(unused)]` + +error: aborting due to previous error +