Skip to content

Commit 003a211

Browse files
committed
Improve diagnostic of no_mangle_with_rust_abi
1 parent 8b65632 commit 003a211

File tree

4 files changed

+71
-81
lines changed

4 files changed

+71
-81
lines changed

Diff for: clippy_lints/src/no_mangle_with_rust_abi.rs

+16-12
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
use clippy_utils::diagnostics::span_lint_and_sugg;
1+
use clippy_utils::diagnostics::span_lint_and_then;
22
use clippy_utils::source::snippet_with_applicability;
33
use rustc_errors::Applicability;
44
use rustc_hir::{Item, ItemKind};
55
use rustc_lint::{LateContext, LateLintPass};
66
use rustc_session::{declare_lint_pass, declare_tool_lint};
7+
use rustc_span::{BytePos, Pos};
78
use rustc_target::spec::abi::Abi;
89

910
declare_clippy_lint! {
@@ -38,25 +39,28 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi {
3839
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
3940
if let ItemKind::Fn(fn_sig, _, _) = &item.kind {
4041
let attrs = cx.tcx.hir().attrs(item.hir_id());
41-
let mut applicability = Applicability::MachineApplicable;
42-
let snippet = snippet_with_applicability(cx, fn_sig.span, "..", &mut applicability);
42+
let mut app = Applicability::MaybeIncorrect;
43+
let snippet = snippet_with_applicability(cx, fn_sig.span, "..", &mut app);
4344
for attr in attrs {
4445
if let Some(ident) = attr.ident()
4546
&& ident.name == rustc_span::sym::no_mangle
4647
&& fn_sig.header.abi == Abi::Rust
47-
&& !snippet.contains("extern") {
48+
&& let Some((fn_attrs, _)) = snippet.split_once("fn")
49+
&& !fn_attrs.contains("extern")
50+
{
51+
let sugg_span = fn_sig.span
52+
.with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len()))
53+
.shrink_to_lo();
4854

49-
let suggestion = snippet.split_once("fn")
50-
.map_or(String::new(), |(first, second)| format!(r#"{first}extern "C" fn{second}"#));
51-
52-
span_lint_and_sugg(
55+
span_lint_and_then(
5356
cx,
5457
NO_MANGLE_WITH_RUST_ABI,
5558
fn_sig.span,
56-
"attribute #[no_mangle] set on a Rust ABI function",
57-
"try",
58-
suggestion,
59-
applicability
59+
"`#[no_mangle]` set on a function with the default (`Rust`) ABI",
60+
|diag| {
61+
diag.span_suggestion(sugg_span, "set an ABI", "extern \"C\" ", app)
62+
.span_suggestion(sugg_span, "or explicitly set the default", "extern \"Rust\" ", app);
63+
},
6064
);
6165
}
6266
}

Diff for: tests/ui/no_mangle_with_rust_abi.fixed

-48
This file was deleted.

Diff for: tests/ui/no_mangle_with_rust_abi.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// run-rustfix
2-
31
#![allow(unused)]
42
#![warn(clippy::no_mangle_with_rust_abi)]
53

Diff for: tests/ui/no_mangle_with_rust_abi.stderr

+55-19
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,81 @@
1-
error: attribute #[no_mangle] set on a Rust ABI function
2-
--> $DIR/no_mangle_with_rust_abi.rs:7:1
1+
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
2+
--> $DIR/no_mangle_with_rust_abi.rs:5:1
33
|
44
LL | fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize)`
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66
|
77
= note: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings`
8+
help: set an ABI
9+
|
10+
LL | extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
11+
| ++++++++++
12+
help: or explicitly set the default
13+
|
14+
LL | extern "Rust" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
15+
| +++++++++++++
816

9-
error: attribute #[no_mangle] set on a Rust ABI function
10-
--> $DIR/no_mangle_with_rust_abi.rs:10:1
17+
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
18+
--> $DIR/no_mangle_with_rust_abi.rs:8:1
1119
|
1220
LL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
13-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `pub extern "C" fn rust_abi_fn_two(arg_one: u32, arg_two: usize)`
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
22+
|
23+
help: set an ABI
24+
|
25+
LL | pub extern "C" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
26+
| ++++++++++
27+
help: or explicitly set the default
28+
|
29+
LL | pub extern "Rust" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
30+
| +++++++++++++
1431

15-
error: attribute #[no_mangle] set on a Rust ABI function
16-
--> $DIR/no_mangle_with_rust_abi.rs:15:1
32+
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
33+
--> $DIR/no_mangle_with_rust_abi.rs:13:1
1734
|
1835
LL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
19-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `pub unsafe extern "C" fn rust_abi_fn_three(arg_one: u32, arg_two: usize)`
36+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
37+
|
38+
help: set an ABI
39+
|
40+
LL | pub unsafe extern "C" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
41+
| ++++++++++
42+
help: or explicitly set the default
43+
|
44+
LL | pub unsafe extern "Rust" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
45+
| +++++++++++++
2046

21-
error: attribute #[no_mangle] set on a Rust ABI function
22-
--> $DIR/no_mangle_with_rust_abi.rs:20:1
47+
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
48+
--> $DIR/no_mangle_with_rust_abi.rs:18:1
2349
|
2450
LL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
25-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe extern "C" fn rust_abi_fn_four(arg_one: u32, arg_two: usize)`
51+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
52+
|
53+
help: set an ABI
54+
|
55+
LL | unsafe extern "C" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
56+
| ++++++++++
57+
help: or explicitly set the default
58+
|
59+
LL | unsafe extern "Rust" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
60+
| +++++++++++++
2661

27-
error: attribute #[no_mangle] set on a Rust ABI function
28-
--> $DIR/no_mangle_with_rust_abi.rs:23:1
62+
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
63+
--> $DIR/no_mangle_with_rust_abi.rs:21:1
2964
|
3065
LL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
3166
LL | | arg_one: u32,
3267
LL | | arg_two: usize,
3368
LL | | ) -> u32 {
3469
| |________^
3570
|
36-
help: try
71+
help: set an ABI
3772
|
38-
LL + extern "C" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
39-
LL + arg_one: u32,
40-
LL + arg_two: usize,
41-
LL ~ ) -> u32 {
73+
LL | extern "C" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
74+
| ++++++++++
75+
help: or explicitly set the default
4276
|
77+
LL | extern "Rust" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
78+
| +++++++++++++
4379

4480
error: aborting due to 5 previous errors
4581

0 commit comments

Comments
 (0)