1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
#![warn(clippy::swap_with_temporary)]
use std::mem::swap;
fn func() -> String {
String::from("func")
}
fn func_returning_refmut(s: &mut String) -> &mut String {
s
}
fn main() {
let mut x = String::from("x");
let mut y = String::from("y");
let mut zz = String::from("zz");
let z = &mut zz;
// No lint
swap(&mut x, &mut y);
y = func();
//~^ ERROR: swapping with a temporary value is inefficient
x = func();
//~^ ERROR: swapping with a temporary value is inefficient
*z = func();
//~^ ERROR: swapping with a temporary value is inefficient
// No lint
swap(z, func_returning_refmut(&mut x));
swap(&mut y, z);
*z = func();
//~^ ERROR: swapping with a temporary value is inefficient
macro_rules! mac {
(refmut $x:expr) => {
&mut $x
};
(funcall $f:ident) => {
$f()
};
(wholeexpr) => {
swap(&mut 42, &mut 0)
};
(ident $v:ident) => {
$v
};
}
*z = mac!(funcall func);
//~^ ERROR: swapping with a temporary value is inefficient
*mac!(ident z) = mac!(funcall func);
//~^ ERROR: swapping with a temporary value is inefficient
*mac!(ident z) = mac!(funcall func);
//~^ ERROR: swapping with a temporary value is inefficient
*mac!(refmut y) = func();
//~^ ERROR: swapping with a temporary value is inefficient
// No lint if it comes from a macro as it may depend on the arguments
mac!(wholeexpr);
}
struct S {
t: String,
}
fn dont_lint_those(s: &mut S, v: &mut [String], w: Option<&mut String>) {
swap(&mut s.t, &mut v[0]);
swap(&mut s.t, v.get_mut(0).unwrap());
swap(w.unwrap(), &mut s.t);
}
fn issue15166() {
use std::sync::Mutex;
struct A {
thing: Mutex<Vec<u8>>,
}
impl A {
fn a(&self) {
let mut new_vec = vec![42];
// Do not lint here, as neither `new_vec` nor the result of `.lock().unwrap()` are temporaries
swap(&mut new_vec, &mut self.thing.lock().unwrap());
for v in new_vec {
// Do something with v
}
// Here `vec![42]` is temporary though, and a proper dereference will have to be used in the fix
*self.thing.lock().unwrap() = vec![42];
//~^ ERROR: swapping with a temporary value is inefficient
}
}
}
fn multiple_deref() {
let mut v1 = &mut &mut &mut vec![42];
***v1 = vec![];
//~^ ERROR: swapping with a temporary value is inefficient
struct Wrapper<T: ?Sized>(T);
impl<T: ?Sized> std::ops::Deref for Wrapper<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T: ?Sized> std::ops::DerefMut for Wrapper<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
use std::sync::Mutex;
let mut v1 = Mutex::new(Wrapper(Wrapper(vec![42])));
***v1.lock().unwrap() = vec![];
//~^ ERROR: swapping with a temporary value is inefficient
}
|