| #![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 | |
| } |