diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs index 3d2285efbe18..904ff538ba36 100644 --- a/clippy_lints/src/needless_pass_by_ref_mut.rs +++ b/clippy_lints/src/needless_pass_by_ref_mut.rs @@ -1,7 +1,7 @@ use super::needless_pass_by_value::requires_exact_signature; use clippy_config::Conf; use clippy_utils::diagnostics::span_lint_hir_and_then; -use clippy_utils::source::snippet; +use clippy_utils::source::HasSession as _; use clippy_utils::visitors::for_each_expr; use clippy_utils::{inherits_cfg, is_from_proc_macro, is_self}; use core::ops::ControlFlow; @@ -18,9 +18,9 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{self, Ty, TyCtxt, UpvarId, UpvarPath}; use rustc_session::impl_lint_pass; -use rustc_span::Span; use rustc_span::def_id::LocalDefId; use rustc_span::symbol::kw; +use rustc_span::{BytePos, Span}; declare_clippy_lint! { /// ### What it does @@ -269,6 +269,15 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { // If the argument is never used mutably, we emit the warning. let sp = input.span; if let rustc_hir::TyKind::Ref(_, inner_ty) = input.kind { + let Some(after_mut_span) = cx.sess().source_map().span_extend_to_prev_str( + inner_ty.ty.span.shrink_to_lo(), + "mut", + true, + true, + ) else { + return; + }; + let mut_span = after_mut_span.with_lo(after_mut_span.lo() - BytePos(3)); let is_cfged = is_cfged.get_or_insert_with(|| inherits_cfg(cx.tcx, *fn_def_id)); span_lint_hir_and_then( cx, @@ -278,9 +287,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> { "this argument is a mutable reference, but not used mutably", |diag| { diag.span_suggestion( - sp, - "consider changing to".to_string(), - format!("&{}", snippet(cx, cx.tcx.hir_span(inner_ty.ty.hir_id), "_"),), + mut_span, + "consider removing this `mut`", + "", Applicability::Unspecified, ); if cx.effective_visibilities.is_exported(*fn_def_id) { diff --git a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr index c10607bf4bab..f79b20ec69fc 100644 --- a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr +++ b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.stderr @@ -2,7 +2,9 @@ error: this argument is a mutable reference, but not used mutably --> tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs:5:19 | LL | pub fn pub_foo(s: &mut Vec, b: &u32, x: &mut u32) { - | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + | ^----^^^^^^^^ + | | + | help: consider removing this `mut` | = warning: changing this function will impact semver compatibility = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` diff --git a/tests/ui/needless_pass_by_ref_mut.stderr b/tests/ui/needless_pass_by_ref_mut.stderr index 94d98f0e9b12..90d99b9f0cf6 100644 --- a/tests/ui/needless_pass_by_ref_mut.stderr +++ b/tests/ui/needless_pass_by_ref_mut.stderr @@ -2,7 +2,9 @@ error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:12:11 | LL | fn foo(s: &mut Vec, b: &u32, x: &mut u32) { - | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + | ^----^^^^^^^^ + | | + | help: consider removing this `mut` | = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]` @@ -11,79 +13,105 @@ error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:38:12 | LL | fn foo6(s: &mut Vec) { - | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + | ^----^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:49:12 | LL | fn bar(&mut self) {} - | ^^^^^^^^^ help: consider changing to: `&self` + | ^----^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:52:29 | LL | fn mushroom(&self, vec: &mut Vec) -> usize { - | ^^^^^^^^^^^^^ help: consider changing to: `&Vec` + | ^----^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:130:16 | LL | async fn a1(x: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:135:16 | LL | async fn a2(x: &mut i32, y: String) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:140:16 | LL | async fn a3(x: &mut i32, y: String, z: String) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:145:16 | LL | async fn a4(x: &mut i32, y: i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:150:24 | LL | async fn a5(x: i32, y: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:155:24 | LL | async fn a6(x: i32, y: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:160:32 | LL | async fn a7(x: i32, y: i32, z: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:165:24 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:165:45 | LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:201:16 | LL | fn cfg_warn(s: &mut u32) {} - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` | = note: this is cfg-gated and may require further changes @@ -91,7 +119,9 @@ error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:206:20 | LL | fn cfg_warn(s: &mut u32) {} - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` | = note: this is cfg-gated and may require further changes @@ -99,115 +129,153 @@ error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:219:39 | LL | async fn inner_async2(x: &mut i32, y: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:228:26 | LL | async fn inner_async3(x: &mut i32, y: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:248:30 | LL | async fn call_in_closure1(n: &mut str) { - | ^^^^^^^^ help: consider changing to: `&str` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:268:16 | LL | fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize { - | ^^^^^^^^^^ help: consider changing to: `&usize` + | ^----^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:280:22 | LL | async fn closure4(n: &mut usize) { - | ^^^^^^^^^^ help: consider changing to: `&usize` + | ^----^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:335:12 | LL | fn bar(&mut self) {} - | ^^^^^^^^^ help: consider changing to: `&self` + | ^----^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:338:18 | LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { - | ^^^^^^^^^ help: consider changing to: `&self` + | ^----^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:338:45 | LL | async fn foo(&mut self, u: &mut i32, v: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:347:46 | LL | async fn foo2(&mut self, u: &mut i32, v: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:364:18 | LL | fn _empty_tup(x: &mut (())) {} - | ^^^^^^^^^ help: consider changing to: `&()` + | ^^----^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:366:19 | LL | fn _single_tup(x: &mut ((i32,))) {} - | ^^^^^^^^^^^^^ help: consider changing to: `&(i32,)` + | ^^----^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:368:18 | LL | fn _multi_tup(x: &mut ((i32, u32))) {} - | ^^^^^^^^^^^^^^^^^ help: consider changing to: `&(i32, u32)` + | ^^----^^^^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:370:11 | LL | fn _fn(x: &mut (fn())) {} - | ^^^^^^^^^^^ help: consider changing to: `&fn()` + | ^^----^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:373:23 | LL | fn _extern_rust_fn(x: &mut extern "Rust" fn()) {} - | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "Rust" fn()` + | ^----^^^^^^^^^^^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:375:20 | LL | fn _extern_c_fn(x: &mut extern "C" fn()) {} - | ^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "C" fn()` + | ^----^^^^^^^^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:377:18 | LL | fn _unsafe_fn(x: &mut unsafe fn()) {} - | ^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe fn()` + | ^----^^^^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:379:25 | LL | fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn()` + | ^----^^^^^^^^^^^^^^^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:381:20 | LL | fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn(i32)` + | ^----^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | help: consider removing this `mut` error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut.rs:383:20 | LL | fn _fn_with_ret(x: &mut unsafe extern "C" fn() -> (i32)) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn() -> (i32)` + | ^----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | help: consider removing this `mut` error: aborting due to 34 previous errors diff --git a/tests/ui/needless_pass_by_ref_mut2.fixed b/tests/ui/needless_pass_by_ref_mut2.fixed index 0e2ac0202364..c462f1cc8d87 100644 --- a/tests/ui/needless_pass_by_ref_mut2.fixed +++ b/tests/ui/needless_pass_by_ref_mut2.fixed @@ -24,3 +24,9 @@ async fn inner_async4(u: &mut i32, v: &u32) { } fn main() {} + +//~v needless_pass_by_ref_mut +fn issue16267<'a>(msg: &str, slice: &'a [i32]) -> &'a [i32] { + println!("{msg}"); + &slice[0..5] +} diff --git a/tests/ui/needless_pass_by_ref_mut2.rs b/tests/ui/needless_pass_by_ref_mut2.rs index 9201d9a27298..b00f294c57f0 100644 --- a/tests/ui/needless_pass_by_ref_mut2.rs +++ b/tests/ui/needless_pass_by_ref_mut2.rs @@ -24,3 +24,9 @@ async fn inner_async4(u: &mut i32, v: &mut u32) { } fn main() {} + +//~v needless_pass_by_ref_mut +fn issue16267<'a>(msg: &str, slice: &'a mut [i32]) -> &'a [i32] { + println!("{msg}"); + &slice[0..5] +} diff --git a/tests/ui/needless_pass_by_ref_mut2.stderr b/tests/ui/needless_pass_by_ref_mut2.stderr index 9876a6b50718..6af8a4d4a2b5 100644 --- a/tests/ui/needless_pass_by_ref_mut2.stderr +++ b/tests/ui/needless_pass_by_ref_mut2.stderr @@ -2,7 +2,9 @@ error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut2.rs:8:26 | LL | async fn inner_async3(x: &mut i32, y: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&i32` + | ^----^^^ + | | + | help: consider removing this `mut` | = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]` @@ -11,7 +13,17 @@ error: this argument is a mutable reference, but not used mutably --> tests/ui/needless_pass_by_ref_mut2.rs:17:39 | LL | async fn inner_async4(u: &mut i32, v: &mut u32) { - | ^^^^^^^^ help: consider changing to: `&u32` + | ^----^^^ + | | + | help: consider removing this `mut` -error: aborting due to 2 previous errors +error: this argument is a mutable reference, but not used mutably + --> tests/ui/needless_pass_by_ref_mut2.rs:29:37 + | +LL | fn issue16267<'a>(msg: &str, slice: &'a mut [i32]) -> &'a [i32] { + | ^^^^----^^^^^ + | | + | help: consider removing this `mut` + +error: aborting due to 3 previous errors