#![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>, } 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); impl std::ops::Deref for Wrapper { type Target = T; fn deref(&self) -> &Self::Target { &self.0 } } impl std::ops::DerefMut for Wrapper { 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 }