Skip to content

Commit ebe7393

Browse files
authored
Rollup merge of rust-lang#107911 - blyxyas:issue-107231-fix, r=compiler-errors
Add check for invalid #[macro_export] arguments Resolves rust-lang#107231 Sorry if I made something wrong, this is my first contribution to the repo.
2 parents f9216b7 + 05838b5 commit ebe7393

File tree

6 files changed

+115
-4
lines changed

6 files changed

+115
-4
lines changed

compiler/rustc_error_messages/locales/en-US/passes.ftl

+4
Original file line numberDiff line numberDiff line change
@@ -745,3 +745,7 @@ passes_proc_macro_invalid_abi = proc macro functions may not be `extern "{$abi}"
745745
passes_proc_macro_unsafe = proc macro functions may not be `unsafe`
746746
747747
passes_skipping_const_checks = skipping const checks
748+
749+
passes_invalid_macro_export_arguments = `{$name}` isn't a valid `#[macro_export]` argument
750+
751+
passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments

compiler/rustc_lint_defs/src/builtin.rs

+30
Original file line numberDiff line numberDiff line change
@@ -4103,3 +4103,33 @@ declare_lint! {
41034103
};
41044104
report_in_external_macro
41054105
}
4106+
4107+
declare_lint! {
4108+
/// The `invalid_macro_export_arguments` lint detects cases where `#[macro_export]` is being used with invalid arguments.
4109+
///
4110+
/// ### Example
4111+
///
4112+
/// ```rust,compile_fail
4113+
/// #![deny(invalid_macro_export_arguments)]
4114+
///
4115+
/// #[macro_export(invalid_parameter)]
4116+
/// macro_rules! myMacro {
4117+
/// () => {
4118+
/// // [...]
4119+
/// }
4120+
/// }
4121+
///
4122+
/// #[macro_export(too, many, items)]
4123+
/// ```
4124+
///
4125+
/// {{produces}}
4126+
///
4127+
/// ### Explanation
4128+
///
4129+
/// The only valid argument is `#[macro_export(local_inner_macros)]` or no argument (`#[macro_export]`).
4130+
/// You can't have multiple arguments in a `#[macro_export(..)]`, or mention arguments other than `local_inner_macros`.
4131+
///
4132+
pub INVALID_MACRO_EXPORT_ARGUMENTS,
4133+
Warn,
4134+
"\"invalid_parameter\" isn't a valid argument for `#[macro_export]`",
4135+
}

compiler/rustc_passes/src/check_attr.rs

+29-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
2323
use rustc_middle::ty::query::Providers;
2424
use rustc_middle::ty::{ParamEnv, TyCtxt};
2525
use rustc_session::lint::builtin::{
26-
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, UNUSED_ATTRIBUTES,
26+
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
27+
UNUSED_ATTRIBUTES,
2728
};
2829
use rustc_session::parse::feature_err;
2930
use rustc_span::symbol::{kw, sym, Symbol};
@@ -2102,7 +2103,33 @@ impl CheckAttrVisitor<'_> {
21022103

21032104
fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) {
21042105
if target != Target::MacroDef {
2105-
self.tcx.emit_spanned_lint(UNUSED_ATTRIBUTES, hir_id, attr.span, errors::MacroExport);
2106+
self.tcx.emit_spanned_lint(
2107+
UNUSED_ATTRIBUTES,
2108+
hir_id,
2109+
attr.span,
2110+
errors::MacroExport::Normal,
2111+
);
2112+
} else if let Some(meta_item_list) = attr.meta_item_list() &&
2113+
!meta_item_list.is_empty() {
2114+
if meta_item_list.len() > 1 {
2115+
self.tcx.emit_spanned_lint(
2116+
INVALID_MACRO_EXPORT_ARGUMENTS,
2117+
hir_id,
2118+
attr.span,
2119+
errors::MacroExport::TooManyItems,
2120+
);
2121+
} else {
2122+
if meta_item_list[0].name_or_empty() != sym::local_inner_macros {
2123+
self.tcx.emit_spanned_lint(
2124+
INVALID_MACRO_EXPORT_ARGUMENTS,
2125+
hir_id,
2126+
meta_item_list[0].span(),
2127+
errors::MacroExport::UnknownItem {
2128+
name: meta_item_list[0].name_or_empty(),
2129+
},
2130+
);
2131+
}
2132+
}
21062133
}
21072134
}
21082135

compiler/rustc_passes/src/errors.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -640,8 +640,16 @@ pub struct MacroUse {
640640
}
641641

642642
#[derive(LintDiagnostic)]
643-
#[diag(passes_macro_export)]
644-
pub struct MacroExport;
643+
pub enum MacroExport {
644+
#[diag(passes_macro_export)]
645+
Normal,
646+
647+
#[diag(passes_invalid_macro_export_arguments)]
648+
UnknownItem { name: Symbol },
649+
650+
#[diag(passes_invalid_macro_export_arguments_too_many_items)]
651+
TooManyItems,
652+
}
645653

646654
#[derive(LintDiagnostic)]
647655
#[diag(passes_plugin_registrar)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// check-pass
2+
#[macro_export(hello, world)] //~ WARN `#[macro_export]` can only take 1 or 0 arguments
3+
macro_rules! a {
4+
() => ()
5+
}
6+
7+
#[macro_export(not_local_inner_macros)] //~ WARN `not_local_inner_macros` isn't a valid `#[macro_export]` argument
8+
macro_rules! b {
9+
() => ()
10+
}
11+
12+
#[macro_export]
13+
macro_rules! c {
14+
() => ()
15+
}
16+
#[macro_export(local_inner_macros)]
17+
macro_rules! d {
18+
() => ()
19+
}
20+
21+
#[macro_export()]
22+
macro_rules! e {
23+
() => ()
24+
}
25+
26+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
warning: `#[macro_export]` can only take 1 or 0 arguments
2+
--> $DIR/invalid_macro_export_argument.rs:2:1
3+
|
4+
LL | #[macro_export(hello, world)]
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: `#[warn(invalid_macro_export_arguments)]` on by default
8+
9+
warning: `not_local_inner_macros` isn't a valid `#[macro_export]` argument
10+
--> $DIR/invalid_macro_export_argument.rs:7:16
11+
|
12+
LL | #[macro_export(not_local_inner_macros)]
13+
| ^^^^^^^^^^^^^^^^^^^^^^
14+
15+
warning: 2 warnings emitted
16+

0 commit comments

Comments
 (0)