Skip to content

Commit 5260e64

Browse files
committed
Port #[macro_export] to the new attribute parsing infrastructure
1 parent 1ae7c49 commit 5260e64

28 files changed

+569
-296
lines changed

compiler/rustc_attr_parsing/messages.ftl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ attr_parsing_ill_formed_attribute_input = {$num_suggestions ->
3838
*[other] valid forms for the attribute are {$suggestions}
3939
}
4040
41+
attr_parsing_invalid_macro_export_arguments = {$num_suggestions ->
42+
[1] attribute must be of the form {$suggestions}
43+
*[other] valid forms for the attribute are {$suggestions}
44+
}
45+
4146
attr_parsing_incorrect_repr_format_align_one_arg =
4247
incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
4348

compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@ use rustc_errors::DiagArgValue;
22
use rustc_feature::{AttributeTemplate, template};
33
use rustc_hir::Target;
44
use rustc_hir::attrs::{AttributeKind, MacroUseArgs};
5+
use rustc_hir::lints::AttributeLintKind;
56
use rustc_span::{Span, Symbol, sym};
67
use thin_vec::ThinVec;
78

8-
use crate::attributes::{AcceptMapping, AttributeParser, NoArgsAttributeParser, OnDuplicate};
9+
use crate::attributes::{
10+
AcceptMapping, AttributeOrder, AttributeParser, NoArgsAttributeParser, OnDuplicate,
11+
SingleAttributeParser,
12+
};
913
use crate::context::MaybeWarn::{Allow, Error, Warn};
1014
use crate::context::{AcceptContext, AllowedTargets, FinalizeContext, Stage};
1115
use crate::parser::ArgParser;
@@ -139,3 +143,63 @@ impl<S: Stage> NoArgsAttributeParser<S> for AllowInternalUnsafeParser {
139143
]);
140144
const CREATE: fn(Span) -> AttributeKind = |span| AttributeKind::AllowInternalUnsafe(span);
141145
}
146+
147+
pub(crate) struct MacroExportParser;
148+
149+
impl<S: Stage> SingleAttributeParser<S> for crate::attributes::macro_attrs::MacroExportParser {
150+
const PATH: &[Symbol] = &[sym::macro_export];
151+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
152+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
153+
const TEMPLATE: AttributeTemplate = template!(Word, List: &["local_inner_macros"]);
154+
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowListWarnRest(&[
155+
Allow(Target::MacroDef),
156+
Error(Target::WherePredicate),
157+
Error(Target::Crate),
158+
]);
159+
160+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
161+
let suggestions =
162+
|| <Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "macro_export");
163+
let local_inner_macros = match args {
164+
ArgParser::NoArgs => false,
165+
ArgParser::List(list) => {
166+
let Some(l) = list.single() else {
167+
let span = cx.attr_span;
168+
cx.emit_lint(
169+
AttributeLintKind::InvalidMacroExportArguments {
170+
suggestions: suggestions(),
171+
},
172+
span,
173+
);
174+
return None;
175+
};
176+
match l.meta_item().and_then(|i| i.path().word_sym()) {
177+
Some(sym::local_inner_macros) => true,
178+
_ => {
179+
let span = cx.attr_span;
180+
cx.emit_lint(
181+
AttributeLintKind::InvalidMacroExportArguments {
182+
suggestions: suggestions(),
183+
},
184+
span,
185+
);
186+
return None;
187+
}
188+
}
189+
}
190+
ArgParser::NameValue(_) => {
191+
let span = cx.attr_span;
192+
let suggestions = suggestions();
193+
cx.emit_err(session_diagnostics::IllFormedAttributeInputLint {
194+
num_suggestions: suggestions.len(),
195+
suggestions: DiagArgValue::StrListSepByAnd(
196+
suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
197+
),
198+
span,
199+
});
200+
return None;
201+
}
202+
};
203+
Some(AttributeKind::MacroExport { span: cx.attr_span, local_inner_macros })
204+
}
205+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use crate::attributes::lint_helpers::{
3737
};
3838
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
3939
use crate::attributes::macro_attrs::{
40-
AllowInternalUnsafeParser, MacroEscapeParser, MacroUseParser,
40+
AllowInternalUnsafeParser, MacroEscapeParser, MacroExportParser, MacroUseParser,
4141
};
4242
use crate::attributes::must_use::MustUseParser;
4343
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
@@ -176,6 +176,7 @@ attribute_parsers!(
176176
Single<LinkOrdinalParser>,
177177
Single<LinkSectionParser>,
178178
Single<LinkageParser>,
179+
Single<MacroExportParser>,
179180
Single<MustUseParser>,
180181
Single<OptimizeParser>,
181182
Single<PathAttributeParser>,

compiler/rustc_attr_parsing/src/lints.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,17 @@ pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<HirId>, lint_emi
5555
only,
5656
},
5757
),
58+
AttributeLintKind::InvalidMacroExportArguments { suggestions } => lint_emitter
59+
.emit_node_span_lint(
60+
rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS,
61+
*id,
62+
*span,
63+
session_diagnostics::IllFormedAttributeInput {
64+
num_suggestions: suggestions.len(),
65+
suggestions: DiagArgValue::StrListSepByAnd(
66+
suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
67+
),
68+
},
69+
),
5870
}
5971
}

