diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs index 3d2285efbe18..f3e42b1c58f8 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,18 +269,27 @@ 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, NEEDLESS_PASS_BY_REF_MUT, cx.tcx.local_def_id_to_hir_id(*fn_def_id), sp, - "this argument is a mutable reference, but not used mutably", + "this parameter is a mutable reference but is 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.fixed b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.fixed index 40556ca5410f..962a4e00d86e 100644 --- a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.fixed +++ b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.fixed @@ -3,7 +3,7 @@ // Should warn pub fn pub_foo(s: &Vec, b: &u32, x: &mut u32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably + //~^ needless_pass_by_ref_mut *x += *b + s.len() as u32; } diff --git a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs index bbc63ceb15a3..5f584c6704f2 100644 --- a/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs +++ b/tests/ui-toml/needless_pass_by_ref_mut/needless_pass_by_ref_mut.rs @@ -3,7 +3,7 @@ // Should warn pub fn pub_foo(s: &mut Vec, b: &u32, x: &mut u32) { - //~^ ERROR: this argument is a mutable reference, but not used mutably + //~^ needless_pass_by_ref_mut *x += *b + s.len() as u32; } 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..57137ab08d1e 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 @@ -1,8 +1,10 @@ -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is 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..c427f4c3e42c 100644 --- a/tests/ui/needless_pass_by_ref_mut.stderr +++ b/tests/ui/needless_pass_by_ref_mut.stderr @@ -1,213 +1,281 @@ -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is 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)]` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is 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 -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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 +error: this parameter is a mutable reference but is 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..aa5c412adb4d 100644 --- a/tests/ui/needless_pass_by_ref_mut2.stderr +++ b/tests/ui/needless_pass_by_ref_mut2.stderr @@ -1,17 +1,29 @@ -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is 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)]` -error: this argument is a mutable reference, but not used mutably +error: this parameter is a mutable reference but is 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 parameter is a mutable reference but is 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