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 1735b54

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

File tree

12 files changed

+96
-61
lines changed

12 files changed

+96
-61
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/src/codegen_attrs.rs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,28 @@ 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+
no_mangle_span = Some(*attr_span);
127+
if tcx.opt_item_name(did.to_def_id()).is_some() {
128+
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
129+
mixed_export_name_no_mangle_lint_state.track_no_mangle(
130+
*attr_span,
131+
tcx.local_def_id_to_hir_id(did),
132+
attr,
133+
);
134+
} else {
135+
tcx.dcx()
136+
.struct_span_err(
137+
*attr_span,
138+
format!(
139+
"`#[no_mangle]` cannot be used on {} {} as it has no name",
140+
tcx.def_descr_article(did.to_def_id()),
141+
tcx.def_descr(did.to_def_id()),
142+
),
143+
)
144+
.emit();
145+
}
146+
}
125147
_ => {}
126148
}
127149
}
@@ -141,28 +163,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
141163
codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED
142164
}
143165
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-
}
166166
sym::rustc_std_internal_symbol => {
167167
codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL
168168
}

‎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/tools/clippy/clippy_lints/src/functions/must_use.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use clippy_utils::ty::is_must_use_ty;
1515
use clippy_utils::visitors::for_each_expr_without_closures;
1616
use clippy_utils::{return_ty, trait_ref_of_method};
1717
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
18+
use rustc_attr_data_structures::{AttributeKind, find_attr};
1819

1920
use core::ops::ControlFlow;
2021

@@ -33,7 +34,7 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>
3334
let fn_header_span = item.span.with_hi(sig.decl.output.span().hi());
3435
if let Some(attr) = attr {
3536
check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr, attrs, sig);
36-
} else if is_public && !is_proc_macro(attrs) && !attrs.iter().any(|a| a.has_name(sym::no_mangle)) {
37+
} else if is_public && !is_proc_macro(attrs) && !find_attr!(attrs,AttributeKind::NoMangle(..)) {
3738
check_must_use_candidate(
3839
cx,
3940
sig.decl,

‎src/tools/clippy/clippy_lints/src/no_mangle_with_rust_abi.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use rustc_hir::{Item, ItemKind};
66
use rustc_lint::{LateContext, LateLintPass};
77
use rustc_session::declare_lint_pass;
88
use rustc_span::{BytePos, Pos};
9+
use rustc_attr_data_structures::AttributeKind;
10+
use rustc_hir::Attribute;
911

1012
declare_clippy_lint! {
1113
/// ### What it does
@@ -44,8 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi {
4446
let mut app = Applicability::MaybeIncorrect;
4547
let fn_snippet = snippet_with_applicability(cx, fn_sig.span.with_hi(ident.span.lo()), "..", &mut app);
4648
for attr in attrs {
47-
if let Some(ident) = attr.ident()
48-
&& ident.name == rustc_span::sym::no_mangle
49+
if let Attribute::Parsed(AttributeKind::NoMangle(attr_span)) = attr
4950
&& fn_sig.header.abi == ExternAbi::Rust
5051
&& let Some((fn_attrs, _)) = fn_snippet.rsplit_once("fn")
5152
&& !fn_attrs.contains("extern")
@@ -54,7 +55,7 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi {
5455
.span
5556
.with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len()))
5657
.shrink_to_lo();
57-
let attr_snippet = snippet(cx, attr.span(), "..");
58+
let attr_snippet = snippet(cx, *attr_span, "..");
5859

5960
span_lint_and_then(
6061
cx,

‎src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/decl_check.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ impl<'a> DeclValidator<'a> {
201201

202202
// Don't run the lint on extern "[not Rust]" fn items with the
203203
// #[no_mangle] attribute.
204-
let no_mangle = self.db.attrs(func.into()).by_key(sym::no_mangle).exists();
204+
let no_mangle = find_attr!(self.db.attrs(func.into()),AttributeKind::NoMangle(..));
205205
if no_mangle && data.abi.as_ref().is_some_and(|abi| *abi != sym::Rust) {
206206
cov_mark::hit!(extern_func_no_mangle_ignored);
207207
} else {

0 commit comments

Comments
(0)

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