compiler/rustc_expand/src/base.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -941,9 +941,9 @@ impl SyntaxExtension {
941941
.unwrap_or_default();
942942
let allow_internal_unsafe = find_attr!(attrs, AttributeKind::AllowInternalUnsafe(_));
943943

944-
let local_inner_macros = ast::attr::find_by_name(attrs, sym::macro_export)
945-
.and_then(|macro_export| macro_export.meta_item_list())
946-
.is_some_and(|l| ast::attr::list_contains_name(&l, sym::local_inner_macros));
944+
let local_inner_macros =
945+
*find_attr!(attrs, AttributeKind::MacroExport {local_inner_macros: l, ..} => l)
946+
.unwrap_or(&false);
947947
let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, !is_local);
948948
tracing::debug!(?name, ?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe);
949949

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,9 @@ pub enum AttributeKind {
387387
/// Represents `#[macro_escape]`.
388388
MacroEscape(Span),
389389

390+
/// Represents [`#[macro_export]`](https://doc.rust-lang.org/reference/macros-by-example.html#r-macro.decl.scope.path).
391+
MacroExport { span: Span, local_inner_macros: bool },
392+
390393
/// Represents `#[rustc_macro_transparency]`.
391394
MacroTransparency(Transparency),
392395

compiler/rustc_hir/src/attrs/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ impl AttributeKind {
4949
Linkage(..) => No,
5050
LoopMatch(..) => No,
5151
MacroEscape(..) => No,
52+
MacroExport { .. } => Yes,
5253
MacroTransparency(..) => Yes,
5354
MacroUse { .. } => No,
5455
Marker(..) => No,

compiler/rustc_hir/src/lints.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,28 @@ pub struct AttributeLint<Id> {
3131

3232
#[derive(Clone, Debug, HashStable_Generic)]
3333
pub enum AttributeLintKind {
34-
UnusedDuplicate { this: Span, other: Span, warning: bool },
35-
IllFormedAttributeInput { suggestions: Vec<String> },
36-
EmptyAttribute { first_span: Span },
37-
InvalidTarget { name: Symbol, target: Target, applied: String, only: &'static str },
34+
UnusedDuplicate {
35+
this: Span,
36+
other: Span,
37+
warning: bool,
38+
},
39+
IllFormedAttributeInput {
40+
suggestions: Vec<String>,
41+
},
42+
EmptyAttribute {
43+
first_span: Span,
44+
},
45+
46+
/// Copy of `IllFormedAttributeInput`
47+
/// specifically for the `invalid_macro_export_arguments` lint until that is removed,
48+
/// see <https://github.com/rust-lang/rust/pull/143857#issuecomment-3079175663>
49+
InvalidMacroExportArguments {
50+
suggestions: Vec<String>,
51+
},
52+
InvalidTarget {
53+
name: Symbol,
54+
target: Target,
55+
applied: String,
56+
only: &'static str,
57+
},
3858
}

compiler/rustc_lint/src/non_local_def.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use rustc_errors::MultiSpan;
2+
use rustc_hir::attrs::AttributeKind;
23
use rustc_hir::def::{DefKind, Res};
34
use rustc_hir::intravisit::{self, Visitor, VisitorExt};
4-
use rustc_hir::{Body, HirId, Item, ItemKind, Node, Path, TyKind};
5+
use rustc_hir::{Body, HirId, Item, ItemKind, Node, Path, TyKind, find_attr};
56
use rustc_middle::ty::TyCtxt;
67
use rustc_session::{declare_lint, impl_lint_pass};
78
use rustc_span::def_id::{DefId, LOCAL_CRATE};
8-
use rustc_span::{ExpnKind, Span, kw, sym};
9+
use rustc_span::{ExpnKind, Span, kw};
910

1011
use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag};
1112
use crate::{LateContext, LateLintPass, LintContext, fluent_generated as fluent};
@@ -241,7 +242,10 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
241242
)
242243
}
243244
ItemKind::Macro(_, _macro, _kinds)
244-
if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) =>
245+
if find_attr!(
246+
cx.tcx.get_all_attrs(item.owner_id.def_id),
247+
AttributeKind::MacroExport { .. }
248+
) =>
245249
{
246250
cx.emit_span_lint(
247251
NON_LOCAL_DEFINITIONS,

compiler/rustc_lint_defs/src/builtin.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4191,8 +4191,13 @@ declare_lint! {
41914191
/// You can't have multiple arguments in a `#[macro_export(..)]`, or mention arguments other than `local_inner_macros`.
41924192
///
41934193
pub INVALID_MACRO_EXPORT_ARGUMENTS,
4194-
Warn,
4194+
Deny,
41954195
"\"invalid_parameter\" isn't a valid argument for `#[macro_export]`",
4196+
@future_incompatible = FutureIncompatibleInfo {
4197+
reason: FutureIncompatibilityReason::FutureReleaseError,
4198+
reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
4199+
report_in_deps: true,
4200+
};
41964201
}
41974202

41984203
declare_lint! {

0 commit comments

Comments
 (0)