Skip to content

Commit 90fad60

Browse files
committed
Port #[macro_export] to the new attribute parsing infrastructure
1 parent e3ee7f7 commit 90fad60

File tree

25 files changed

+328
-127
lines changed

25 files changed

+328
-127
lines changed

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: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
use rustc_errors::DiagArgValue;
22
use rustc_feature::{AttributeTemplate, template};
33
use rustc_hir::attrs::{AttributeKind, MacroUseArgs};
4+
use rustc_hir::lints::AttributeLintKind;
45
use rustc_span::{Span, Symbol, sym};
56
use thin_vec::ThinVec;
67

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

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
@@ -910,9 +910,9 @@ impl SyntaxExtension {
910910
let allow_internal_unsafe =
911911
ast::attr::find_by_name(attrs, sym::allow_internal_unsafe).is_some();
912912

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

compiler/rustc_hir/src/attrs/data_structures.rs

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

363+
/// Represents [`#[macro_export}`](https://doc.rust-lang.org/reference/macros-by-example.html#r-macro.decl.scope.path).
364+
MacroExport { span: Span, local_inner_macros: bool },
365+
363366
/// Represents `#[rustc_macro_transparency]`.
364367
MacroTransparency(Transparency),
365368

compiler/rustc_hir/src/attrs/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_hir/src/lints.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,22 @@ 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 },
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+
},
3752
}

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, 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)