Skip to content

Commit d62190a

Browse files
committed
Port #[macro_export] to the new attribute parsing infrastructure
1 parent 9ba00e0 commit d62190a

File tree

24 files changed

+320
-119
lines changed

24 files changed

+320
-119
lines changed

compiler/rustc_attr_data_structures/src/attributes.rs

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

370+
/// Represents [`#[macro_export}`](https://doc.rust-lang.org/reference/macros-by-example.html#r-macro.decl.scope.path).
371+
MacroExport { span: Span, local_inner_macros: bool },
372+
370373
/// Represents `#[rustc_macro_transparency]`.
371374
MacroTransparency(Transparency),
372375

compiler/rustc_attr_data_structures/src/encode_cross_crate.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ impl AttributeKind {
4646
LinkSection { .. } => Yes, // Needed for rustdoc
4747
LoopMatch(..) => No,
4848
MacroEscape(..) => No,
49+
MacroExport { .. } => Yes,
4950
MacroTransparency(..) => Yes,
5051
MacroUse { .. } => No,
5152
Marker(..) => No,

compiler/rustc_attr_data_structures/src/lints.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,21 @@ pub struct AttributeLint<Id> {
1010

1111
#[derive(Clone, Debug, HashStable_Generic)]
1212
pub enum AttributeLintKind {
13-
UnusedDuplicate { this: Span, other: Span, warning: bool },
14-
IllFormedAttributeInput { suggestions: Vec<String> },
15-
EmptyAttribute { first_span: Span },
13+
UnusedDuplicate {
14+
this: Span,
15+
other: Span,
16+
warning: bool,
17+
},
18+
IllFormedAttributeInput {
19+
suggestions: Vec<String>,
20+
},
21+
EmptyAttribute {
22+
first_span: Span,
23+
},
24+
/// Copy of `IllFormedAttributeInput`
25+
/// specifically for the `invalid_macro_export_arguments` lint until that is removed,
26+
/// see <https://github.com/rust-lang/rust/pull/143857#issuecomment-3079175663>
27+
InvalidMacroExportArguments {
28+
suggestions: Vec<String>,
29+
},
1630
}

compiler/rustc_attr_parsing/messages.ftl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ attr_parsing_ill_formed_attribute_input = {$num_suggestions ->
3232
*[other] valid forms for the attribute are {$suggestions}
3333
}
3434
35+
attr_parsing_invalid_macro_export_arguments = {$num_suggestions ->
36+
[1] attribute must be of the form {$suggestions}
37+
*[other] valid forms for the attribute are {$suggestions}
38+
}
39+
3540
attr_parsing_incorrect_repr_format_align_one_arg =
3641
incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
3742

compiler/rustc_attr_parsing/src/attributes/macro_attrs.rs

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1+
use rustc_attr_data_structures::AttributeKind::MacroExport;
2+
use rustc_attr_data_structures::lints::AttributeLintKind;
13
use rustc_attr_data_structures::{AttributeKind, MacroUseArgs};
24
use rustc_errors::DiagArgValue;
35
use rustc_feature::{AttributeTemplate, template};
46
use rustc_span::{Span, Symbol, sym};
57
use thin_vec::ThinVec;
68

7-
use crate::attributes::{AcceptMapping, AttributeParser, NoArgsAttributeParser, OnDuplicate};
9+
use crate::attributes::{
10+
AcceptMapping, AttributeOrder, AttributeParser, NoArgsAttributeParser, OnDuplicate,
11+
SingleAttributeParser,
12+
};
813
use crate::context::{AcceptContext, FinalizeContext, Stage};
914
use crate::parser::ArgParser;
1015
use crate::session_diagnostics;
@@ -113,3 +118,58 @@ impl<S: Stage> AttributeParser<S> for MacroUseParser {
113118
Some(AttributeKind::MacroUse { span: self.first_span?, arguments: self.state })
114119
}
115120
}
121+
122+
pub(crate) struct MacroExportParser;
123+
124+
impl<S: Stage> SingleAttributeParser<S> for crate::attributes::macro_attrs::MacroExportParser {
125+
const PATH: &[Symbol] = &[sym::macro_export];
126+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
127+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
128+
const TEMPLATE: AttributeTemplate = template!(Word, List: "local_inner_macros");
129+
130+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
131+
let suggestions =
132+
|| <Self as SingleAttributeParser<S>>::TEMPLATE.suggestions(false, "macro_export");
133+
let local_inner_macros = match args {
134+
ArgParser::NoArgs => false,
135+
ArgParser::List(list) => {
136+
let Some(l) = list.single() else {
137+
let span = cx.attr_span;
138+
cx.emit_lint(
139+
AttributeLintKind::InvalidMacroExportArguments {
140+
suggestions: suggestions(),
141+
},
142+
span,
143+
);
144+
return None;
145+
};
146+
match l.meta_item().and_then(|i| i.path().word_sym()) {
147+
Some(sym::local_inner_macros) => true,
148+
_ => {
149+
let span = cx.attr_span;
150+
cx.emit_lint(
151+
AttributeLintKind::InvalidMacroExportArguments {
152+
suggestions: suggestions(),
153+
},
154+
span,
155+
);
156+
return None;
157+
}
158+
}
159+
}
160+
ArgParser::NameValue(_) => {
161+
let span = cx.attr_span;
162+
let suggestions = suggestions();
163+
cx.emit_err(session_diagnostics::IllFormedAttributeInputLint {
164+
num_suggestions: suggestions.len(),
165+
suggestions: DiagArgValue::StrListSepByAnd(
166+
suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
167+
),
168+
span,
169+
});
170+
return None;
171+
}
172+
};
173+
Some(MacroExport { span: cx.attr_span, local_inner_macros })
174+
}
175+
}

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use crate::attributes::lint_helpers::{
3333
AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser,
3434
};
3535
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
36-
use crate::attributes::macro_attrs::{MacroEscapeParser, MacroUseParser};
36+
use crate::attributes::macro_attrs::{MacroEscapeParser, MacroExportParser, MacroUseParser};
3737
use crate::attributes::must_use::MustUseParser;
3838
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
3939
use crate::attributes::non_exhaustive::NonExhaustiveParser;
@@ -154,6 +154,7 @@ attribute_parsers!(
154154
Single<LinkNameParser>,
155155
Single<LinkOrdinalParser>,
156156
Single<LinkSectionParser>,
157+
Single<MacroExportParser>,
157158
Single<MustUseParser>,
158159
Single<OptimizeParser>,
159160
Single<PathAttributeParser>,

compiler/rustc_attr_parsing/src/lints.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,17 @@ pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<HirId>, lint_emi
3434
*first_span,
3535
session_diagnostics::EmptyAttributeList { attr_span: *first_span },
3636
),
37+
AttributeLintKind::InvalidMacroExportArguments { suggestions } => lint_emitter
38+
.emit_node_span_lint(
39+
rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS,
40+
*id,
41+
*span,
42+
session_diagnostics::IllFormedAttributeInput {
43+
num_suggestions: suggestions.len(),
44+
suggestions: DiagArgValue::StrListSepByAnd(
45+
suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
46+
),
47+
},
48+
),
3749
}
3850
}

compiler/rustc_expand/src/base.rs

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

912-
let local_inner_macros = ast::attr::find_by_name(attrs, sym::macro_export)
913-
.and_then(|macro_export| macro_export.meta_item_list())
914-
.is_some_and(|l| ast::attr::list_contains_name(&l, sym::local_inner_macros));
912+
let local_inner_macros =
913+
*find_attr!(attrs, AttributeKind::MacroExport {local_inner_macros: l, ..} => l)
914+
.unwrap_or(&false);
915915
let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, !is_local);
916916
tracing::debug!(?name, ?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe);
917917

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_lint_defs/src/builtin.rs

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

41944199
declare_lint! {

0 commit comments

Comments
 (0)