Skip to content

Commit 3d1cee5

Browse files
Move mixed export_name/no_mangle check to check_attr.rs and improve the error
Signed-off-by: Jonathan Brouwer <[email protected]>
1 parent 287d9af commit 3d1cee5

12 files changed

+133
-81
lines changed

compiler/rustc_codegen_ssa/messages.ftl

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,6 @@ codegen_ssa_missing_features = add the missing features in a `target_feature` at
205205
codegen_ssa_missing_query_depgraph =
206206
found CGU-reuse attribute but `-Zquery-dep-graph` was not specified
207207
208-
codegen_ssa_mixed_export_name_and_no_mangle = `{$no_mangle_attr}` attribute may not be used in combination with `#[export_name]`
209-
.label = `{$no_mangle_attr}` is ignored
210-
.note = `#[export_name]` takes precedence
211-
.suggestion = remove the `{$no_mangle_attr}` attribute
212-
213208
codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but `link.exe` was not found
214209
215210
codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_attr_data_structures::{
99
use rustc_hir::def::DefKind;
1010
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
1111
use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
12-
use rustc_hir::{self as hir, HirId, LangItem, lang_items};
12+
use rustc_hir::{self as hir, LangItem, lang_items};
1313
use rustc_middle::middle::codegen_fn_attrs::{
1414
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry,
1515
};
@@ -87,7 +87,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
8787

8888
let mut link_ordinal_span = None;
8989
let mut no_sanitize_span = None;
90-
let mut mixed_export_name_no_mangle_lint_state = MixedExportNameAndNoMangleState::default();
9190

9291
for attr in attrs.iter() {
9392
// In some cases, attribute are only valid on functions, but it's the `check_attr`
@@ -119,20 +118,14 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
119118
.max();
120119
}
121120
AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD,
122-
AttributeKind::ExportName { name, span: attr_span } => {
121+
AttributeKind::ExportName { name, .. } => {
123122
codegen_fn_attrs.export_name = Some(*name);
124-
mixed_export_name_no_mangle_lint_state.track_export_name(*attr_span);
125123
}
126124
AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
127125
AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
128126
AttributeKind::NoMangle(attr_span) => {
129127
if tcx.opt_item_name(did.to_def_id()).is_some() {
130128
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
131-
mixed_export_name_no_mangle_lint_state.track_no_mangle(
132-
*attr_span,
133-
tcx.local_def_id_to_hir_id(did),
134-
attr,
135-
);
136129
} else {
137130
tcx.dcx().emit_err(NoMangleNameless {
138131
span: *attr_span,
@@ -437,8 +430,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
437430
}
438431
}
439432

440-
mixed_export_name_no_mangle_lint_state.lint_if_mixed(tcx);
441-
442433
// Apply the minimum function alignment here, so that individual backends don't have to.
443434
codegen_fn_attrs.alignment =
444435
Ord::max(codegen_fn_attrs.alignment, tcx.sess.opts.unstable_opts.min_function_alignment);
@@ -665,49 +656,6 @@ fn check_link_name_xor_ordinal(
665656
}
666657
}
667658

668-
#[derive(Default)]
669-
struct MixedExportNameAndNoMangleState<'a> {
670-
export_name: Option<Span>,
671-
hir_id: Option<HirId>,
672-
no_mangle: Option<Span>,
673-
no_mangle_attr: Option<&'a hir::Attribute>,
674-
}
675-
676-
impl<'a> MixedExportNameAndNoMangleState<'a> {
677-
fn track_export_name(&mut self, span: Span) {
678-
self.export_name = Some(span);
679-
}
680-
681-
fn track_no_mangle(&mut self, span: Span, hir_id: HirId, attr_name: &'a hir::Attribute) {
682-
self.no_mangle = Some(span);
683-
self.hir_id = Some(hir_id);
684-
self.no_mangle_attr = Some(attr_name);
685-
}
686-
687-
/// Emit diagnostics if the lint condition is met.
688-
fn lint_if_mixed(self, tcx: TyCtxt<'_>) {
689-
if let Self {
690-
export_name: Some(export_name),
691-
no_mangle: Some(no_mangle),
692-
hir_id: Some(hir_id),
693-
no_mangle_attr: Some(_),
694-
} = self
695-
{
696-
tcx.emit_node_span_lint(
697-
lint::builtin::UNUSED_ATTRIBUTES,
698-
hir_id,
699-
no_mangle,
700-
errors::MixedExportNameAndNoMangle {
701-
no_mangle,
702-
no_mangle_attr: "#[unsafe(no_mangle)]".to_string(),
703-
export_name,
704-
removal_span: no_mangle,
705-
},
706-
);
707-
}
708-
}
709-
}
710-
711659
/// We now check the #\[rustc_autodiff\] attributes which we generated from the #[autodiff(...)]
712660
/// macros. There are two forms. The pure one without args to mark primal functions (the functions
713661
/// being differentiated). The other form is #[rustc_autodiff(Mode, ActivityList)] on top of the

compiler/rustc_codegen_ssa/src/errors.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,18 +1200,6 @@ pub(crate) struct ErrorCreatingImportLibrary<'a> {
12001200
#[diag(codegen_ssa_aix_strip_not_used)]
12011201
pub(crate) struct AixStripNotUsed;
12021202

1203-
#[derive(LintDiagnostic)]
1204-
#[diag(codegen_ssa_mixed_export_name_and_no_mangle)]
1205-
pub(crate) struct MixedExportNameAndNoMangle {
1206-
#[label]
1207-
pub no_mangle: Span,
1208-
pub no_mangle_attr: String,
1209-
#[note]
1210-
pub export_name: Span,
1211-
#[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
1212-
pub removal_span: Span,
1213-
}
1214-
12151203
#[derive(Diagnostic, Debug)]
12161204
pub(crate) enum XcrunError {
12171205
#[diag(codegen_ssa_xcrun_failed_invoking)]

compiler/rustc_passes/messages.ftl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,11 @@ passes_missing_panic_handler =
486486
passes_missing_stability_attr =
487487
{$descr} has missing stability attribute
488488
489+
passes_mixed_export_name_and_no_mangle = `{$no_mangle_attr}` attribute may not be used in combination with `{$export_name_attr}`
490+
.label = `{$no_mangle_attr}` is ignored
491+
.note = `{$export_name_attr}` takes precedence
492+
.suggestion = remove the `{$no_mangle_attr}` attribute
493+
489494
passes_multiple_rustc_main =
490495
multiple functions with a `#[rustc_main]` attribute
491496
.first = first `#[rustc_main]` function

compiler/rustc_passes/src/check_attr.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@ use rustc_middle::ty::error::{ExpectedFound, TypeError};
3030
use rustc_middle::ty::{self, TyCtxt, TypingMode};
3131
use rustc_middle::{bug, span_bug};
3232
use rustc_session::config::CrateType;
33+
use rustc_session::lint;
3334
use rustc_session::lint::builtin::{
3435
CONFLICTING_REPR_HINTS, INVALID_DOC_ATTRIBUTES, INVALID_MACRO_EXPORT_ARGUMENTS,
3536
UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, UNUSED_ATTRIBUTES,
3637
};
3738
use rustc_session::parse::feature_err;
39+
use rustc_span::edition::Edition;
3840
use rustc_span::{BytePos, DUMMY_SP, Span, Symbol, edition, sym};
3941
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
4042
use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs};
@@ -403,6 +405,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
403405
self.check_repr(attrs, span, target, item, hir_id);
404406
self.check_used(attrs, target, span);
405407
self.check_rustc_force_inline(hir_id, attrs, span, target);
408+
self.check_mix_no_mangle_export(hir_id, attrs);
406409
}
407410

408411
fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr_span: Span, sym: &str) {
@@ -2628,6 +2631,36 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
26282631
}
26292632
}
26302633

