Add check for invalid \#[macro_export]\
arguments
This commit is contained in:
parent
fdbc4329cb
commit
e39fe374df
@ -4103,3 +4103,33 @@
|
||||
};
|
||||
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]`",
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -23,7 +23,8 @@
|
||||
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 @@ fn check_macro_use(&self, hir_id: HirId, attr: &Attribute, target: Target) {
|
||||
|
||||
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(),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)]
|
||||
|
26
tests/ui/attributes/invalid_macro_export_argument.rs
Normal file
26
tests/ui/attributes/invalid_macro_export_argument.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// 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() {}
|
16
tests/ui/attributes/invalid_macro_export_argument.stderr
Normal file
16
tests/ui/attributes/invalid_macro_export_argument.stderr
Normal file
@ -0,0 +1,16 @@
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user