Skip to content

Commit 12474a6

Browse files
committed
Port #[macro_export] to the new attribute parsing infrastructure
1 parent 6254afa commit 12474a6

File tree

21 files changed

+206
-127
lines changed

21 files changed

+206
-127
lines changed

compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,9 @@ pub enum AttributeKind {
267267
/// Represents `#[loop_match]`.
268268
LoopMatch(Span),
269269

270+
/// Represents [`#[macro_export}`](https://doc.rust-lang.org/reference/macros-by-example.html#r-macro.decl.scope.path).
271+
MacroExport { span: Span, local_inner_macros: bool },
272+
270273
/// Represents `#[rustc_macro_transparency]`.
271274
MacroTransparency(Transparency),
272275

compiler/rustc_attr_data_structures/src/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ impl AttributeKind {
3131
LinkName { .. } => Yes,
3232
LinkSection { .. } => No,
3333
LoopMatch(..) => No,
34+
MacroExport { .. } => Yes,
3435
MacroTransparency(..) => Yes,
3536
MayDangle(..) => No,
3637
MustUse { .. } => Yes,
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
use rustc_attr_data_structures::AttributeKind;
2+
use rustc_attr_data_structures::AttributeKind::MacroExport;
3+
use rustc_attr_data_structures::lints::AttributeLintKind;
4+
use rustc_feature::{AttributeTemplate, template};
5+
use rustc_span::{Symbol, sym};
6+
7+
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
8+
use crate::context::{AcceptContext, Stage};
9+
use crate::parser::ArgParser;
10+
11+
pub(crate) struct MacroExportParser;
12+
13+
impl<S: Stage> SingleAttributeParser<S> for crate::attributes::macro_attrs::MacroExportParser {
14+
const PATH: &[Symbol] = &[sym::macro_export];
15+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
16+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
17+
const TEMPLATE: AttributeTemplate = template!(Word, List: "local_inner_macros");
18+
19+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
20+
let local_inner_macros = match args {
21+
ArgParser::NoArgs => false,
22+
ArgParser::List(list) => {
23+
let Some(l) = list.single() else {
24+
cx.expected_single_argument(list.span);
25+
return None;
26+
};
27+
match l.meta_item().and_then(|i| i.path().word_sym()) {
28+
Some(sym::local_inner_macros) => true,
29+
_ => {
30+
cx.expected_specific_argument(l.span(), vec!["local_inner_macros"]);
31+
return None;
32+
}
33+
}
34+
}
35+
ArgParser::NameValue(_) => {
36+
let suggestions =
37+
<Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "macro_export");
38+
let span = cx.attr_span;
39+
cx.emit_lint(AttributeLintKind::IllFormedAttributeInput { suggestions }, span);
40+
return None;
41+
}
42+
};
43+
Some(MacroExport { span: cx.attr_span, local_inner_macros })
44+
}
45+
}

compiler/rustc_attr_parsing/src/attributes/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub(crate) mod inline;
3434
pub(crate) mod link_attrs;
3535
pub(crate) mod lint_helpers;
3636
pub(crate) mod loop_match;
37+
pub(crate) mod macro_attrs;
3738
pub(crate) mod must_use;
3839
pub(crate) mod no_implicit_prelude;
3940
pub(crate) mod non_exhaustive;

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
2525
use crate::attributes::link_attrs::{LinkNameParser, LinkSectionParser};
2626
use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser};
2727
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
28+
use crate::attributes::macro_attrs::MacroExportParser;
2829
use crate::attributes::must_use::MustUseParser;
2930
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
3031
use crate::attributes::non_exhaustive::NonExhaustiveParser;
@@ -132,6 +133,7 @@ attribute_parsers!(
132133
Single<InlineParser>,
133134
Single<LinkNameParser>,
134135
Single<LinkSectionParser>,
136+
Single<MacroExportParser>,
135137
Single<MustUseParser>,
136138
Single<OptimizeParser>,
137139
Single<PathAttributeParser>,

compiler/rustc_expand/src/base.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -892,9 +892,9 @@ impl SyntaxExtension {
892892
let allow_internal_unsafe =
893893
ast::attr::find_by_name(attrs, sym::allow_internal_unsafe).is_some();
894894

895-
let local_inner_macros = ast::attr::find_by_name(attrs, sym::macro_export)
896-
.and_then(|macro_export| macro_export.meta_item_list())
897-
.is_some_and(|l| ast::attr::list_contains_name(&l, sym::local_inner_macros));
895+
let local_inner_macros =
896+
*find_attr!(attrs, AttributeKind::MacroExport {local_inner_macros: l, ..} => l)
897+
.unwrap_or(&false);
898898
let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, !is_local);
899899
tracing::debug!(?name, ?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe);
900900

compiler/rustc_lint/src/non_local_def.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
use rustc_attr_data_structures::{AttributeKind, find_attr};
12
use rustc_errors::MultiSpan;
23
use rustc_hir::def::{DefKind, Res};
34
use rustc_hir::intravisit::{self, Visitor, VisitorExt};
45
use rustc_hir::{Body, HirId, Item, ItemKind, Node, Path, TyKind};
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, MacroKind, Span, kw, sym};
9+
use rustc_span::{ExpnKind, MacroKind, 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, MacroKind::Bang)
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_parse/src/validate_attr.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ pub fn check_builtin_meta_item(
286286
| sym::cold
287287
| sym::target_feature
288288
| sym::rustc_allow_const_fn_unstable
289+
| sym::macro_export
289290
| sym::naked
290291
| sym::no_mangle
291292
| sym::non_exhaustive

compiler/rustc_passes/messages.ftl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -395,10 +395,6 @@ passes_invalid_attr_at_crate_level =
395395
passes_invalid_attr_at_crate_level_item =
396396
the inner attribute doesn't annotate this {$kind}
397397
398-
passes_invalid_macro_export_arguments = invalid `#[macro_export]` argument
399-
400-
passes_invalid_macro_export_arguments_too_many_items = `#[macro_export]` can only take 1 or 0 arguments
401-
402398
passes_lang_item_fn = {$name ->
403399
[panic_impl] `#[panic_handler]`
404400
*[other] `{$name}` lang item

compiler/rustc_passes/src/check_attr.rs

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ use rustc_middle::{bug, span_bug};
3232
use rustc_session::config::CrateType;
3333
use rustc_session::lint;
3434
use rustc_session::lint::builtin::{
35-
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
36-
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
35+
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES,
36+
UNUSED_ATTRIBUTES,
3737
};
3838
use rustc_session::parse::feature_err;
3939
use rustc_span::edition::Edition;
@@ -209,6 +209,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
209209
| AttributeKind::ConstStabilityIndirect
210210
| AttributeKind::MacroTransparency(_),
211211
) => { /* do nothing */ }
212+
Attribute::Parsed(AttributeKind::MacroExport { span, .. }) => {
213+
self.check_macro_export(hir_id, *span, target)
214+
}
212215
Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => {
213216
self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target)
214217
}
@@ -308,7 +311,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
308311
self.check_macro_use(hir_id, attr, target)
309312
}
310313
[sym::path, ..] => self.check_generic_attr_unparsed(hir_id, attr, target, Target::Mod),
311-
[sym::macro_export, ..] => self.check_macro_export(hir_id, attr, target),
312314
[sym::should_panic, ..] => {
313315
self.check_generic_attr_unparsed(hir_id, attr, target, Target::Fn)
314316
}
@@ -2280,32 +2282,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
22802282
}
22812283
}
22822284

