Skip to content

Commit 1e3b24d

Browse files
committed
Make manual_swap autofixable
1 parent bd39a60 commit 1e3b24d

File tree

4 files changed

+100
-13
lines changed

4 files changed

+100
-13
lines changed

clippy_lints/src/swap.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::utils::sugg::Sugg;
22
use crate::utils::{
3-
differing_macro_contexts, is_type_diagnostic_item, match_type, paths, snippet, span_lint_and_then, walk_ptrs_ty,
4-
SpanlessEq,
3+
differing_macro_contexts, is_type_diagnostic_item, match_type, paths, snippet_with_applicability,
4+
span_lint_and_then, walk_ptrs_ty, SpanlessEq,
55
};
66
use if_chain::if_chain;
77
use matches::matches;
@@ -105,8 +105,9 @@ fn check_manual_swap(cx: &LateContext<'_, '_>, block: &Block) {
105105
}
106106
}
107107

108-
let slice = check_for_slice(cx, lhs1, lhs2);
108+
let mut applicability = Applicability::MachineApplicable;
109109

110+
let slice = check_for_slice(cx, lhs1, lhs2);
110111
let (replace, what, sugg) = if let Slice::NotSwappable = slice {
111112
return;
112113
} else if let Slice::Swappable(slice, idx1, idx2) = slice {
@@ -117,8 +118,8 @@ fn check_manual_swap(cx: &LateContext<'_, '_>, block: &Block) {
117118
format!(
118119
"{}.swap({}, {})",
119120
slice.maybe_par(),
120-
snippet(cx, idx1.span, ".."),
121-
snippet(cx, idx2.span, ".."),
121+
snippet_with_applicability(cx, idx1.span, "..", &mut applicability),
122+
snippet_with_applicability(cx, idx2.span, "..", &mut applicability),
122123
),
123124
)
124125
} else {
@@ -147,7 +148,7 @@ fn check_manual_swap(cx: &LateContext<'_, '_>, block: &Block) {
147148
span,
148149
"try",
149150
sugg,
150-
Applicability::Unspecified,
151+
applicability,
151152
);
152153

153154
if replace {

tests/ui/swap.fixed

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// run-rustfix
2+
3+
#![warn(clippy::all)]
4+
#![allow(
5+
clippy::blacklisted_name,
6+
clippy::no_effect,
7+
clippy::redundant_clone,
8+
redundant_semicolon,
9+
unused_assignments
10+
)]
11+
12+
struct Foo(u32);
13+
14+
#[derive(Clone)]
15+
struct Bar {
16+
a: u32,
17+
b: u32,
18+
}
19+
20+
fn field() {
21+
let mut bar = Bar { a: 1, b: 2 };
22+
23+
let temp = bar.a;
24+
bar.a = bar.b;
25+
bar.b = temp;
26+
27+
let mut baz = vec![bar.clone(), bar.clone()];
28+
let temp = baz[0].a;
29+
baz[0].a = baz[1].a;
30+
baz[1].a = temp;
31+
}
32+
33+
fn array() {
34+
let mut foo = [1, 2];
35+
foo.swap(0, 1);
36+
37+
foo.swap(0, 1);
38+
}
39+
40+
fn slice() {
41+
let foo = &mut [1, 2];
42+
foo.swap(0, 1);
43+
44+
foo.swap(0, 1);
45+
}
46+
47+
fn unswappable_slice() {
48+
let foo = &mut [vec![1, 2], vec![3, 4]];
49+
let temp = foo[0][1];
50+
foo[0][1] = foo[1][0];
51+
foo[1][0] = temp;
52+
53+
// swap(foo[0][1], foo[1][0]) would fail
54+
}
55+
56+
fn vec() {
57+
let mut foo = vec![1, 2];
58+
foo.swap(0, 1);
59+
60+
foo.swap(0, 1);
61+
}
62+
63+
#[rustfmt::skip]
64+
fn main() {
65+
field();
66+
array();
67+
slice();
68+
unswappable_slice();
69+
vec();
70+
71+
let mut a = 42;
72+
let mut b = 1337;
73+
74+
std::mem::swap(&mut a, &mut b);
75+
76+
; std::mem::swap(&mut a, &mut b);
77+
78+
let mut c = Foo(42);
79+
80+
std::mem::swap(&mut c.0, &mut a);
81+
82+
; std::mem::swap(&mut c.0, &mut a);
83+
}

tests/ui/swap.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// run-rustfix
2+
13
#![warn(clippy::all)]
24
#![allow(
35
clippy::blacklisted_name,
@@ -69,6 +71,7 @@ fn main() {
6971
field();
7072
array();
7173
slice();
74+
unswappable_slice();
7275
vec();
7376

7477
let mut a = 42;

tests/ui/swap.stderr

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: this looks like you are swapping elements of `foo` manually
2-
--> $DIR/swap.rs:33:5
2+
--> $DIR/swap.rs:35:5
33
|
44
LL | / let temp = foo[0];
55
LL | | foo[0] = foo[1];
@@ -9,23 +9,23 @@ LL | | foo[1] = temp;
99
= note: `-D clippy::manual-swap` implied by `-D warnings`
1010

1111
error: this looks like you are swapping elements of `foo` manually
12-
--> $DIR/swap.rs:42:5
12+
--> $DIR/swap.rs:44:5
1313
|
1414
LL | / let temp = foo[0];
1515
LL | | foo[0] = foo[1];
1616
LL | | foo[1] = temp;
1717
| |_________________^ help: try: `foo.swap(0, 1)`
1818

1919
error: this looks like you are swapping elements of `foo` manually
20-
--> $DIR/swap.rs:60:5
20+
--> $DIR/swap.rs:62:5
2121
|
2222
LL | / let temp = foo[0];
2323
LL | | foo[0] = foo[1];
2424
LL | | foo[1] = temp;
2525
| |_________________^ help: try: `foo.swap(0, 1)`
2626

2727
error: this looks like you are swapping `a` and `b` manually
28-
--> $DIR/swap.rs:80:7
28+
--> $DIR/swap.rs:83:7
2929
|
3030
LL | ; let t = a;
3131
| _______^
@@ -36,7 +36,7 @@ LL | | b = t;
3636
= note: or maybe you should use `std::mem::replace`?
3737

3838
error: this looks like you are swapping `c.0` and `a` manually
39-
--> $DIR/swap.rs:89:7
39+
--> $DIR/swap.rs:92:7
4040
|
4141
LL | ; let t = c.0;
4242
| _______^
@@ -47,7 +47,7 @@ LL | | a = t;
4747
= note: or maybe you should use `std::mem::replace`?
4848

4949
error: this looks like you are trying to swap `a` and `b`
50-
--> $DIR/swap.rs:77:5
50+
--> $DIR/swap.rs:80:5
5151
|
5252
LL | / a = b;
5353
LL | | b = a;
@@ -57,7 +57,7 @@ LL | | b = a;
5757
= note: or maybe you should use `std::mem::replace`?
5858

5959
error: this looks like you are trying to swap `c.0` and `a`
60-
--> $DIR/swap.rs:86:5
60+
--> $DIR/swap.rs:89:5
6161
|
6262
LL | / c.0 = a;
6363
LL | | a = c.0;

0 commit comments

Comments
 (0)