Skip to content

Commit

Permalink
Auto merge of #10420 - Jarcho:no_mangle_diag, r=dswij
Browse files Browse the repository at this point in the history
Improve diagnostic of `no_mangle_with_rust_abi`

fixes #10409

Pending rust-lang/rustfmt#5701

This rewords the message to focus on the error being an implicit ABI, rather than the `Rust` ABI. Also downgrades the suggestion to `MaybeIncorrect` and changes the suggestion span to better highlight the change.

---

changelog: None
<!-- changelog_checked -->
  • Loading branch information
bors committed Mar 11, 2023
2 parents 8e1dd06 + 003a211 commit e426ba4
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 81 deletions.
28 changes: 16 additions & 12 deletions clippy_lints/src/no_mangle_with_rust_abi.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::snippet_with_applicability;
use rustc_errors::Applicability;
use rustc_hir::{Item, ItemKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{BytePos, Pos};
use rustc_target::spec::abi::Abi;

declare_clippy_lint! {
Expand Down Expand Up @@ -38,25 +39,28 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi {
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
if let ItemKind::Fn(fn_sig, _, _) = &item.kind {
let attrs = cx.tcx.hir().attrs(item.hir_id());
let mut applicability = Applicability::MachineApplicable;
let snippet = snippet_with_applicability(cx, fn_sig.span, "..", &mut applicability);
let mut app = Applicability::MaybeIncorrect;
let snippet = snippet_with_applicability(cx, fn_sig.span, "..", &mut app);
for attr in attrs {
if let Some(ident) = attr.ident()
&& ident.name == rustc_span::sym::no_mangle
&& fn_sig.header.abi == Abi::Rust
&& !snippet.contains("extern") {
&& let Some((fn_attrs, _)) = snippet.split_once("fn")
&& !fn_attrs.contains("extern")
{
let sugg_span = fn_sig.span
.with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len()))
.shrink_to_lo();

let suggestion = snippet.split_once("fn")
.map_or(String::new(), |(first, second)| format!(r#"{first}extern "C" fn{second}"#));

span_lint_and_sugg(
span_lint_and_then(
cx,
NO_MANGLE_WITH_RUST_ABI,
fn_sig.span,
"attribute #[no_mangle] set on a Rust ABI function",
"try",
suggestion,
applicability
"`#[no_mangle]` set on a function with the default (`Rust`) ABI",
|diag| {
diag.span_suggestion(sugg_span, "set an ABI", "extern \"C\" ", app)
.span_suggestion(sugg_span, "or explicitly set the default", "extern \"Rust\" ", app);
},
);
}
}
Expand Down
48 changes: 0 additions & 48 deletions tests/ui/no_mangle_with_rust_abi.fixed

This file was deleted.

2 changes: 0 additions & 2 deletions tests/ui/no_mangle_with_rust_abi.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
// run-rustfix

#![allow(unused)]
#![warn(clippy::no_mangle_with_rust_abi)]

Expand Down
74 changes: 55 additions & 19 deletions tests/ui/no_mangle_with_rust_abi.stderr
Original file line number Diff line number Diff line change
@@ -1,45 +1,81 @@
error: attribute #[no_mangle] set on a Rust ABI function
--> $DIR/no_mangle_with_rust_abi.rs:7:1
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
--> $DIR/no_mangle_with_rust_abi.rs:5:1
|
LL | fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize)`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings`
help: set an ABI
|
LL | extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
| ++++++++++
help: or explicitly set the default
|
LL | extern "Rust" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {}
| +++++++++++++

error: attribute #[no_mangle] set on a Rust ABI function
--> $DIR/no_mangle_with_rust_abi.rs:10:1
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
--> $DIR/no_mangle_with_rust_abi.rs:8:1
|
LL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `pub extern "C" fn rust_abi_fn_two(arg_one: u32, arg_two: usize)`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: set an ABI
|
LL | pub extern "C" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
| ++++++++++
help: or explicitly set the default
|
LL | pub extern "Rust" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {}
| +++++++++++++

error: attribute #[no_mangle] set on a Rust ABI function
--> $DIR/no_mangle_with_rust_abi.rs:15:1
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
--> $DIR/no_mangle_with_rust_abi.rs:13:1
|
LL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `pub unsafe extern "C" fn rust_abi_fn_three(arg_one: u32, arg_two: usize)`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: set an ABI
|
LL | pub unsafe extern "C" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
| ++++++++++
help: or explicitly set the default
|
LL | pub unsafe extern "Rust" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {}
| +++++++++++++

error: attribute #[no_mangle] set on a Rust ABI function
--> $DIR/no_mangle_with_rust_abi.rs:20:1
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
--> $DIR/no_mangle_with_rust_abi.rs:18:1
|
LL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe extern "C" fn rust_abi_fn_four(arg_one: u32, arg_two: usize)`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: set an ABI
|
LL | unsafe extern "C" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
| ++++++++++
help: or explicitly set the default
|
LL | unsafe extern "Rust" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {}
| +++++++++++++

error: attribute #[no_mangle] set on a Rust ABI function
--> $DIR/no_mangle_with_rust_abi.rs:23:1
error: `#[no_mangle]` set on a function with the default (`Rust`) ABI
--> $DIR/no_mangle_with_rust_abi.rs:21:1
|
LL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
LL | | arg_one: u32,
LL | | arg_two: usize,
LL | | ) -> u32 {
| |________^
|
help: try
help: set an ABI
|
LL + extern "C" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
LL + arg_one: u32,
LL + arg_two: usize,
LL ~ ) -> u32 {
LL | extern "C" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
| ++++++++++
help: or explicitly set the default
|
LL | extern "Rust" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines(
| +++++++++++++

error: aborting due to 5 previous errors

0 comments on commit e426ba4

Please sign in to comment.