2283-
fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) {
2285+
fn check_macro_export(&self, hir_id: HirId, attr_span: Span, target: Target) {
22842286
if target != Target::MacroDef {
22852287
self.tcx.emit_node_span_lint(
22862288
UNUSED_ATTRIBUTES,
22872289
hir_id,
2288-
attr.span(),
2290+
attr_span,
22892291
errors::MacroExport::Normal,
22902292
);
2291-
} else if let Some(meta_item_list) = attr.meta_item_list()
2292-
&& !meta_item_list.is_empty()
2293-
{
2294-
if meta_item_list.len() > 1 {
2295-
self.tcx.emit_node_span_lint(
2296-
INVALID_MACRO_EXPORT_ARGUMENTS,
2297-
hir_id,
2298-
attr.span(),
2299-
errors::MacroExport::TooManyItems,
2300-
);
2301-
} else if !meta_item_list[0].has_name(sym::local_inner_macros) {
2302-
self.tcx.emit_node_span_lint(
2303-
INVALID_MACRO_EXPORT_ARGUMENTS,
2304-
hir_id,
2305-
meta_item_list[0].span(),
2306-
errors::MacroExport::InvalidArgument,
2307-
);
2308-
}
23092293
} else {
23102294
// special case when `#[macro_export]` is applied to a macro 2.0
23112295
let (_, macro_definition, _) = self.tcx.hir_node(hir_id).expect_item().expect_macro();
@@ -2315,7 +2299,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
23152299
self.tcx.emit_node_span_lint(
23162300
UNUSED_ATTRIBUTES,
23172301
hir_id,
2318-
attr.span(),
2302+
attr_span,
23192303
errors::MacroExport::OnDeclMacro,
23202304
);
23212305
}
@@ -2669,7 +2653,9 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
26692653
// In the long run, the checks should be harmonized.
26702654
if let ItemKind::Macro(_, macro_def, _) = item.kind {
26712655
let def_id = item.owner_id.to_def_id();
2672-
if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) {
2656+
if macro_def.macro_rules
2657+
&& !find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::MacroExport { .. })
2658+
{
26732659
check_non_exported_macro_for_invalid_attrs(self.tcx, item);
26742660
}
26752661
}
@@ -2799,7 +2785,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
27992785
// which were unsuccessfully resolved due to cannot determine
28002786
// resolution for the attribute macro error.
28012787
const ATTRS_TO_CHECK: &[Symbol] = &[
2802-
sym::macro_export,
28032788
sym::automatically_derived,
28042789
sym::rustc_main,
28052790
sym::derive,
@@ -2823,6 +2808,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
28232808
(*first_attr_span, sym::repr)
28242809
} else if let Attribute::Parsed(AttributeKind::Path(.., span)) = attr {
28252810
(*span, sym::path)
2811+
} else if let Attribute::Parsed(AttributeKind::MacroExport { span, .. }) = attr {
2812+
(*span, sym::macro_export)
28262813
} else {
28272814
continue;
28282815
};

0 commit comments

Comments
 (0)