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