Change:
<!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: I expected to see this happen: it shouldn't compile Instead, this happened: it compiles <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: <!-- Include a backtrace in the code block by setting in your environment. E.g. . --<details<summaryBacktrace</summary<p</p</details<!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
For anyone who would like to work on this, the following code needs to be adjusted to check if the meta-item list is empty or if it only contains the identifier (i.e. only allowing the attribute to be or : Due to backward compatibility concerns, probably only a future-incompat warning should be issued if the verification fails. label T-compiler A-attributes
claim
First rust-lang/rust contribution I hope this goes well

Discussion:
}; report_in_external_macro } <ins> 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]`", } </ins>

passes_proc_macro_unsafe = proc macro functions may not be `unsafe` passes_skipping_const_checks = skipping const checks <ins> 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 </ins>

use rustc_middle::ty::query::Providers; use rustc_middle::ty::{ParamEnv, TyCtxt}; use rustc_session::lint::builtin::{ <del> CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, UNUSED_ATTRIBUTES, </del> <ins> CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS, UNUSED_ATTRIBUTES, </ins> }; use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Symbol};

fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) { if target != Target::MacroDef { <del> self.tcx.emit_spanned_lint(UNUSED_ATTRIBUTES, hir_id, attr.span, errors::MacroExport); </del> <ins> 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(), }, ); } } </ins> } }

} #[derive(LintDiagnostic)] <del> #[diag(passes_macro_export)] pub struct MacroExport; </del> <ins> 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, } </ins> #[derive(LintDiagnostic)] #[diag(passes_plugin_registrar)]

<ins> // check-pass #[macro_export(hello, world)] //~ WARN `#[macro_export]` can only take 1 or 0 arguments macro_rules! a { () => () } #[macro_export(not_local_inner_macros)] //~ WARN `not_local_inner_macros` isn't a valid `#[macro_export]` argument macro_rules! b { () => () } #[macro_export] macro_rules! c { () => () } #[macro_export(local_inner_macros)] macro_rules! d { () => () } #[macro_export()] macro_rules! e { () => () } fn main() {} </ins>

<ins> warning: `#[macro_export]` can only take 1 or 0 arguments --> $DIR/invalid_macro_export_argument.rs:2:1 | LL | #[macro_export(hello, world)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `#[warn(invalid_macro_export_arguments)]` on by default warning: `not_local_inner_macros` isn't a valid `#[macro_export]` argument --> $DIR/invalid_macro_export_argument.rs:7:16 | LL | #[macro_export(not_local_inner_macros)] |                ^^^^^^^^^^^^^^^^^^^^^^ warning: 2 warnings emitted </ins>