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 2084831

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

File tree

17 files changed

+120
-80
lines changed

17 files changed

+120
-80
lines changed

‎compiler/rustc_attr_data_structures/src/attributes.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ pub enum AttributeKind {
244244
reason: Option<Symbol>,
245245
},
246246

247+
/// Represents `#[no_mangle]`
248+
NoMangle(Span),
249+
247250
/// Represents `#[optimize(size|speed)]`
248251
Optimize(OptimizeAttr, Span),
249252

‎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::Warn;
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};
@@ -114,6 +114,7 @@ attribute_parsers!(
114114
Single<InlineParser>,
115115
Single<MayDangleParser>,
116116
Single<MustUseParser>,
117+
Single<NoMangleParser>,
117118
Single<OptimizeParser>,
118119
Single<PubTransparentParser>,
119120
Single<RustcForceInlineParser>,

‎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
@@ -174,6 +174,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
174174
Attribute::Parsed(AttributeKind::MustUse { span, .. }) => {
175175
self.check_must_use(hir_id, *span, target)
176176
}
177+
Attribute::Parsed(AttributeKind::NoMangle(attr_span)) => {
178+
self.check_no_mangle(hir_id, *attr_span, span, target)
179+
}
177180
Attribute::Unparsed(attr_item) => {
178181
style = Some(attr_item.style);
179182
match attr.path().as_slice() {
@@ -261,7 +264,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
261264
[sym::link, ..] => self.check_link(hir_id, attr, span, target),
262265
[sym::link_name, ..] => self.check_link_name(hir_id, attr, span, target),
263266
[sym::link_section, ..] => self.check_link_section(hir_id, attr, span, target),
264-
[sym::no_mangle, ..] => self.check_no_mangle(hir_id, attr, span, target),
265267
[sym::macro_use, ..] | [sym::macro_escape, ..] => {
266268
self.check_macro_use(hir_id, attr, target)
267269
}
@@ -698,6 +700,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
698700
AttributeKind::Deprecation { .. }
699701
| AttributeKind::Repr { .. }
700702
| AttributeKind::Align { .. }
703+
| AttributeKind::NoMangle(..)
701704
| AttributeKind::Cold(..)
702705
| AttributeKind::MustUse { .. },
703706
) => {
@@ -1952,7 +1955,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
19521955
}
19531956

19541957
/// Checks if `#[no_mangle]` is applied to a function or static.
1955-
fn check_no_mangle(&self, hir_id: HirId, attr:&Attribute, span: Span, target: Target) {
1958+
fn check_no_mangle(&self, hir_id: HirId, attr_span:Span, span: Span, target: Target) {
19561959
match target {
19571960
Target::Static | Target::Fn => {}
19581961
Target::Method(..) if self.is_impl_item(hir_id) => {}
@@ -1961,7 +1964,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
19611964
// erroneously allowed it and some crates used it accidentally, to be compatible
19621965
// with crates depending on them, we can't throw an error here.
19631966
Target::Field | Target::Arm | Target::MacroDef => {
1964-
self.inline_attr_str_error_with_macro_def(hir_id, attr.span(), "no_mangle");
1967+
self.inline_attr_str_error_with_macro_def(hir_id, attr_span, "no_mangle");
19651968
}
19661969
// FIXME: #[no_mangle] was previously allowed on non-functions/statics, this should be an error
19671970
// The error should specify that the item that is wrong is specifically a *foreign* fn/static
@@ -1975,8 +1978,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
19751978
self.tcx.emit_node_span_lint(
19761979
UNUSED_ATTRIBUTES,
19771980
hir_id,
1978-
attr.span(),
1979-
errors::NoMangleForeign { span, attr_span: attr.span(), foreign_item_kind },
1981+
attr_span,
1982+
errors::NoMangleForeign { span, attr_span, foreign_item_kind },
19801983
);
19811984
}
19821985
_ => {
@@ -1985,7 +1988,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
19851988
self.tcx.emit_node_span_lint(
19861989
UNUSED_ATTRIBUTES,
19871990
hir_id,
1988-
attr.span(),
1991+
attr_span,
19891992
errors::NoMangle { span },
19901993
);
19911994
}

‎src/librustdoc/clean/types.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -746,15 +746,17 @@ impl Item {
746746
Some(tcx.visibility(def_id))
747747
}
748748

749-
pub(crate)fn attributes_without_repr(&self, tcx: TyCtxt<'_>, is_json: bool) -> Vec<String> {
749+
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()
756755
.filter_map(|attr| {
757-
if is_json {
756+
// NoMangle is special-cased because cargo-semver-checks uses it
757+
if matches!(attr, hir::Attribute::Parsed(AttributeKind::NoMangle(..))) {
758+
Some("#[no_mangle]".to_string())
759+
} else if is_json {
758760
match attr {
759761
// rustdoc-json stores this in `Item::deprecation`, so we
760762
// don't want it it `Item::attrs`.
@@ -767,26 +769,22 @@ impl Item {
767769
s
768770
}),
769771
}
770-
} else if attr.has_any_name(ALLOWED_ATTRIBUTES) {
772+
} else {
773+
if !attr.has_any_name(ALLOWED_ATTRIBUTES) {
774+
return None;
775+
}
771776
Some(
772777
rustc_hir_pretty::attribute_to_string(&tcx, attr)
773778
.replace("\\\n", "")
774779
.replace('\n', "")
775780
.replace(" ", " "),
776781
)
777-
} else {
778-
None
779782
}
780783
})
781784
.collect()
782785
}
783786

784-
pub(crate) fn attributes_and_repr(
785-
&self,
786-
tcx: TyCtxt<'_>,
787-
cache: &Cache,
788-
is_json: bool,
789-
) -> Vec<String> {
787+
pub(crate) fn attributes(&self, tcx: TyCtxt<'_>, cache: &Cache, is_json: bool) -> Vec<String> {
790788
let mut attrs = self.attributes_without_repr(tcx, is_json);
791789

792790
if let Some(repr_attr) = self.repr(tcx, cache, is_json) {

0 commit comments

Comments
(0)

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