Skip to content

Commit 8d369a2

Browse files
committed
unnecessary_mut_passed: add structured suggestion
1 parent 8779679 commit 8d369a2

File tree

4 files changed

+75
-10
lines changed

4 files changed

+75
-10
lines changed

clippy_lints/src/mut_reference.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
use clippy_utils::diagnostics::span_lint;
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::sugg::Sugg;
3+
use rustc_errors::Applicability;
24
use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability};
35
use rustc_lint::{LateContext, LateLintPass};
46
use rustc_middle::ty::{self, Ty};
@@ -83,13 +85,18 @@ fn check_arguments<'tcx>(
8385
let parameters = type_definition.fn_sig(cx.tcx).skip_binder().inputs();
8486
for (argument, parameter) in iter::zip(arguments, parameters) {
8587
if let ty::Ref(_, _, Mutability::Not) | ty::RawPtr(_, Mutability::Not) = parameter.kind()
86-
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, _) = argument.kind
88+
&& let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, arg) = argument.kind
8789
{
88-
span_lint(
90+
let mut applicability = Applicability::MachineApplicable;
91+
let sugg = Sugg::hir_with_applicability(cx, arg, "_", &mut applicability).addr();
92+
span_lint_and_sugg(
8993
cx,
9094
UNNECESSARY_MUT_PASSED,
9195
argument.span,
9296
format!("the {fn_kind} `{name}` doesn't need a mutable reference"),
97+
"remove the `mut`",
98+
sugg.to_string(),
99+
applicability,
93100
);
94101
}
95102
}

tests/ui/mut_reference.fixed

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#![allow(unused_variables, dead_code)]
2+
fn takes_an_immutable_reference(a: &i32) {}
3+
fn takes_a_mutable_reference(a: &mut i32) {}
4+
5+
mod issue11268 {
6+
macro_rules! x {
7+
($f:expr) => {
8+
$f(&mut 1);
9+
};
10+
}
11+
12+
fn f() {
13+
x!(super::takes_an_immutable_reference);
14+
x!(super::takes_a_mutable_reference);
15+
}
16+
}
17+
18+
struct MyStruct;
19+
20+
impl MyStruct {
21+
fn takes_an_immutable_reference(&self, a: &i32) {}
22+
23+
fn takes_a_mutable_reference(&self, a: &mut i32) {}
24+
}
25+
26+
#[warn(clippy::unnecessary_mut_passed)]
27+
fn main() {
28+
// Functions
29+
takes_an_immutable_reference(&42);
30+
//~^ unnecessary_mut_passed
31+
32+
let as_ptr: fn(&i32) = takes_an_immutable_reference;
33+
as_ptr(&42);
34+
//~^ unnecessary_mut_passed
35+
36+
// Methods
37+
let my_struct = MyStruct;
38+
my_struct.takes_an_immutable_reference(&42);
39+
//~^ unnecessary_mut_passed
40+
41+
// No error
42+
43+
// Functions
44+
takes_an_immutable_reference(&42);
45+
let as_ptr: fn(&i32) = takes_an_immutable_reference;
46+
as_ptr(&42);
47+
48+
takes_a_mutable_reference(&mut 42);
49+
let as_ptr: fn(&mut i32) = takes_a_mutable_reference;
50+
as_ptr(&mut 42);
51+
52+
let a = &mut 42;
53+
takes_an_immutable_reference(a);
54+
55+
// Methods
56+
my_struct.takes_an_immutable_reference(&42);
57+
my_struct.takes_a_mutable_reference(&mut 42);
58+
my_struct.takes_an_immutable_reference(a);
59+
}

tests/ui/mut_reference.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#![allow(unused_variables, dead_code)]
2-
//@no-rustfix
32
fn takes_an_immutable_reference(a: &i32) {}
43
fn takes_a_mutable_reference(a: &mut i32) {}
54

tests/ui/mut_reference.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
error: the function `takes_an_immutable_reference` doesn't need a mutable reference
2-
--> tests/ui/mut_reference.rs:30:34
2+
--> tests/ui/mut_reference.rs:29:34
33
|
44
LL | takes_an_immutable_reference(&mut 42);
5-
| ^^^^^^^
5+
| ^^^^^^^ help: remove the `mut`: `&42`
66
|
77
= note: `-D clippy::unnecessary-mut-passed` implied by `-D warnings`
88
= help: to override `-D warnings` add `#[allow(clippy::unnecessary_mut_passed)]`
99

1010
error: the function `as_ptr` doesn't need a mutable reference
11-
--> tests/ui/mut_reference.rs:34:12
11+
--> tests/ui/mut_reference.rs:33:12
1212
|
1313
LL | as_ptr(&mut 42);
14-
| ^^^^^^^
14+
| ^^^^^^^ help: remove the `mut`: `&42`
1515

1616
error: the method `takes_an_immutable_reference` doesn't need a mutable reference
17-
--> tests/ui/mut_reference.rs:39:44
17+
--> tests/ui/mut_reference.rs:38:44
1818
|
1919
LL | my_struct.takes_an_immutable_reference(&mut 42);
20-
| ^^^^^^^
20+
| ^^^^^^^ help: remove the `mut`: `&42`
2121

2222
error: aborting due to 3 previous errors
2323

0 commit comments

Comments
 (0)