Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 628e1ee

Browse files
Port #[no_mangle] to new attribute parsing infrastructure
Signed-off-by: Jonathan Brouwer <jonathantbrouwer@gmail.com>
1 parent 6d0c9e2 commit 628e1ee

File tree

17 files changed

+114
-67
lines changed

17 files changed

+114
-67
lines changed

‎compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ pub enum AttributeKind {
233233

234234
/// Represents `#[rustc_macro_transparency]`.
235235
MacroTransparency(Transparency),
236+
/// Represents `#[no_mangle]`
237+
NoMangle(Span),
236238
/// Represents `#[optimize(size|speed)]`
237239
Optimize(OptimizeAttr, Span),
238240
/// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).

‎compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,21 @@ impl<S: Stage> SingleAttributeParser<S> for ColdParser {
5656
Some(AttributeKind::Cold(cx.attr_span))
5757
}
5858
}
59+
60+
pub(crate) struct NoMangleParser;
61+
62+
impl<S: Stage> SingleAttributeParser<S> for NoMangleParser {
63+
const PATH: &[rustc_span::Symbol] = &[sym::no_mangle];
64+
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepLast;
65+
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
66+
const TEMPLATE: AttributeTemplate = template!(Word);
67+
68+
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
69+
if !args.no_args() {
70+
cx.expected_no_args(args.span().unwrap_or(cx.attr_span));
71+
return None;
72+
};
73+
74+
Some(AttributeKind::NoMangle(cx.attr_span))
75+
}
76+
}

‎compiler/rustc_attr_parsing/src/context.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_session::Session;
1515
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym};
1616

