about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/drop_forget_ref.rs2
-rw-r--r--tests/ui/drop_ref.rs23
-rw-r--r--tests/ui/drop_ref.stderr38
3 files changed, 61 insertions, 2 deletions
diff --git a/clippy_lints/src/drop_forget_ref.rs b/clippy_lints/src/drop_forget_ref.rs
index 4721a7b3705..11e1bcdf12d 100644
--- a/clippy_lints/src/drop_forget_ref.rs
+++ b/clippy_lints/src/drop_forget_ref.rs
@@ -206,7 +206,7 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef {
             let is_copy = is_copy(cx, arg_ty);
             let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr);
             let (lint, msg) = match fn_name {
-                sym::mem_drop if arg_ty.is_ref() => (DROP_REF, DROP_REF_SUMMARY),
+                sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => (DROP_REF, DROP_REF_SUMMARY),
                 sym::mem_forget if arg_ty.is_ref() => (FORGET_REF, FORGET_REF_SUMMARY),
                 sym::mem_drop if is_copy && !drop_is_single_call_in_arm => (DROP_COPY, DROP_COPY_SUMMARY),
                 sym::mem_forget if is_copy => (FORGET_COPY, FORGET_COPY_SUMMARY),
diff --git a/tests/ui/drop_ref.rs b/tests/ui/drop_ref.rs
index 7de0b0bbdf9..10044e65f11 100644
--- a/tests/ui/drop_ref.rs
+++ b/tests/ui/drop_ref.rs
@@ -72,3 +72,26 @@ fn test_owl_result_2() -> Result<u8, ()> {
     produce_half_owl_ok().map(drop)?;
     Ok(1)
 }
+
+#[allow(unused)]
+#[allow(clippy::unit_cmp)]
+fn issue10122(x: u8) {
+    // This is a function which returns a reference and has a side-effect, which means
+    // that calling drop() on the function is considered an idiomatic way of achieving the side-effect
+    // in a match arm.
+    fn println_and<T>(t: &T) -> &T {
+        println!("foo");
+        t
+    }
+
+    match x {
+        0 => drop(println_and(&12)), // Don't lint (copy type), we only care about side-effects
+        1 => drop(println_and(&String::new())), // Don't lint (no copy type), we only care about side-effects
+        2 => {
+            drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block
+        },
+        3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm`
+        4 => drop(&2),                           // Lint, not a fn/method call
+        _ => (),
+    }
+}
diff --git a/tests/ui/drop_ref.stderr b/tests/ui/drop_ref.stderr
index 4743cf79b5d..293b9f6de83 100644
--- a/tests/ui/drop_ref.stderr
+++ b/tests/ui/drop_ref.stderr
@@ -107,5 +107,41 @@ note: argument has type `&SomeStruct`
 LL |     std::mem::drop(&SomeStruct);
    |                    ^^^^^^^^^^^
 
-error: aborting due to 9 previous errors
+error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
+  --> $DIR/drop_ref.rs:91:13
+   |
+LL |             drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: argument has type `&i32`
+  --> $DIR/drop_ref.rs:91:18
+   |
+LL |             drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block
+   |                  ^^^^^^^^^^^^^^^^
+
+error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
+  --> $DIR/drop_ref.rs:93:14
+   |
+LL |         3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm`
+   |              ^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: argument has type `&i32`
+  --> $DIR/drop_ref.rs:93:19
+   |
+LL |         3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm`
+   |                   ^^^^^^^^^^^^^^^^
+
+error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
+  --> $DIR/drop_ref.rs:94:14
+   |
+LL |         4 => drop(&2),                           // Lint, not a fn/method call
+   |              ^^^^^^^^
+   |
+note: argument has type `&i32`
+  --> $DIR/drop_ref.rs:94:19
+   |
+LL |         4 => drop(&2),                           // Lint, not a fn/method call
+   |                   ^^
+
+error: aborting due to 12 previous errors