Skip to content

Commit 83731a6

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 612fce2 commit 83731a6

12 files changed

+131
-83
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`
@@ -121,20 +120,14 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
121120
.max();
122121
}
123122
AttributeKind::Cold(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD,
124-
AttributeKind::ExportName { name, span: attr_span } => {
123+
AttributeKind::ExportName { name, .. } => {
125124
codegen_fn_attrs.export_name = Some(*name);
126-
mixed_export_name_no_mangle_lint_state.track_export_name(*attr_span);
127125
}
128126
AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
129127
AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
130128
AttributeKind::NoMangle(attr_span) => {
131129
if tcx.opt_item_name(did.to_def_id()).is_some() {
132130
codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE;
133-
mixed_export_name_no_mangle_lint_state.track_no_mangle(
134-
*attr_span,
135-
tcx.local_def_id_to_hir_id(did),
136-
attr,
137-
);
138131
} else {
139132
tcx.dcx().emit_err(NoMangleNameless {
140133
span: *attr_span,
@@ -439,8 +432,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
439432
}
440433
}
441434

442-
mixed_export_name_no_mangle_lint_state.lint_if_mixed(tcx);
443-
444435
// Apply the minimum function alignment here, so that individual backends don't have to.
445436
codegen_fn_attrs.alignment =
446437
Ord::max(codegen_fn_attrs.alignment, tcx.sess.opts.unstable_opts.min_function_alignment);
@@ -667,49 +658,6 @@ fn check_link_name_xor_ordinal(
667658
}
668659
}
669660

670-
#[derive(Default)]
671-
struct MixedExportNameAndNoMangleState<'a> {
672-
export_name: Option<Span>,
673-
hir_id: Option<HirId>,
674-
no_mangle: Option<Span>,
675-
no_mangle_attr: Option<&'a hir::Attribute>,
676-
}
677-
678-
impl<'a> MixedExportNameAndNoMangleState<'a> {
679-
fn track_export_name(&mut self, span: Span) {
680-
self.export_name = Some(span);
681-
}
682-
683-
fn track_no_mangle(&mut self, span: Span, hir_id: HirId, attr_name: &'a hir::Attribute) {
684-
self.no_mangle = Some(span);
685-
self.hir_id = Some(hir_id);
686-
self.no_mangle_attr = Some(attr_name);
687-
}
688-
689-
/// Emit diagnostics if the lint condition is met.
690-
fn lint_if_mixed(self, tcx: TyCtxt<'_>) {
691-
if let Self {
692-
export_name: Some(export_name),
693-
no_mangle: Some(no_mangle),
694-
hir_id: Some(hir_id),
695-
no_mangle_attr: Some(_),
696-
} = self
697-
{
698-
tcx.emit_node_span_lint(
699-
lint::builtin::UNUSED_ATTRIBUTES,
700-
hir_id,
701-
no_mangle,
702-
errors::MixedExportNameAndNoMangle {
703-
no_mangle,
704-
no_mangle_attr: "#[unsafe(no_mangle)]".to_string(),
705-
export_name,
706-
removal_span: no_mangle,
707-
},
708-
);
709-
}
710-
}
711-
}
712-
713661
/// We now check the #\[rustc_autodiff\] attributes which we generated from the #[autodiff(...)]
714662
/// macros. There are two forms. The pure one without args to mark primal functions (the functions
715663
/// 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
@@ -479,6 +479,11 @@ passes_missing_panic_handler =
479479
passes_missing_stability_attr =
480480
{$descr} has missing stability attribute
481481
482+
passes_mixed_export_name_and_no_mangle = `{$no_mangle_attr}` attribute may not be used in combination with `{$export_name_attr}`
483+
.label = `{$no_mangle_attr}` is ignored
484+
.note = `#[unsafe(export_name)]` takes precedence
485+
.suggestion = remove the `{$no_mangle_attr}` attribute
486+
482487
passes_multiple_rustc_main =
483488
multiple functions with a `#[rustc_main]` attribute
484489
.first = first `#[rustc_main]` function

compiler/rustc_passes/src/check_attr.rs

Lines changed: 29 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};
@@ -397,6 +399,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
397399
self.check_repr(attrs, span, target, item, hir_id);
398400
self.check_used(attrs, target, span);
399401
self.check_rustc_force_inline(hir_id, attrs, span, target);
402+
self.check_mix_no_mangle_export(hir_id, attrs);
400403
}
401404

402405
fn inline_attr_str_error_with_macro_def(&self, hir_id: HirId, attr_span: Span, sym: &str) {
@@ -2624,6 +2627,32 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
26242627
}
26252628
}
26262629

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

compiler/rustc_passes/src/errors.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ pub(crate) struct AutoDiffAttr {
3131
pub attr_span: Span,
3232
}
3333

34+
#[derive(LintDiagnostic)]
35+
#[diag(passes_mixed_export_name_and_no_mangle)]
36+
pub(crate) struct MixedExportNameAndNoMangle {
37+
#[label]
38+
#[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
39+
pub no_mangle_span: Span,
40+
#[note]
41+
pub export_name_span: Span,
42+
pub no_mangle_attr: &'static str,
43+
pub export_name_attr: &'static str,
44+
}
45+
3446
#[derive(LintDiagnostic)]
3547
#[diag(passes_outer_crate_level_attr)]
3648
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: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
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
|
7-
note: `#[export_name]` takes precedence
7+
note: `#[unsafe(export_name)]` takes precedence
88
--> $DIR/mixed_export_name_and_no_mangle.rs:8:1
99
|
1010
LL | #[export_name = "foo"]
@@ -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
|
28-
note: `#[export_name]` takes precedence
28+
note: `#[unsafe(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)