Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clippy_lints/src/declared_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,6 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[
crate::multiple_unsafe_ops_per_block::MULTIPLE_UNSAFE_OPS_PER_BLOCK_INFO,
crate::mut_key::MUTABLE_KEY_TYPE_INFO,
crate::mut_mut::MUT_MUT_INFO,
crate::mut_reference::UNNECESSARY_MUT_PASSED_INFO,
crate::mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL_INFO,
crate::mutex_atomic::MUTEX_ATOMIC_INFO,
crate::mutex_atomic::MUTEX_INTEGER_INFO,
Expand Down Expand Up @@ -752,6 +751,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[
crate::unnecessary_box_returns::UNNECESSARY_BOX_RETURNS_INFO,
crate::unnecessary_literal_bound::UNNECESSARY_LITERAL_BOUND_INFO,
crate::unnecessary_map_on_constructor::UNNECESSARY_MAP_ON_CONSTRUCTOR_INFO,
crate::unnecessary_mut_passed::UNNECESSARY_MUT_PASSED_INFO,
crate::unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS_INFO,
crate::unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS_INFO,
crate::unnecessary_semicolon::UNNECESSARY_SEMICOLON_INFO,
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,6 @@ mod multiple_bound_locations;
mod multiple_unsafe_ops_per_block;
mod mut_key;
mod mut_mut;
mod mut_reference;
mod mutable_debug_assertion;
mod mutex_atomic;
mod needless_arbitrary_self_type;
Expand Down Expand Up @@ -375,6 +374,7 @@ mod unit_types;
mod unnecessary_box_returns;
mod unnecessary_literal_bound;
mod unnecessary_map_on_constructor;
mod unnecessary_mut_passed;
mod unnecessary_owned_empty_strings;
mod unnecessary_self_imports;
mod unnecessary_semicolon;
Expand Down Expand Up @@ -483,7 +483,7 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co
store.register_late_pass(|_| Box::new(misc::LintPass));
store.register_late_pass(|_| Box::new(eta_reduction::EtaReduction));
store.register_late_pass(|_| Box::new(mut_mut::MutMut));
store.register_late_pass(|_| Box::new(mut_reference::UnnecessaryMutPassed));
store.register_late_pass(|_| Box::new(unnecessary_mut_passed::UnnecessaryMutPassed));
store.register_late_pass(|_| Box::<significant_drop_tightening::SignificantDropTightening<'_>>::default());
store.register_late_pass(|_| Box::new(len_zero::LenZero));
store.register_late_pass(move |_| Box::new(attrs::Attributes::new(conf)));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::sugg::Sugg;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::SpanRangeExt;
use rustc_errors::Applicability;
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability};
use rustc_lint::{LateContext, LateLintPass};
Expand Down Expand Up @@ -87,16 +87,33 @@ fn check_arguments<'tcx>(
if let ty::Ref(_, _, Mutability::Not) | ty::RawPtr(_, Mutability::Not) = parameter.kind()
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, arg) = argument.kind
{
let mut applicability = Applicability::MachineApplicable;
let sugg = Sugg::hir_with_applicability(cx, arg, "_", &mut applicability).addr();
span_lint_and_sugg(
let applicability = Applicability::MachineApplicable;

let span_to_remove = {
let span_until_arg = argument.span.until(arg.span);
if let Some(Some(ref_pos)) = span_until_arg.with_source_text(cx, |src| {
src
// we don't use `strip_prefix` here, because `argument` might be enclosed in parens, in
// which case `&` is no longer the prefix
.find('&')
// just a sanity check, in case some proc-macro messes up the spans
.filter(|ref_pos| src[*ref_pos..].contains("mut"))
}) && let Ok(lo) = u32::try_from(ref_pos + '&'.len_utf8())
{
span_until_arg.split_at(lo).1
} else {
return;
}
};

span_lint_and_then(
cx,
UNNECESSARY_MUT_PASSED,
argument.span,
format!("the {fn_kind} `{name}` doesn't need a mutable reference"),
"remove this `mut`",
sugg.to_string(),
applicability,
|diag| {
diag.span_suggestion_verbose(span_to_remove, "remove this `mut`", String::new(), applicability);
},
);
}
}
Expand Down
77 changes: 0 additions & 77 deletions tests/ui/mut_reference.stderr

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ mod issue11268 {
struct MyStruct;

impl MyStruct {
fn takes_nothing(&self) {}
fn takes_ref(&self, a: &i32) {}
fn takes_refmut(&self, a: &mut i32) {}
fn takes_ref_ref(&self, a: &&i32) {}
Expand Down Expand Up @@ -168,3 +169,22 @@ fn raw_ptrs(my_struct: MyStruct) {
my_struct.takes_raw_mut(&raw mut n);
my_struct.takes_raw_const(a);
}

#[expect(clippy::needless_borrow)]
fn issue15722(mut my_struct: MyStruct) {
(&my_struct).takes_nothing();
//~^ unnecessary_mut_passed
(&my_struct).takes_nothing();

// Only put parens around the argument that used to have it
(&my_struct).takes_ref(&42);
//~^ unnecessary_mut_passed
//~| unnecessary_mut_passed
#[expect(clippy::double_parens)]
(&my_struct).takes_ref((&42));
//~^ unnecessary_mut_passed
//~| unnecessary_mut_passed
#[expect(clippy::double_parens)]
my_struct.takes_ref((&42));
//~^ unnecessary_mut_passed
}
20 changes: 20 additions & 0 deletions tests/ui/mut_reference.rs → tests/ui/unnecessary_mut_passed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ mod issue11268 {
struct MyStruct;

impl MyStruct {
fn takes_nothing(&self) {}
fn takes_ref(&self, a: &i32) {}
fn takes_refmut(&self, a: &mut i32) {}
fn takes_ref_ref(&self, a: &&i32) {}
Expand Down Expand Up @@ -168,3 +169,22 @@ fn raw_ptrs(my_struct: MyStruct) {
my_struct.takes_raw_mut(&raw mut n);
my_struct.takes_raw_const(a);
}

#[expect(clippy::needless_borrow)]
fn issue15722(mut my_struct: MyStruct) {
(&mut my_struct).takes_nothing();
//~^ unnecessary_mut_passed
(&my_struct).takes_nothing();

// Only put parens around the argument that used to have it
(&mut my_struct).takes_ref(&mut 42);
//~^ unnecessary_mut_passed
//~| unnecessary_mut_passed
#[expect(clippy::double_parens)]
(&mut my_struct).takes_ref((&mut 42));
//~^ unnecessary_mut_passed
//~| unnecessary_mut_passed
#[expect(clippy::double_parens)]
my_struct.takes_ref((&mut 42));
//~^ unnecessary_mut_passed
}
Loading