2634+
fn check_mix_no_mangle_export(&self, hir_id: HirId, attrs: &[Attribute]) {
2635+
if let Some(export_name_span) = find_attr!(attrs, AttributeKind::ExportName { span: export_name_span, .. } => *export_name_span)
2636+
&& let Some(no_mangle_span) =
2637+
find_attr!(attrs, AttributeKind::NoMangle(no_mangle_span) => *no_mangle_span)
2638+
{
2639+
let no_mangle_attr = if no_mangle_span.edition() >= Edition::Edition2024 {
2640+
"#[unsafe(no_mangle)]"
2641+
} else {
2642+
"#[no_mangle]"
2643+
};
2644+
let export_name_attr = if export_name_span.edition() >= Edition::Edition2024 {
2645+
"#[unsafe(export_name)]"
2646+
} else {
2647+
"#[export_name]"
2648+
};
2649+
2650+
self.tcx.emit_node_span_lint(
2651+
lint::builtin::UNUSED_ATTRIBUTES,
2652+
hir_id,
2653+
no_mangle_span,
2654+
errors::MixedExportNameAndNoMangle {
2655+
no_mangle_span,
2656+
export_name_span,
2657+
no_mangle_attr,
2658+
export_name_attr,
2659+
},
2660+
);
2661+
}
2662+
}
2663+
26312664
/// Checks if `#[autodiff]` is applied to an item other than a function item.
26322665
fn check_autodiff(&self, _hir_id: HirId, _attr: &Attribute, span: Span, target: Target) {
26332666
debug!("check_autodiff");

compiler/rustc_passes/src/errors.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ pub(crate) struct ConstContinueAttr {
4949
pub node_span: Span,
5050
}
5151

52+
#[derive(LintDiagnostic)]
53+
#[diag(passes_mixed_export_name_and_no_mangle)]
54+
pub(crate) struct MixedExportNameAndNoMangle {
55+
#[label]
56+
#[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
57+
pub no_mangle_span: Span,
58+
#[note]
59+
pub export_name_span: Span,
60+
pub no_mangle_attr: &'static str,
61+
pub export_name_attr: &'static str,
62+
}
63+
5264
#[derive(LintDiagnostic)]
5365
#[diag(passes_outer_crate_level_attr)]
5466
pub(crate) struct OuterCrateLevelAttr;

tests/ui/attributes/mixed_export_name_and_no_mangle.fixed

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
//@ check-pass
44

55
#![warn(unused_attributes)]
6-
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
6+
//~^ WARN `#[no_mangle]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
77
#[export_name = "foo"]
88
pub fn bar() {}
99

10-
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
10+
//~^ WARN `#[no_mangle]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
1111
#[export_name = "baz"]
1212
pub fn bak() {}
1313

tests/ui/attributes/mixed_export_name_and_no_mangle.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44

55
#![warn(unused_attributes)]
66
#[no_mangle]
7-
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
7+
//~^ WARN `#[no_mangle]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
88
#[export_name = "foo"]
99
pub fn bar() {}
1010

1111
#[unsafe(no_mangle)]
12-
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
12+
//~^ WARN `#[no_mangle]` attribute may not be used in combination with `#[export_name]` [unused_attributes]
1313
#[export_name = "baz"]
1414
pub fn bak() {}
1515

tests/ui/attributes/mixed_export_name_and_no_mangle.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
warning: `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]`
1+
warning: `#[no_mangle]` attribute may not be used in combination with `#[export_name]`
22
--> $DIR/mixed_export_name_and_no_mangle.rs:6:1
33
|
44
LL | #[no_mangle]
5-
| ^^^^^^^^^^^^ `#[unsafe(no_mangle)]` is ignored
5+
| ^^^^^^^^^^^^ `#[no_mangle]` is ignored
66
|
77
note: `#[export_name]` takes precedence
88
--> $DIR/mixed_export_name_and_no_mangle.rs:8:1
@@ -14,23 +14,23 @@ note: the lint level is defined here
1414
|
1515
LL | #![warn(unused_attributes)]
1616
| ^^^^^^^^^^^^^^^^^
17-
help: remove the `#[unsafe(no_mangle)]` attribute
17+
help: remove the `#[no_mangle]` attribute
1818
|
1919
LL - #[no_mangle]
2020
|
2121

22-
warning: `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[export_name]`
22+
warning: `#[no_mangle]` attribute may not be used in combination with `#[export_name]`
2323
--> $DIR/mixed_export_name_and_no_mangle.rs:11:1
2424
|
2525
LL | #[unsafe(no_mangle)]
26-
| ^^^^^^^^^^^^^^^^^^^^ `#[unsafe(no_mangle)]` is ignored
26+
| ^^^^^^^^^^^^^^^^^^^^ `#[no_mangle]` is ignored
2727
|
2828
note: `#[export_name]` takes precedence
2929
--> $DIR/mixed_export_name_and_no_mangle.rs:13:1
3030
|
3131
LL | #[export_name = "baz"]
3232
| ^^^^^^^^^^^^^^^^^^^^^^
33-
help: remove the `#[unsafe(no_mangle)]` attribute
33+
help: remove the `#[no_mangle]` attribute
3434
|
3535
LL - #[unsafe(no_mangle)]
3636
|
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// issue: rust-lang/rust#47446
2+
//@ run-rustfix
3+
//@ check-pass
4+
//@ edition:2024
5+
6+
#![warn(unused_attributes)]
7+
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[unsafe(export_name)]` [unused_attributes]
8+
#[unsafe(export_name = "foo")]
9+
pub fn bar() {}
10+
11+
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[unsafe(export_name)]` [unused_attributes]
12+
#[unsafe(export_name = "baz")]
13+
pub fn bak() {}
14+
15+
fn main() {}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// issue: rust-lang/rust#47446
2+
//@ run-rustfix
3+
//@ check-pass
4+
//@ edition:2024
5+
6+
#![warn(unused_attributes)]
7+
#[unsafe(no_mangle)]
8+
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[unsafe(export_name)]` [unused_attributes]
9+
#[unsafe(export_name = "foo")]
10+
pub fn bar() {}
11+
12+
#[unsafe(no_mangle)]
13+
//~^ WARN `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[unsafe(export_name)]` [unused_attributes]
14+
#[unsafe(export_name = "baz")]
15+
pub fn bak() {}
16+
17+
fn main() {}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
warning: `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[unsafe(export_name)]`
2+
--> $DIR/mixed_export_name_and_no_mangle_2024.rs:7:1
3+
|
4+
LL | #[unsafe(no_mangle)]
5+
| ^^^^^^^^^^^^^^^^^^^^ `#[unsafe(no_mangle)]` is ignored
6+
|
7+
note: `#[unsafe(export_name)]` takes precedence
8+
--> $DIR/mixed_export_name_and_no_mangle_2024.rs:9:1
9+
|
10+
LL | #[unsafe(export_name = "foo")]
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
note: the lint level is defined here
13+
--> $DIR/mixed_export_name_and_no_mangle_2024.rs:6:9
14+
|
15+
LL | #![warn(unused_attributes)]
16+
| ^^^^^^^^^^^^^^^^^
17+
help: remove the `#[unsafe(no_mangle)]` attribute
18+
|
19+
LL - #[unsafe(no_mangle)]
20+
|
21+
22+
warning: `#[unsafe(no_mangle)]` attribute may not be used in combination with `#[unsafe(export_name)]`
23+
--> $DIR/mixed_export_name_and_no_mangle_2024.rs:12:1
24+
|
25+
LL | #[unsafe(no_mangle)]
26+
| ^^^^^^^^^^^^^^^^^^^^ `#[unsafe(no_mangle)]` is ignored
27+
|
28+
note: `#[unsafe(export_name)]` takes precedence
29+
--> $DIR/mixed_export_name_and_no_mangle_2024.rs:14:1
30+
|
31+
LL | #[unsafe(export_name = "baz")]
32+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
33+
help: remove the `#[unsafe(no_mangle)]` attribute
34+
|
35+
LL - #[unsafe(no_mangle)]
36+
|
37+
38+
warning: 2 warnings emitted
39+

0 commit comments

Comments
 (0)