X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=tests%2Fui%2Fredundant_clone.fixed;h=f5da703cd1dea5e9d524f8c2950ec629525faec2;hb=f6d1f368db9e726fde825dc2525cdec07673b416;hp=614a9bf4d90028074a74bdfa4c3f94f0ac844bce;hpb=249b6cac3e60ac4ac50dcf33460c905e2364630c;p=rust.git diff --git a/tests/ui/redundant_clone.fixed b/tests/ui/redundant_clone.fixed index 614a9bf4d90..f5da703cd1d 100644 --- a/tests/ui/redundant_clone.fixed +++ b/tests/ui/redundant_clone.fixed @@ -1,5 +1,7 @@ // run-rustfix // rustfix-only-machine-applicable + +#![allow(clippy::implicit_clone)] use std::ffi::OsString; use std::path::Path; @@ -46,18 +48,23 @@ fn main() { let _ = Some(String::new()).unwrap_or_else(|| x.0.clone()); // ok; closure borrows `x` with_branch(Alpha, true); + cannot_double_move(Alpha); cannot_move_from_type_with_drop(); borrower_propagation(); + not_consumed(); + issue_5405(); + manually_drop(); + clone_then_move_cloned(); } #[derive(Clone)] struct Alpha; fn with_branch(a: Alpha, b: bool) -> (Alpha, Alpha) { - if b { - (a.clone(), a) - } else { - (Alpha, a) - } + if b { (a.clone(), a) } else { (Alpha, a) } +} + +fn cannot_double_move(a: Alpha) -> (Alpha, Alpha) { + (a.clone(), a) } struct TypeWithDrop { @@ -130,3 +137,72 @@ fn borrower_propagation() { let _f = f.clone(); // ok } } + +fn not_consumed() { + let x = std::path::PathBuf::from("home"); + let y = x.join("matthias"); + // join() creates a new owned PathBuf, does not take a &mut to x variable, thus the .clone() is + // redundant. (It also does not consume the PathBuf) + + println!("x: {:?}, y: {:?}", x, y); + + let mut s = String::new(); + s.clone().push_str("foo"); // OK, removing this `clone()` will change the behavior. + s.push_str("bar"); + assert_eq!(s, "bar"); + + let t = Some(s); + // OK + if let Some(x) = t.clone() { + println!("{}", x); + } + if let Some(x) = t { + println!("{}", x); + } +} + +#[allow(clippy::clone_on_copy)] +fn issue_5405() { + let a: [String; 1] = [String::from("foo")]; + let _b: String = a[0].clone(); + + let c: [usize; 2] = [2, 3]; + let _d: usize = c[1].clone(); +} + +fn manually_drop() { + use std::mem::ManuallyDrop; + use std::sync::Arc; + + let a = ManuallyDrop::new(Arc::new("Hello!".to_owned())); + let _ = a.clone(); // OK + + let p: *const String = Arc::into_raw(ManuallyDrop::into_inner(a)); + unsafe { + Arc::from_raw(p); + Arc::from_raw(p); + } +} + +fn clone_then_move_cloned() { + // issue #5973 + let x = Some(String::new()); + // ok, x is moved while the clone is in use. + assert_eq!(x.clone(), None, "not equal {}", x.unwrap()); + + // issue #5595 + fn foo(_: &Alpha, _: F) {} + let x = Alpha; + // ok, data is moved while the clone is in use. + foo(&x.clone(), move || { + let _ = x; + }); + + // issue #6998 + struct S(String); + impl S { + fn m(&mut self) {} + } + let mut x = S(String::new()); + x.0.clone().chars().for_each(|_| x.m()); +}