diff --git a/clippy_lints/src/mut_mut.rs b/clippy_lints/src/mut_mut.rs index c8b4ad3f7722..0feed460d2ed 100644 --- a/clippy_lints/src/mut_mut.rs +++ b/clippy_lints/src/mut_mut.rs @@ -1,4 +1,4 @@ -use clippy_utils::diagnostics::{span_lint, span_lint_hir, span_lint_hir_and_then}; +use clippy_utils::diagnostics::{span_lint, span_lint_hir_and_then}; use clippy_utils::higher; use clippy_utils::sugg::Sugg; use rustc_errors::Applicability; @@ -72,12 +72,17 @@ impl<'tcx> intravisit::Visitor<'tcx> for MutVisitor<'_, 'tcx> { intravisit::walk_expr(self, body); } else if let hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e) = expr.kind { if let hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, _) = e.kind { - span_lint_hir( + let mut applicability = Applicability::MaybeIncorrect; + let sugg = Sugg::hir_with_applicability(self.cx, e, "..", &mut applicability); + span_lint_hir_and_then( self.cx, MUT_MUT, expr.hir_id, expr.span, - "generally you want to avoid `&mut &mut _` if possible", + "an expression of form `&mut &mut _`", + |diag| { + diag.span_suggestion(expr.span, "remove the extra `&mut`", sugg, applicability); + }, ); } else if let ty::Ref(_, ty, hir::Mutability::Mut) = self.cx.typeck_results().expr_ty(e).kind() && ty.peel_refs().is_sized(self.cx.tcx, self.cx.typing_env()) diff --git a/tests/ui/mut_mut.fixed b/tests/ui/mut_mut.fixed index cbce826b6e85..c6b318d76510 100644 --- a/tests/ui/mut_mut.fixed +++ b/tests/ui/mut_mut.fixed @@ -29,7 +29,7 @@ macro_rules! mut_ptr { #[allow(unused_mut, unused_variables)] #[inline_macros] fn main() { - let mut x = &mut &mut 1u32; + let mut x = &mut 1u32; //~^ mut_mut { let mut y = &mut *x; @@ -37,19 +37,19 @@ fn main() { } { - let y: &mut &mut u32 = &mut &mut 2; + let y: &mut &mut u32 = &mut 2; //~^ mut_mut //~| mut_mut } { - let y: &mut &mut &mut u32 = &mut &mut &mut 2; + let y: &mut &mut &mut u32 = &mut &mut 2; //~^ mut_mut //~| mut_mut //~| mut_mut } - let mut z = inline!(&mut $(&mut 3u32)); + let mut z = inline!(&mut 3u32mut $(&mut 3u32)); //~^ mut_mut } diff --git a/tests/ui/mut_mut.stderr b/tests/ui/mut_mut.stderr index aa4731e8fe04..f21de359e64f 100644 --- a/tests/ui/mut_mut.stderr +++ b/tests/ui/mut_mut.stderr @@ -7,17 +7,17 @@ LL | fn fun(x: &mut &mut u32) { = note: `-D clippy::mut-mut` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::mut_mut)]` -error: generally you want to avoid `&mut &mut _` if possible +error: an expression of form `&mut &mut _` --> tests/ui/mut_mut.rs:32:17 | LL | let mut x = &mut &mut 1u32; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ help: remove the extra `&mut`: `&mut 1u32` -error: generally you want to avoid `&mut &mut _` if possible +error: an expression of form `&mut &mut _` --> tests/ui/mut_mut.rs:52:25 | LL | let mut z = inline!(&mut $(&mut 3u32)); - | ^ + | ^ help: remove the extra `&mut`: `&mut 3u32` | = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -27,11 +27,11 @@ error: this expression mutably borrows a mutable reference LL | let mut y = &mut x; | ^^^^^^ help: reborrow instead: `&mut *x` -error: generally you want to avoid `&mut &mut _` if possible +error: an expression of form `&mut &mut _` --> tests/ui/mut_mut.rs:40:32 | LL | let y: &mut &mut u32 = &mut &mut 2; - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ help: remove the extra `&mut`: `&mut 2` error: generally you want to avoid `&mut &mut _` if possible --> tests/ui/mut_mut.rs:40:16 @@ -39,11 +39,11 @@ error: generally you want to avoid `&mut &mut _` if possible LL | let y: &mut &mut u32 = &mut &mut 2; | ^^^^^^^^^^^^^ -error: generally you want to avoid `&mut &mut _` if possible +error: an expression of form `&mut &mut _` --> tests/ui/mut_mut.rs:46:37 | LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ help: remove the extra `&mut`: `&mut &mut 2` error: generally you want to avoid `&mut &mut _` if possible --> tests/ui/mut_mut.rs:46:16 diff --git a/tests/ui/mut_mut_unfixable.stderr b/tests/ui/mut_mut_unfixable.stderr index 835b272258d3..129e5b24387e 100644 --- a/tests/ui/mut_mut_unfixable.stderr +++ b/tests/ui/mut_mut_unfixable.stderr @@ -7,11 +7,11 @@ LL | fn fun(x: &mut &mut u32) -> bool { = note: `-D clippy::mut-mut` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::mut_mut)]` -error: generally you want to avoid `&mut &mut _` if possible +error: an expression of form `&mut &mut _` --> tests/ui/mut_mut_unfixable.rs:15:17 | LL | let mut x = &mut &mut 1u32; - | ^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^ help: remove the extra `&mut`: `&mut 1u32` error: this expression mutably borrows a mutable reference --> tests/ui/mut_mut_unfixable.rs:18:21 @@ -19,17 +19,17 @@ error: this expression mutably borrows a mutable reference LL | let mut y = &mut x; | ^^^^^^ help: reborrow instead: `&mut *x` -error: generally you want to avoid `&mut &mut _` if possible +error: an expression of form `&mut &mut _` --> tests/ui/mut_mut_unfixable.rs:24:17 | LL | let y = &mut &mut 2; - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ help: remove the extra `&mut`: `&mut 2` -error: generally you want to avoid `&mut &mut _` if possible +error: an expression of form `&mut &mut _` --> tests/ui/mut_mut_unfixable.rs:30:17 | LL | let y = &mut &mut &mut 2; - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ help: remove the extra `&mut`: `&mut &mut 2` error: aborting due to 5 previous errors