about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/redundant_clone.rs6
-rw-r--r--clippy_lints/src/utils/paths.rs1
-rw-r--r--tests/ui/redundant_clone.fixed15
-rw-r--r--tests/ui/redundant_clone.rs15
-rw-r--r--tests/ui/redundant_clone.stderr20
5 files changed, 47 insertions, 10 deletions
diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs
index fda7480194d..7932be0d4b1 100644
--- a/clippy_lints/src/redundant_clone.rs
+++ b/clippy_lints/src/redundant_clone.rs
@@ -124,6 +124,12 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
                 continue;
             }
 
+            if let ty::Adt(ref def, _) = arg_ty.kind {
+                if match_def_path(cx, def.did, &paths::MEM_MANUALLY_DROP) {
+                    continue;
+                }
+            }
+
             // `{ cloned = &arg; clone(move cloned); }` or `{ cloned = &arg; to_path_buf(cloned); }`
             let (cloned, cannot_move_out) = unwrap_or_continue!(find_stmt_assigns_to(cx, mir, arg, from_borrow, bb));
 
diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs
index 4c3462802e9..a515ee29c82 100644
--- a/clippy_lints/src/utils/paths.rs
+++ b/clippy_lints/src/utils/paths.rs
@@ -59,6 +59,7 @@ pub const LINKED_LIST: [&str; 4] = ["alloc", "collections", "linked_list", "Link
 pub const LINT: [&str; 3] = ["rustc_session", "lint", "Lint"];
 pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"];
 pub const MEM_FORGET: [&str; 3] = ["core", "mem", "forget"];
+pub const MEM_MANUALLY_DROP: [&str; 4] = ["core", "mem", "manually_drop", "ManuallyDrop"];
 pub const MEM_MAYBEUNINIT: [&str; 4] = ["core", "mem", "maybe_uninit", "MaybeUninit"];
 pub const MEM_MAYBEUNINIT_UNINIT: [&str; 5] = ["core", "mem", "maybe_uninit", "MaybeUninit", "uninit"];
 pub const MEM_REPLACE: [&str; 3] = ["core", "mem", "replace"];
diff --git a/tests/ui/redundant_clone.fixed b/tests/ui/redundant_clone.fixed
index 764c10a6d39..cdeefda4c23 100644
--- a/tests/ui/redundant_clone.fixed
+++ b/tests/ui/redundant_clone.fixed
@@ -52,6 +52,7 @@ fn main() {
     borrower_propagation();
     not_consumed();
     issue_5405();
+    manually_drop();
 }
 
 #[derive(Clone)]
@@ -170,3 +171,17 @@ fn issue_5405() {
     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);
+    }
+}
diff --git a/tests/ui/redundant_clone.rs b/tests/ui/redundant_clone.rs
index 839747b131d..acb7ffb305f 100644
--- a/tests/ui/redundant_clone.rs
+++ b/tests/ui/redundant_clone.rs
@@ -52,6 +52,7 @@ fn main() {
     borrower_propagation();
     not_consumed();
     issue_5405();
+    manually_drop();
 }
 
 #[derive(Clone)]
@@ -170,3 +171,17 @@ fn issue_5405() {
     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);
+    }
+}
diff --git a/tests/ui/redundant_clone.stderr b/tests/ui/redundant_clone.stderr
index eced198283c..89b39254299 100644
--- a/tests/ui/redundant_clone.stderr
+++ b/tests/ui/redundant_clone.stderr
@@ -108,61 +108,61 @@ LL |     let _t = tup.0.clone();
    |              ^^^^^
 
 error: redundant clone
-  --> $DIR/redundant_clone.rs:61:22
+  --> $DIR/redundant_clone.rs:62:22
    |
 LL |         (a.clone(), a.clone())
    |                      ^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> $DIR/redundant_clone.rs:61:21
+  --> $DIR/redundant_clone.rs:62:21
    |
 LL |         (a.clone(), a.clone())
    |                     ^
 
 error: redundant clone
-  --> $DIR/redundant_clone.rs:121:15
+  --> $DIR/redundant_clone.rs:122:15
    |
 LL |     let _s = s.clone();
    |               ^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> $DIR/redundant_clone.rs:121:14
+  --> $DIR/redundant_clone.rs:122:14
    |
 LL |     let _s = s.clone();
    |              ^
 
 error: redundant clone
-  --> $DIR/redundant_clone.rs:122:15
+  --> $DIR/redundant_clone.rs:123:15
    |
 LL |     let _t = t.clone();
    |               ^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> $DIR/redundant_clone.rs:122:14
+  --> $DIR/redundant_clone.rs:123:14
    |
 LL |     let _t = t.clone();
    |              ^
 
 error: redundant clone
-  --> $DIR/redundant_clone.rs:132:19
+  --> $DIR/redundant_clone.rs:133:19
    |
 LL |         let _f = f.clone();
    |                   ^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> $DIR/redundant_clone.rs:132:18
+  --> $DIR/redundant_clone.rs:133:18
    |
 LL |         let _f = f.clone();
    |                  ^
 
 error: redundant clone
-  --> $DIR/redundant_clone.rs:144:14
+  --> $DIR/redundant_clone.rs:145:14
    |
 LL |     let y = x.clone().join("matthias");
    |              ^^^^^^^^ help: remove this
    |
 note: cloned value is neither consumed nor mutated
-  --> $DIR/redundant_clone.rs:144:13
+  --> $DIR/redundant_clone.rs:145:13
    |
 LL |     let y = x.clone().join("matthias");
    |             ^^^^^^^^^