diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index f61efcf238852..7be6e6c77b4a3 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -300,6 +300,9 @@ pub enum AttributeKind { /// Represents `#[loop_match]`. LoopMatch(Span), + /// Represents [`#[macro_export}`](https://doc.rust-lang.org/reference/macros-by-example.html#r-macro.decl.scope.path). + MacroExport { span: Span, local_inner_macros: bool }, + /// Represents `#[rustc_macro_transparency]`. MacroTransparency(Transparency), diff --git a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs index ad587523e0373..0a2ce63461252 100644 --- a/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs +++ b/compiler/rustc_attr_data_structures/src/encode_cross_crate.rs @@ -42,6 +42,7 @@ impl AttributeKind { LinkName { .. } => Yes, LinkSection { .. } => No, LoopMatch(..) => No, + MacroExport { .. } => Yes, MacroTransparency(..) => Yes, Marker(..) => No, MayDangle(..) => No, diff --git a/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs new file mode 100644 index 0000000000000..31eacca7d769c --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs @@ -0,0 +1,45 @@ +use rustc_attr_data_structures::AttributeKind; +use rustc_attr_data_structures::AttributeKind::MacroExport; +use rustc_attr_data_structures::lints::AttributeLintKind; +use rustc_feature::{AttributeTemplate, template}; +use rustc_span::{Symbol, sym}; + +use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; +use crate::context::{AcceptContext, Stage}; +use crate::parser::ArgParser; + +pub(crate) struct MacroExportParser; + +impl SingleAttributeParser for crate::attributes::macro_attrs::MacroExportParser { + const PATH: &[Symbol] = &[sym::macro_export]; + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Warn; + const TEMPLATE: AttributeTemplate = template!(Word, List: "local_inner_macros"); + + fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option { + let local_inner_macros = match args { + ArgParser::NoArgs => false, + ArgParser::List(list) => { + let Some(l) = list.single() else { + cx.expected_single_argument(list.span); + return None; + }; + match l.meta_item().and_then(|i| i.path().word_sym()) { + Some(sym::local_inner_macros) => true, + _ => { + cx.expected_specific_argument(l.span(), vec!["local_inner_macros"]); + return None; + } + } + } + ArgParser::NameValue(_) => { + let suggestions = + >::TEMPLATE.suggestions(false, "macro_export"); + let span = cx.attr_span; + cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span); + return None; + } + }; + Some(MacroExport { span: cx.attr_span, local_inner_macros }) + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index 68c716d1a99d1..40a09e017407d 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -35,6 +35,7 @@ pub(crate) mod inline; pub(crate) mod link_attrs; pub(crate) mod lint_helpers; pub(crate) mod loop_match; +pub(crate) mod macro_attrs; pub(crate) mod must_use; pub(crate) mod no_implicit_prelude; pub(crate) mod non_exhaustive; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index cc10bb3098a61..57bc9954b4e8e 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -29,6 +29,7 @@ use crate::attributes::link_attrs::{ }; use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser}; use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser}; +use crate::attributes::macro_attrs::MacroExportParser; use crate::attributes::must_use::MustUseParser; use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser; use crate::attributes::non_exhaustive::NonExhaustiveParser; @@ -142,6 +143,7 @@ attribute_parsers!( Single, Single, Single, + Single, Single, Single, Single, diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index d6d898088395e..f2af791b06b69 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -892,9 +892,9 @@ impl SyntaxExtension { let allow_internal_unsafe = ast::attr::find_by_name(attrs, sym::allow_internal_unsafe).is_some(); - let local_inner_macros = ast::attr::find_by_name(attrs, sym::macro_export) - .and_then(|macro_export| macro_export.meta_item_list()) - .is_some_and(|l| ast::attr::list_contains_name(&l, sym::local_inner_macros)); + let local_inner_macros = + *find_attr!(attrs, AttributeKind::MacroExport {local_inner_macros: l, ..} => l) + .unwrap_or(&false); let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, !is_local); tracing::debug!(?name, ?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe); diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index b877f909fc029..83e8ed40435b7 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -1,3 +1,4 @@ +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_errors::MultiSpan; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{self, Visitor, VisitorExt}; @@ -5,7 +6,7 @@ use rustc_hir::{Body, HirId, Item, ItemKind, Node, Path, TyKind}; use rustc_middle::ty::TyCtxt; use rustc_session::{declare_lint, impl_lint_pass}; use rustc_span::def_id::{DefId, LOCAL_CRATE}; -use rustc_span::{ExpnKind, MacroKind, Span, kw, sym}; +use rustc_span::{ExpnKind, MacroKind, Span, kw}; use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag}; use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent}; @@ -241,7 +242,10 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { ) } ItemKind::Macro(_, _macro, MacroKind::Bang) - if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) => + if find_attr!( + cx.tcx.get_all_attrs(item.owner_id.def_id), + AttributeKind::MacroExport { .. } + ) => { cx.emit_span_lint( NON_LOCAL_DEFINITIONS, diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index a08d68e2d1532..4c8301549f637 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -52,7 +52,6 @@ declare_lint_pass! { INEFFECTIVE_UNSTABLE_TRAIT_IMPL, INLINE_NO_SANITIZE, INVALID_DOC_ATTRIBUTES, - INVALID_MACRO_EXPORT_ARGUMENTS, INVALID_TYPE_PARAM_DEFAULT, IRREFUTABLE_LET_PATTERNS, LARGE_ASSIGNMENTS, @@ -4161,36 +4160,6 @@ 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]`", -} - declare_lint! { /// The `private_interfaces` lint detects types in a primary interface of an item, /// that are more private than the item itself. Primary interface of an item is all diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index bb5c1e0e653a7..de5e3b4aceb58 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -302,6 +302,7 @@ pub fn check_builtin_meta_item( | sym::cold | sym::target_feature | sym::rustc_allow_const_fn_unstable + | sym::macro_export | sym::naked | sym::no_mangle | sym::non_exhaustive diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 46c21dcf67b19..2c31518a1fa37 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -395,10 +395,6 @@ passes_invalid_attr_at_crate_level = passes_invalid_attr_at_crate_level_item = the inner attribute doesn't annotate this {$kind} -passes_invalid_macro_export_arguments = invalid `#[macro_export]` argument - -passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments - passes_lang_item_fn = {$name -> [panic_impl] `#[panic_handler]` *[other] `{$name}` lang item diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 86f10f335893a..f2d2a5f397f62 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -32,8 +32,8 @@ use rustc_middle::{bug, span_bug}; use rustc_session::config::CrateType; use rustc_session::lint; use rustc_session::lint::builtin::{ - CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS, - MALFORMED_DIAGNOSTIC_ATTRIBUTES, MISPLACED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES, + CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, MALFORMED_DIAGNOSTIC_ATTRIBUTES, + MISPLACED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES, }; use rustc_session::parse::feature_err; use rustc_span::edition::Edition; @@ -242,6 +242,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::MacroTransparency(_) | AttributeKind::Dummy, ) => { /* do nothing */ } + Attribute::Parsed(AttributeKind::MacroExport { span, .. }) => { + self.check_macro_export(hir_id, *span, target) + } Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => { self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target) } @@ -331,7 +334,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_macro_use(hir_id, attr, target) } [sym::path, ..] => self.check_generic_attr_unparsed(hir_id, attr, target, Target::Mod), - [sym::macro_export, ..] => self.check_macro_export(hir_id, attr, target), [sym::should_panic, ..] => { self.check_generic_attr_unparsed(hir_id, attr, target, Target::Fn) } @@ -2295,32 +2297,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> { } } - fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) { + fn check_macro_export(&self, hir_id: HirId, attr_span: Span, target: Target) { if target != Target::MacroDef { self.tcx.emit_node_span_lint( UNUSED_ATTRIBUTES, hir_id, - attr.span(), + 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_node_span_lint( - INVALID_MACRO_EXPORT_ARGUMENTS, - hir_id, - attr.span(), - errors::MacroExport::TooManyItems, - ); - } else if !meta_item_list[0].has_name(sym::local_inner_macros) { - self.tcx.emit_node_span_lint( - INVALID_MACRO_EXPORT_ARGUMENTS, - hir_id, - meta_item_list[0].span(), - errors::MacroExport::InvalidArgument, - ); - } } else { // special case when `#[macro_export]` is applied to a macro 2.0 let (_, macro_definition, _) = self.tcx.hir_node(hir_id).expect_item().expect_macro(); @@ -2330,7 +2314,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.tcx.emit_node_span_lint( UNUSED_ATTRIBUTES, hir_id, - attr.span(), + attr_span, errors::MacroExport::OnDeclMacro, ); } @@ -2684,7 +2668,9 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> { // In the long run, the checks should be harmonized. if let ItemKind::Macro(_, macro_def, _) = item.kind { let def_id = item.owner_id.to_def_id(); - if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) { + if macro_def.macro_rules + && !find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::MacroExport { .. }) + { check_non_exported_macro_for_invalid_attrs(self.tcx, item); } } @@ -2814,7 +2800,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { // which were unsuccessfully resolved due to cannot determine // resolution for the attribute macro error. const ATTRS_TO_CHECK: &[Symbol] = &[ - sym::macro_export, sym::automatically_derived, sym::rustc_main, sym::derive, @@ -2838,6 +2823,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) { (*first_attr_span, sym::repr) } else if let Attribute::Parsed(AttributeKind::Path(.., span)) = attr { (*span, sym::path) + } else if let Attribute::Parsed(AttributeKind::MacroExport { span, .. }) = attr { + (*span, sym::macro_export) } else { continue; }; diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 4ad615a2abfc8..144cc14d3f4c5 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -769,12 +769,6 @@ pub(crate) enum MacroExport { #[diag(passes_macro_export_on_decl_macro)] #[note] OnDeclMacro, - - #[diag(passes_invalid_macro_export_arguments)] - InvalidArgument, - - #[diag(passes_invalid_macro_export_arguments_too_many_items)] - TooManyItems, } #[derive(Subdiagnostic)] diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index aff8684ee3a09..92fd20fbd4879 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -4,6 +4,7 @@ use std::collections::hash_map::Entry; use std::collections::{BTreeMap, VecDeque}; use encode::{bitmap_to_string, write_vlqhex_to_string}; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_middle::ty::TyCtxt; use rustc_span::def_id::DefId; @@ -408,16 +409,17 @@ pub(crate) fn build_index( if fqp.last() != Some(&item.name) { return None; } - let path = - if item.ty == ItemType::Macro && tcx.has_attr(defid, sym::macro_export) { - // `#[macro_export]` always exports to the crate root. - tcx.crate_name(defid.krate).to_string() - } else { - if fqp.len() < 2 { - return None; - } - join_with_double_colon(&fqp[..fqp.len() - 1]) - }; + let path = if item.ty == ItemType::Macro + && find_attr!(tcx.get_all_attrs(defid), AttributeKind::MacroExport { .. }) + { + // `#[macro_export]` always exports to the crate root. + tcx.crate_name(defid.krate).to_string() + } else { + if fqp.len() < 2 { + return None; + } + join_with_double_colon(&fqp[..fqp.len() - 1]) + }; if path == item.path { return None; } diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index 3388ae46f056c..be69ee113c946 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -2,9 +2,9 @@ use std::mem; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_middle::ty::TyCtxt; -use rustc_span::symbol::sym; use tracing::debug; use crate::clean::utils::inherits_doc_hidden; @@ -114,7 +114,7 @@ impl DocFolder for Stripper<'_, '_> { // If the macro has the `#[macro_export]` attribute, it means it's accessible at the // crate level so it should be handled differently. clean::MacroItem(..) => { - i.attrs.other_attrs.iter().any(|attr| attr.has_name(sym::macro_export)) + find_attr!(&i.attrs.other_attrs, AttributeKind::MacroExport { .. }) } _ => false, }; diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 2784d7c761a84..a7cbe3d3424f8 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -3,6 +3,7 @@ use std::mem; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -167,7 +168,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { if !child.reexport_chain.is_empty() && let Res::Def(DefKind::Macro(_), def_id) = child.res && let Some(local_def_id) = def_id.as_local() - && self.cx.tcx.has_attr(def_id, sym::macro_export) + && find_attr!(self.cx.tcx.get_all_attrs(def_id), AttributeKind::MacroExport { .. }) && inserted.insert(def_id) { let item = self.cx.tcx.hir_expect_item(local_def_id); @@ -407,7 +408,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { || match item.kind { hir::ItemKind::Impl(..) => true, hir::ItemKind::Macro(_, _, MacroKind::Bang) => { - self.cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) + find_attr!(self.cx.tcx.get_all_attrs(item.owner_id.def_id), AttributeKind::MacroExport{..}) } _ => false, } @@ -525,7 +526,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { let def_id = item.owner_id.to_def_id(); let is_macro_2_0 = !macro_def.macro_rules; - let nonexported = !tcx.has_attr(def_id, sym::macro_export); + let nonexported = + !find_attr!(tcx.get_all_attrs(def_id), AttributeKind::MacroExport { .. }); if is_macro_2_0 || nonexported || self.inlining { self.add_to_current_mod(item, renamed, import_id); diff --git a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs index 9071c9c95f9d7..3b8360e19fae2 100644 --- a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs +++ b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs @@ -8,7 +8,8 @@ use rustc_hir::{BlockCheckMode, Expr, ExprKind, HirId, Stmt, UnsafeSource}; use rustc_lint::{LateContext, LateLintPass, Level, LintContext}; use rustc_middle::lint::LevelAndSource; use rustc_session::impl_lint_pass; -use rustc_span::{Span, SyntaxContext, sym}; +use rustc_span::{Span, SyntaxContext}; +use rustc_attr_data_structures::{find_attr, AttributeKind}; use std::collections::BTreeMap; use std::collections::btree_map::Entry; @@ -146,7 +147,8 @@ struct BodyVisitor<'a, 'tcx> { } fn is_public_macro(cx: &LateContext<'_>, def_id: LocalDefId) -> bool { - (cx.effective_visibilities.is_exported(def_id) || cx.tcx.has_attr(def_id, sym::macro_export)) + ( cx.effective_visibilities.is_exported(def_id) || + find_attr!(cx.tcx.get_all_attrs(def_id), AttributeKind::MacroExport{..}) ) && !cx.tcx.is_doc_hidden(def_id) } diff --git a/tests/ui/attributes/invalid_macro_export_argument.deny.stderr b/tests/ui/attributes/invalid_macro_export_argument.deny.stderr deleted file mode 100644 index 9d44bd162c7b7..0000000000000 --- a/tests/ui/attributes/invalid_macro_export_argument.deny.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: `#[macro_export]` can only take 1 or 0 arguments - --> $DIR/invalid_macro_export_argument.rs:7:1 - | -LL | #[macro_export(hello, world)] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: the lint level is defined here - --> $DIR/invalid_macro_export_argument.rs:4:24 - | -LL | #![cfg_attr(deny, deny(invalid_macro_export_arguments))] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: invalid `#[macro_export]` argument - --> $DIR/invalid_macro_export_argument.rs:13:16 - | -LL | #[macro_export(not_local_inner_macros)] - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: invalid `#[macro_export]` argument - --> $DIR/invalid_macro_export_argument.rs:33:16 - | -LL | #[macro_export("blah")] - | ^^^^^^ - -error: aborting due to 3 previous errors - diff --git a/tests/ui/attributes/invalid_macro_export_argument.rs b/tests/ui/attributes/invalid_macro_export_argument.rs index c5fe39d062a4e..02abc60f1fa1d 100644 --- a/tests/ui/attributes/invalid_macro_export_argument.rs +++ b/tests/ui/attributes/invalid_macro_export_argument.rs @@ -1,17 +1,13 @@ -//@ revisions: deny allow -//@[allow] check-pass - -#![cfg_attr(deny, deny(invalid_macro_export_arguments))] -#![cfg_attr(allow, allow(invalid_macro_export_arguments))] - #[macro_export(hello, world)] -//[deny]~^ ERROR `#[macro_export]` can only take 1 or 0 arguments +//~^ ERROR malformed `macro_export` attribute input +//~| HELP try changing it to one of the following valid forms of the attribute macro_rules! a { () => () } #[macro_export(not_local_inner_macros)] -//[deny]~^ ERROR invalid `#[macro_export]` argument +//~^ ERROR malformed `macro_export` attribute input +//~| HELP try changing it to one of the following valid forms of the attribute macro_rules! b { () => () } @@ -26,12 +22,15 @@ macro_rules! d { } #[macro_export()] +//~^ ERROR malformed `macro_export` attribute input +//~| HELP try changing it to one of the following valid forms of the attribute macro_rules! e { () => () } #[macro_export("blah")] -//[deny]~^ ERROR invalid `#[macro_export]` argument +//~^ ERROR malformed `macro_export` attribute input +//~| HELP try changing it to one of the following valid forms of the attribute macro_rules! f { () => () } diff --git a/tests/ui/attributes/invalid_macro_export_argument.stderr b/tests/ui/attributes/invalid_macro_export_argument.stderr new file mode 100644 index 0000000000000..86bb96a8d978f --- /dev/null +++ b/tests/ui/attributes/invalid_macro_export_argument.stderr @@ -0,0 +1,71 @@ +error[E0805]: malformed `macro_export` attribute input + --> $DIR/invalid_macro_export_argument.rs:1:1 + | +LL | #[macro_export(hello, world)] + | ^^^^^^^^^^^^^^--------------^ + | | + | expected a single argument here + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[macro_export(hello, world)] +LL + #[macro_export(local_inner_macros)] + | +LL - #[macro_export(hello, world)] +LL + #[macro_export] + | + +error[E0539]: malformed `macro_export` attribute input + --> $DIR/invalid_macro_export_argument.rs:8:1 + | +LL | #[macro_export(not_local_inner_macros)] + | ^^^^^^^^^^^^^^^----------------------^^ + | | + | the only valid argument here is `local_inner_macros` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[macro_export(not_local_inner_macros)] +LL + #[macro_export(local_inner_macros)] + | +LL - #[macro_export(not_local_inner_macros)] +LL + #[macro_export] + | + +error[E0805]: malformed `macro_export` attribute input + --> $DIR/invalid_macro_export_argument.rs:24:1 + | +LL | #[macro_export()] + | ^^^^^^^^^^^^^^--^ + | | + | expected a single argument here + | +help: try changing it to one of the following valid forms of the attribute + | +LL | #[macro_export(local_inner_macros)] + | ++++++++++++++++++ +LL - #[macro_export()] +LL + #[macro_export] + | + +error[E0539]: malformed `macro_export` attribute input + --> $DIR/invalid_macro_export_argument.rs:31:1 + | +LL | #[macro_export("blah")] + | ^^^^^^^^^^^^^^^------^^ + | | + | the only valid argument here is `local_inner_macros` + | +help: try changing it to one of the following valid forms of the attribute + | +LL - #[macro_export("blah")] +LL + #[macro_export(local_inner_macros)] + | +LL - #[macro_export("blah")] +LL + #[macro_export] + | + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0539, E0805. +For more information about an error, try `rustc --explain E0539`. diff --git a/tests/ui/attributes/malformed-attrs.rs b/tests/ui/attributes/malformed-attrs.rs index aa52de63a6094..3c7e822e58a3c 100644 --- a/tests/ui/attributes/malformed-attrs.rs +++ b/tests/ui/attributes/malformed-attrs.rs @@ -212,7 +212,8 @@ extern crate wloop; //~^ ERROR can't find crate for `wloop` [E0463] #[macro_export = 18] -//~^ ERROR malformed `macro_export` attribute input +//~^ ERROR valid forms for the attribute are +//~| WARN this was previously accepted by the compiler #[allow_internal_unsafe = 1] //~^ ERROR malformed //~| ERROR allow_internal_unsafe side-steps the unsafe_code lint diff --git a/tests/ui/attributes/malformed-attrs.stderr b/tests/ui/attributes/malformed-attrs.stderr index f16ba706485da..607e7fc4e9e42 100644 --- a/tests/ui/attributes/malformed-attrs.stderr +++ b/tests/ui/attributes/malformed-attrs.stderr @@ -197,23 +197,8 @@ LL - #[macro_use = 1] LL + #[macro_use] | -error: malformed `macro_export` attribute input - --> $DIR/malformed-attrs.rs:214:1 - | -LL | #[macro_export = 18] - | ^^^^^^^^^^^^^^^^^^^^ - | -help: the following are the possible correct uses - | -LL - #[macro_export = 18] -LL + #[macro_export(local_inner_macros)] - | -LL - #[macro_export = 18] -LL + #[macro_export] - | - error: malformed `allow_internal_unsafe` attribute input - --> $DIR/malformed-attrs.rs:216:1 + --> $DIR/malformed-attrs.rs:217:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[allow_internal_unsafe]` @@ -237,7 +222,7 @@ LL | #[proc_macro_derive] | ^^^^^^^^^^^^^^^^^^^^ error[E0658]: allow_internal_unsafe side-steps the unsafe_code lint - --> $DIR/malformed-attrs.rs:216:1 + --> $DIR/malformed-attrs.rs:217:1 | LL | #[allow_internal_unsafe = 1] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -630,8 +615,17 @@ LL | #[ignore()] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 +error: valid forms for the attribute are `#[macro_export(local_inner_macros)]` and `#[macro_export]` + --> $DIR/malformed-attrs.rs:214:1 + | +LL | #[macro_export = 18] + | ^^^^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #57571 + error: valid forms for the attribute are `#[ignore = "reason"]` and `#[ignore]` - --> $DIR/malformed-attrs.rs:223:1 + --> $DIR/malformed-attrs.rs:224:1 | LL | #[ignore = 1] | ^^^^^^^^^^^^^ diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr index 49c666f498f58..7b84f2a6068c0 100644 --- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr +++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr @@ -91,21 +91,6 @@ error[E0518]: attribute should be applied to function or closure LL | #![inline] | ^^^^^^^^^^ not a function or closure -error: `macro_export` attribute cannot be used at crate level - --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1 - | -LL | #![macro_export] - | ^^^^^^^^^^^^^^^^ -... -LL | mod inline { - | ------ the inner attribute doesn't annotate this module - | -help: perhaps you meant to use an outer attribute - | -LL - #![macro_export] -LL + #[macro_export] - | - error: `rustc_main` attribute cannot be used at crate level --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:14:1 | @@ -151,6 +136,21 @@ LL - #![repr()] LL + #[repr()] | +error: `macro_export` attribute cannot be used at crate level + --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:12:1 + | +LL | #![macro_export] + | ^^^^^^^^^^^^^^^^ +... +LL | mod inline { + | ------ the inner attribute doesn't annotate this module + | +help: perhaps you meant to use an outer attribute + | +LL - #![macro_export] +LL + #[macro_export] + | + error: `path` attribute cannot be used at crate level --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:21:1 |