Skip to content

Commit bb6c5dd

Browse files
committed
Port #[macro_export] to the new attribute parsing infrastructure
1 parent bfc046a commit bb6c5dd

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
@@ -300,6 +300,9 @@ pub enum AttributeKind {
300300
/// Represents `#[loop_match]`.
301301
LoopMatch(Span),
302302

303+
/// Represents [`#[macro_export}`](https://doc.rust-lang.org/reference/macros-by-example.html#r-macro.decl.scope.path).
304+
MacroExport { span: Span, local_inner_macros: bool },
305+
303306
/// Represents `#[rustc_macro_transparency]`.
304307
MacroTransparency(Transparency),
305308

compiler/rustc_attr_data_structures/src/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ impl AttributeKind {
4242
LinkName { .. } => Yes,
4343
LinkSection { .. } => No,
4444
LoopMatch(..) => No,
45+
MacroExport { .. } => Yes,
4546
MacroTransparency(..) => Yes,
4647
Marker(..) => No,
4748
MayDangle(..) => No,
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::KeepOutermost;
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
@@ -35,6 +35,7 @@ pub(crate) mod inline;
3535
pub(crate) mod link_attrs;
3636
pub(crate) mod lint_helpers;
3737
pub(crate) mod loop_match;
38+
pub(crate) mod macro_attrs;
3839
pub(crate) mod must_use;
3940
pub(crate) mod no_implicit_prelude;
4041
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
@@ -29,6 +29,7 @@ use crate::attributes::link_attrs::{
2929
};
3030
use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser};
3131
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
32+
use crate::attributes::macro_attrs::MacroExportParser;
3233
use crate::attributes::must_use::MustUseParser;
3334
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
3435
use crate::attributes::non_exhaustive::NonExhaustiveParser;
@@ -142,6 +143,7 @@ attribute_parsers!(
142143
Single<InlineParser>,
143144
Single<LinkNameParser>,
144145
Single<LinkSectionParser>,
146+
Single<MacroExportParser>,
145147
Single<MustUseParser>,
146148
Single<OptimizeParser>,
147149
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
@@ -302,6 +302,7 @@ pub fn check_builtin_meta_item(
302302
| sym::cold
303303
| sym::target_feature
304304
| sym::rustc_allow_const_fn_unstable
305+
| sym::macro_export
305306
| sym::naked
306307
| sym::no_mangle
307308
| 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;
@@ -242,6 +242,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
242242
| AttributeKind::MacroTransparency(_)
243243
| AttributeKind::Dummy,
244244
) => { /* do nothing */ }
245+
Attribute::Parsed(AttributeKind::MacroExport { span, .. }) => {
246+
self.check_macro_export(hir_id, *span, target)
247+
}
245248
Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => {
246249
self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target)
247250
}
@@ -331,7 +334,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
331334
self.check_macro_use(hir_id, attr, target)
332335
}
333336
[sym::path, ..] => self.check_generic_attr_unparsed(hir_id, attr, target, Target::Mod),
334-
[sym::macro_export, ..] => self.check_macro_export(hir_id, attr, target),
335337
[sym::should_panic, ..] => {
336338
self.check_generic_attr_unparsed(hir_id, attr, target, Target::Fn)
337339
}
@@ -2294,32 +2296,14 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
22942296
}
22952297
}
22962298

2297-
fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) {
2299+
fn check_macro_export(&self, hir_id: HirId, attr_span: Span, target: Target) {
22982300
if target != Target::MacroDef {
22992301
self.tcx.emit_node_span_lint(
23002302
UNUSED_ATTRIBUTES,
23012303
hir_id,
2302-
attr.span(),
2304+
attr_span,
23032305
errors::MacroExport::Normal,
23042306
);
2305-
} else if let Some(meta_item_list) = attr.meta_item_list()
2306-
&& !meta_item_list.is_empty()
2307-
{
2308-
if meta_item_list.len() > 1 {
2309-
self.tcx.emit_node_span_lint(
2310-
INVALID_MACRO_EXPORT_ARGUMENTS,
2311-
hir_id,
2312-
attr.span(),
2313-
errors::MacroExport::TooManyItems,
2314-
);
2315-
} else if !meta_item_list[0].has_name(sym::local_inner_macros) {
2316-
self.tcx.emit_node_span_lint(
2317-
INVALID_MACRO_EXPORT_ARGUMENTS,
2318-
hir_id,
2319-
meta_item_list[0].span(),
2320-
errors::MacroExport::InvalidArgument,
2321-
);
2322-
}
23232307
} else {
23242308
// special case when `#[macro_export]` is applied to a macro 2.0
23252309
let (_, macro_definition, _) = self.tcx.hir_node(hir_id).expect_item().expect_macro();
@@ -2329,7 +2313,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
23292313
self.tcx.emit_node_span_lint(
23302314
UNUSED_ATTRIBUTES,
23312315
hir_id,
2332-
attr.span(),
2316+
attr_span,
23332317
errors::MacroExport::OnDeclMacro,
23342318
);
23352319
}
@@ -2683,7 +2667,9 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
26832667
// In the long run, the checks should be harmonized.
26842668
if let ItemKind::Macro(_, macro_def, _) = item.kind {
26852669
let def_id = item.owner_id.to_def_id();
2686-
if macro_def.macro_rules && !self.tcx.has_attr(def_id, sym::macro_export) {
2670+
if macro_def.macro_rules
2671+
&& !find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::MacroExport { .. })
2672+
{
26872673
check_non_exported_macro_for_invalid_attrs(self.tcx, item);
26882674
}
26892675
}
@@ -2813,7 +2799,6 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
28132799
// which were unsuccessfully resolved due to cannot determine
28142800
// resolution for the attribute macro error.
28152801
const ATTRS_TO_CHECK: &[Symbol] = &[
2816-
sym::macro_export,
28172802
sym::automatically_derived,
28182803
sym::rustc_main,
28192804
sym::derive,
@@ -2837,6 +2822,8 @@ fn check_invalid_crate_level_attr(tcx: TyCtxt<'_>, attrs: &[Attribute]) {
28372822
(*first_attr_span, sym::repr)
28382823
} else if let Attribute::Parsed(AttributeKind::Path(.., span)) = attr {
28392824
(*span, sym::path)
2825+
} else if let Attribute::Parsed(AttributeKind::MacroExport { span, .. }) = attr {
2826+
(*span, sym::macro_export)
28402827
} else {
28412828
continue;
28422829
};

0 commit comments

Comments
 (0)