Skip to content

Commit f6d8242

Browse files
committed
- Add test for issue 47446 - Implement the new lint lint_builtin_mixed_export_name_and_no_mangle - Add suggestion how to fix it
1 parent 4203c68 commit f6d8242

File tree

6 files changed

+107
-0
lines changed

6 files changed

+107
-0
lines changed

compiler/rustc_lint/messages.ftl

+5
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ lint_builtin_missing_debug_impl =
117117
118118
lint_builtin_missing_doc = missing documentation for {$article} {$desc}
119119
120+
lint_builtin_mixed_export_name_and_no_mangle = the attribute `export_name` may not be used in combination with `no_mangle`
121+
.label = `export_name` takes precedence
122+
.note = the `no_mangle` attribute is ignored
123+
.suggestion = remove the `no_mangle` attribute
124+
120125
lint_builtin_mutable_transmutes =
121126
transmuting &T to &mut T is undefined behavior, even if the reference is unused, consider instead using an UnsafeCell
122127

compiler/rustc_lint/src/builtin.rs

+64
Original file line numberDiff line numberDiff line change
@@ -3035,3 +3035,67 @@ impl EarlyLintPass for SpecialModuleName {
30353035
}
30363036
}
30373037
}
3038+
3039+
declare_lint! {
3040+
/// The `mixed_export_name_and_no_mangle` lint detects mixed usage of `export_name` and `no_mangle`
3041+
/// where `no_mangle` is not used by the compiler.
3042+
///
3043+
/// ### Example
3044+
///
3045+
/// ```rust,compile_fail
3046+
/// #[no_mangle]
3047+
/// #[export_name = "foo"]
3048+
/// pub fn bar() {}
3049+
///
3050+
/// fn main() {}
3051+
/// ```
3052+
///
3053+
/// {{produces}}
3054+
///
3055+
/// ### Explanation
3056+
///
3057+
/// The compiler will not use the `no_mangle` attribute when generating the symbol name for the function,
3058+
/// as the `export_name` attribute is used instead. This can lead to confusion and is unnecessary.
3059+
///
3060+
MIXED_EXPORT_NAME_AND_NO_MANGLE,
3061+
Warn,
3062+
"mixed usage of export_name and no_mangle, where no_mangle is not used by the compiler"
3063+
}
3064+
3065+
declare_lint_pass!(MixedExportNameAndNoMangle => [MIXED_EXPORT_NAME_AND_NO_MANGLE]);
3066+
3067+
impl MixedExportNameAndNoMangle {
3068+
fn report_mixed_export_name_and_no_mangle(
3069+
&self,
3070+
cx: &EarlyContext<'_>,
3071+
span_export_name: Span,
3072+
span_no_mangle: Span,
3073+
) {
3074+
let decorate = crate::lints::BuiltinMixedExportNameAndNoMangle {
3075+
export_name: span_export_name,
3076+
no_mangle: span_no_mangle.clone(),
3077+
removal_span: span_no_mangle,
3078+
};
3079+
cx.emit_span_lint(MIXED_EXPORT_NAME_AND_NO_MANGLE, span_export_name, decorate);
3080+
}
3081+
}
3082+
3083+
impl EarlyLintPass for MixedExportNameAndNoMangle {
3084+
fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) {
3085+
match it.kind {
3086+
ast::ItemKind::Fn(..) | ast::ItemKind::Static(..) => {
3087+
let no_mangle = attr::find_by_name(&it.attrs, sym::no_mangle);
3088+
let export_name = attr::find_by_name(&it.attrs, sym::export_name);
3089+
if let (Some(no_mangle_attr), Some(export_name_attr)) = (no_mangle, export_name) {
3090+
self.report_mixed_export_name_and_no_mangle(
3091+
cx,
3092+
export_name_attr.span,
3093+
no_mangle_attr.span,
3094+
);
3095+
}
3096+
}
3097+
3098+
_ => {}
3099+
}
3100+
}
3101+
}

compiler/rustc_lint/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ early_lint_methods!(
187187
UnusedDocComment: UnusedDocComment,
188188
Expr2024: Expr2024,
189189
Precedence: Precedence,
190+
MixedExportNameAndNoMangle: MixedExportNameAndNoMangle,
190191
]
191192
]
192193
);

compiler/rustc_lint/src/lints.rs

+13
Original file line numberDiff line numberDiff line change
@@ -3053,3 +3053,16 @@ pub(crate) enum MutRefSugg {
30533053
#[derive(LintDiagnostic)]
30543054
#[diag(lint_unqualified_local_imports)]
30553055
pub(crate) struct UnqualifiedLocalImportsDiag {}
3056+
3057+
#[derive(LintDiagnostic)]
3058+
#[diag(lint_builtin_mixed_export_name_and_no_mangle)]
3059+
pub(crate) struct BuiltinMixedExportNameAndNoMangle {
3060+
#[label]
3061+
pub export_name: Span,
3062+
3063+
#[note]
3064+
pub no_mangle: Span,
3065+
3066+
#[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
3067+
pub removal_span: Span,
3068+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// issue: rust-lang/rust#47446
2+
3+
#[no_mangle]
4+
#[export_name = "foo"]
5+
pub fn bar() {}
6+
7+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
warning: the attribute `export_name` may not be used in combination with `no_mangle`
2+
--> $DIR/E47446.rs:2:1
3+
|
4+
LL | #[export_name = "foo"]
5+
| ^^^^^^^^^^^^^^^^^^^^^^ `export_name` takes precedence
6+
|
7+
= note: when `export_name` is used `no_mangle` is ignored
8+
note: the `no_mangle` attribute is ignored
9+
--> $DIR/E47446.rs:1:1
10+
|
11+
LL | #[no_mangle]
12+
| ^^^^^^^^^^^^
13+
= note: `#[warn(mixed_export_name_and_no_mangle)]` on by default
14+
help: remove the `no_mangle` attribute
15+
|
16+
LL - #[no_mangle]
17+
|

0 commit comments

Comments
 (0)