1717
use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser};
18-
use crate::attributes::codegen_attrs::{ColdParser, OptimizeParser};
18+
use crate::attributes::codegen_attrs::{ColdParser, NoMangleParser,OptimizeParser};
1919
use crate::attributes::confusables::ConfusablesParser;
2020
use crate::attributes::deprecation::DeprecationParser;
2121
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
@@ -110,6 +110,7 @@ attribute_parsers!(
110110
Single<ConstStabilityIndirectParser>,
111111
Single<DeprecationParser>,
112112
Single<InlineParser>,
113+
Single<NoMangleParser>,
113114
Single<OptimizeParser>,
114115
Single<RustcForceInlineParser>,
115116
Single<TransparencyParser>,

‎compiler/rustc_codegen_ssa/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple time
221221
222222
codegen_ssa_no_field = no field `{$name}`
223223
224+
codegen_ssa_no_mangle_nameless = `#[no_mangle]` cannot be used on {$definition} as it has no name
225+
224226
codegen_ssa_no_module_named =
225227
no module named `{$user_path}` (mangled: {$cgu_name}). available modules: {$cgu_names}
226228

‎compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use rustc_span::{Ident, Span, sym};
2323
use rustc_target::spec::SanitizerSet;
2424

2525
use crate::errors;
26+
use crate::errors::NoMangleNameless;
2627
use crate::target_features::{
2728
check_target_feature_trait_unsafe, check_tied_features, from_target_feature_attr,
2829
};
@@ -87,7 +88,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
8788
let mut link_ordinal_span = None;
8889
let mut no_sanitize_span = None;
8990
let mut mixed_export_name_no_mangle_lint_state = MixedExportNameAndNoMangleState::default();
90-
let mut no_mangle_span = None;
9191

9292
for attr in attrs.iter() {
9393
// In some cases, attribute are only valid on functions, but it's the `check_attr`
@@ -122,6 +122,25 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
122122
}
123123
AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD,
124124
AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
125+
AttributeKind::NoMangle(attr_span) => {
126+
if tcx.opt_item_name(did.to_def_id()).is_some() {
127+
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
128+
mixed_export_name_no_mangle_lint_state.track_no_mangle(
129+
*attr_span,
130+
tcx.local_def_id_to_hir_id(did),
131+
attr,
132+
);
133+
} else {
134+
tcx.dcx().emit_err(NoMangleNameless {
135+
span: *attr_span,
136+
definition: format!(
137+
"{} {}",
138+
tcx.def_descr_article(did.to_def_id()),
139+
tcx.def_descr(did.to_def_id())
140+
),
141+
});
142+
}
143+
}
125144
_ => {}
126145
}
127146
}
@@ -141,28 +160,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
141160
codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED
142161
}
143162
sym::naked => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
144-
sym::no_mangle => {
145-
no_mangle_span = Some(attr.span());
146-
if tcx.opt_item_name(did.to_def_id()).is_some() {
147-
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
148-
mixed_export_name_no_mangle_lint_state.track_no_mangle(
149-
attr.span(),
150-
tcx.local_def_id_to_hir_id(did),
151-
attr,
152-
);
153-
} else {
154-
tcx.dcx()
155-
.struct_span_err(
156-
attr.span(),
157-
format!(
158-
"`#[no_mangle]` cannot be used on {} {} as it has no name",
159-
tcx.def_descr_article(did.to_def_id()),
160-
tcx.def_descr(did.to_def_id()),
161-
),
162-
)
163-
.emit();
164-
}
165-
}
166163
sym::rustc_std_internal_symbol => {
167164
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL
168165
}
@@ -544,12 +541,15 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
544541
if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
545542
&& codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE)
546543
{
544+
let no_mangle_span =
545+
find_attr!(attrs, AttributeKind::NoMangle(no_mangle_span) => *no_mangle_span)
546+
.unwrap_or_default();
547547
let lang_item =
548548
lang_items::extract(attrs).map_or(None, |(name, _span)| LangItem::from_name(name));
549549
let mut err = tcx
550550
.dcx()
551551
.struct_span_err(
552-
no_mangle_span.unwrap_or_default(),
552+
no_mangle_span,
553553
"`#[no_mangle]` cannot be used on internal language items",
554554
)
555555
.with_note("Rustc requires this item to have a specific mangled name.")

‎compiler/rustc_codegen_ssa/src/errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1310,3 +1310,11 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetFeatureDisableOrEnable<'_
13101310
diag
13111311
}
13121312
}
1313+
1314+
#[derive(Diagnostic)]
1315+
#[diag(codegen_ssa_no_mangle_nameless)]
1316+
pub(crate) struct NoMangleNameless {
1317+
#[primary_span]
1318+
pub span: Span,
1319+
pub definition: String,
1320+
}

