Skip to content

Commit b68893d

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 c8a8c82 commit b68893d

File tree

6 files changed

+106
-0
lines changed

6 files changed

+106
-0
lines changed

compiler/rustc_lint/messages.ftl

Lines changed: 5 additions & 0 deletions
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

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

compiler/rustc_lint/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ early_lint_methods!(
181181
UnusedDocComment: UnusedDocComment,
182182
Expr2024: Expr2024,
183183
Precedence: Precedence,
184+
MixedExportNameAndNoMangle: MixedExportNameAndNoMangle,
184185
]
185186
]
186187
);

compiler/rustc_lint/src/lints.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3060,3 +3060,15 @@ pub(crate) struct ReservedString {
30603060
#[suggestion(code = " ", applicability = "machine-applicable")]
30613061
pub suggestion: Span,
30623062
}
3063+
3064+
#[diag(lint_builtin_mixed_export_name_and_no_mangle)]
3065+
pub(crate) struct BuiltinMixedExportNameAndNoMangle {
3066+
#[label]
3067+
pub export_name: Span,
3068+
3069+
#[note]
3070+
pub no_mangle: Span,
3071+
3072+
#[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
3073+
pub removal_span: Span,
3074+
}
Lines changed: 7 additions & 0 deletions
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() {}
Lines changed: 17 additions & 0 deletions
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)