‎compiler/rustc_lint/src/builtin.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree};
2121
use rustc_ast::visit::{FnCtxt, FnKind};
2222
use rustc_ast::{self as ast, *};
2323
use rustc_ast_pretty::pprust::expr_to_string;
24+
use rustc_attr_data_structures::{AttributeKind, find_attr};
2425
use rustc_errors::{Applicability, LintDiagnostic};
2526
use rustc_feature::GateIssue;
2627
use rustc_hir as hir;
@@ -954,7 +955,7 @@ declare_lint_pass!(InvalidNoMangleItems => [NO_MANGLE_CONST_ITEMS, NO_MANGLE_GEN
954955
impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
955956
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
956957
let attrs = cx.tcx.hir_attrs(it.hir_id());
957-
let check_no_mangle_on_generic_fn = |attr:&hir::Attribute,
958+
let check_no_mangle_on_generic_fn = |attr_span:Span,
958959
impl_generics: Option<&hir::Generics<'_>>,
959960
generics: &hir::Generics<'_>,
960961
span| {
@@ -967,7 +968,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
967968
cx.emit_span_lint(
968969
NO_MANGLE_GENERIC_ITEMS,
969970
span,
970-
BuiltinNoMangleGeneric { suggestion: attr.span() },
971+
BuiltinNoMangleGeneric { suggestion: attr_span },
971972
);
972973
break;
973974
}
@@ -976,14 +977,15 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
976977
};
977978
match it.kind {
978979
hir::ItemKind::Fn { generics, .. } => {
979-
if let Some(attr) = attr::find_by_name(attrs, sym::export_name)
980-
.or_else(|| attr::find_by_name(attrs, sym::no_mangle))
980+
if let Some(attr_span) = attr::find_by_name(attrs, sym::export_name)
981+
.map(|at| at.span())
982+
.or_else(|| find_attr!(attrs, AttributeKind::NoMangle(span) => *span))
981983
{
982-
check_no_mangle_on_generic_fn(attr, None, generics, it.span);
984+
check_no_mangle_on_generic_fn(attr_span, None, generics, it.span);
983985
}
984986
}
985987
hir::ItemKind::Const(..) => {
986-
if attr::contains_name(attrs, sym::no_mangle) {
988+
if find_attr!(attrs, AttributeKind::NoMangle(..)) {
987989
// account for "pub const" (#45562)
988990
let start = cx
989991
.tcx
@@ -1008,11 +1010,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems {
10081010
for it in *items {
10091011
if let hir::AssocItemKind::Fn { .. } = it.kind {
10101012
let attrs = cx.tcx.hir_attrs(it.id.hir_id());
1011-
if let Some(attr) = attr::find_by_name(attrs, sym::export_name)
1012-
.or_else(|| attr::find_by_name(attrs, sym::no_mangle))
1013+
if let Some(attr_span) = attr::find_by_name(attrs, sym::export_name)
1014+
.map(|at| at.span())
1015+
.or_else(|| find_attr!(attrs, AttributeKind::NoMangle(span) => *span))
10131016
{
10141017
check_no_mangle_on_generic_fn(
1015-
attr,
1018+
attr_span,
10161019
Some(generics),
10171020
cx.tcx.hir_get_generics(it.id.owner_id.def_id).unwrap(),
10181021
it.span,

‎compiler/rustc_lint/src/nonstandard_style.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc_abi::ExternAbi;
2-
use rustc_attr_data_structures::{AttributeKind, ReprAttr};
2+
use rustc_attr_data_structures::{AttributeKind, ReprAttr, find_attr};
33
use rustc_attr_parsing::AttributeParser;
44
use rustc_hir::def::{DefKind, Res};
55
use rustc_hir::intravisit::FnKind;
@@ -396,7 +396,9 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
396396
match &fk {
397397
FnKind::Method(ident, sig, ..) => match method_context(cx, id) {
398398
MethodLateContext::PlainImpl => {
399-
if sig.header.abi != ExternAbi::Rust && cx.tcx.has_attr(id, sym::no_mangle) {
399+
if sig.header.abi != ExternAbi::Rust
400+
&& find_attr!(cx.tcx.get_all_attrs(id), AttributeKind::NoMangle(..))
401+
{
400402
return;
401403
}
402404
self.check_snake_case(cx, "method", ident);
@@ -408,7 +410,9 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
408410
},
409411
FnKind::ItemFn(ident, _, header) => {
410412
// Skip foreign-ABI #[no_mangle] functions (Issue #31924)
411-
if header.abi != ExternAbi::Rust && cx.tcx.has_attr(id, sym::no_mangle) {
413+
if header.abi != ExternAbi::Rust
414+
&& find_attr!(cx.tcx.get_all_attrs(id), AttributeKind::NoMangle(..))
415+
{
412416
return;
413417
}
414418
self.check_snake_case(cx, "function", ident);
@@ -514,7 +518,7 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
514518
let attrs = cx.tcx.hir_attrs(it.hir_id());
515519
match it.kind {
516520
hir::ItemKind::Static(_, ident, ..)
517-
if !ast::attr::contains_name(attrs, sym::no_mangle) =>
521+
if !find_attr!(attrs, AttributeKind::NoMangle(..)) =>
518522
{
519523
NonUpperCaseGlobals::check_upper_case(cx, "static variable", &ident);
520524
}

‎compiler/rustc_passes/src/check_attr.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
163163
Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => {
164164
self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target)
165165
}
166+
Attribute::Parsed(AttributeKind::NoMangle(attr_span)) => {
167+
self.check_no_mangle(hir_id, *attr_span, span, target)
168+
}
166169
Attribute::Unparsed(_) => {
167170
match attr.path().as_slice() {
168171
[sym::diagnostic, sym::do_not_recommend, ..] => {
@@ -250,7 +253,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
250253
[sym::link, ..] => self.check_link(hir_id, attr, span, target),
251254
[sym::link_name, ..] => self.check_link_name(hir_id, attr, span, target),
252255
[sym::link_section, ..] => self.check_link_section(hir_id, attr, span, target),
253-
[sym::no_mangle, ..] => self.check_no_mangle(hir_id, attr, span, target),
254256
[sym::macro_use, ..] | [sym::macro_escape, ..] => {
255257
self.check_macro_use(hir_id, attr, target)
256258
}
@@ -688,6 +690,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
688690
AttributeKind::Deprecation { .. }
689691
| AttributeKind::Repr { .. }
690692
| AttributeKind::Align { .. }
693+
| AttributeKind::NoMangle(..)
691694
| AttributeKind::Cold(..),
692695
) => {
693696
continue;
@@ -1936,7 +1939,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
19361939
}
19371940

19381941
/// Checks if `#[no_mangle]` is applied to a function or static.
1939-
fn check_no_mangle(&self, hir_id: HirId, attr:&Attribute, span: Span, target: Target) {
1942+
fn check_no_mangle(&self, hir_id: HirId, attr_span:Span, span: Span, target: Target) {
19401943
match target {
19411944
Target::Static | Target::Fn => {}
19421945
Target::Method(..) if self.is_impl_item(hir_id) => {}
@@ -1945,7 +1948,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
19451948
// erroneously allowed it and some crates used it accidentally, to be compatible
19461949
// with crates depending on them, we can't throw an error here.
19471950
Target::Field | Target::Arm | Target::MacroDef => {
1948-
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "no_mangle");
1951+
self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "no_mangle");
19491952
}
19501953
// FIXME: #[no_mangle] was previously allowed on non-functions/statics, this should be an error
19511954
// The error should specify that the item that is wrong is specifically a *foreign* fn/static
@@ -1959,8 +1962,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
19591962
self.tcx.emit_node_span_lint(
19601963
UNUSED_ATTRIBUTES,
19611964
hir_id,
1962-
attr.span(),
1963-
errors::NoMangleForeign { span, attr_span: attr.span(), foreign_item_kind },
1965+
attr_span,
1966+
errors::NoMangleForeign { span, attr_span, foreign_item_kind },
19641967
);
19651968
}
19661969
_ => {
@@ -1969,7 +1972,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
19691972
self.tcx.emit_node_span_lint(
19701973
UNUSED_ATTRIBUTES,
19711974
hir_id,
1972-
attr.span(),
1975+
attr_span,
19731976
errors::NoMangle { span },
19741977
);
19751978
}

‎src/librustdoc/clean/types.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,6 @@ impl Item {
749749
pub(crate) fn attributes_without_repr(&self, tcx: TyCtxt<'_>, is_json: bool) -> Vec<String> {
750750
const ALLOWED_ATTRIBUTES: &[Symbol] =
751751
&[sym::export_name, sym::link_section, sym::no_mangle, sym::non_exhaustive];
752-
753752
self.attrs
754753
.other_attrs
755754
.iter()
@@ -767,6 +766,9 @@ impl Item {
767766
s
768767
}),
769768
}
769+
} else if matches!(attr, hir::Attribute::Parsed(AttributeKind::NoMangle(..))) {
770+
// FIXME: We don't use the pretty printing of parsed attributes here because the pretty-print is not very pretty...
771+
Some("#[no_mangle]".to_string())
770772
} else if attr.has_any_name(ALLOWED_ATTRIBUTES) {
771773
Some(
772774
rustc_hir_pretty::attribute_to_string(&tcx, attr)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /