about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-05-12 12:04:32 +0000
committerbors <bors@rust-lang.org>2023-05-12 12:04:32 +0000
commit077fc26f0acfa54e9c580534616c17ffc279a9d4 (patch)
tree5ac9db2c8e201070d88c537c9f9b37c37caff01a
parent0b795044c6f0854445f1f2bb6443e87848e150d1 (diff)
parentf5aede9c822875345eb7eb468ecd9bc4568ed112 (diff)
downloadrust-077fc26f0acfa54e9c580534616c17ffc279a9d4.tar.gz
rust-077fc26f0acfa54e9c580534616c17ffc279a9d4.zip
Auto merge of #109732 - Urgau:uplift_drop_forget_ref_lints, r=davidtwco
Uplift `clippy::{drop,forget}_{ref,copy}` lints

This PR aims at uplifting the `clippy::drop_ref`, `clippy::drop_copy`, `clippy::forget_ref` and `clippy::forget_copy` lints.

Those lints are/were declared in the correctness category of clippy because they lint on useless and most probably is not what the developer wanted.

## `drop_ref` and `forget_ref`

The `drop_ref` and `forget_ref` lint checks for calls to `std::mem::drop` or `std::mem::forget` with a reference instead of an owned value.

### Example

```rust
let mut lock_guard = mutex.lock();
std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex
// still locked
operation_that_requires_mutex_to_be_unlocked();
```

### Explanation

Calling `drop` or `forget` on a reference will only drop the reference itself, which is a no-op. It will not call the `drop` or `forget` method on the underlying referenced value, which is likely what was intended.

## `drop_copy` and `forget_copy`

The `drop_copy` and `forget_copy` lint checks for calls to `std::mem::forget` or `std::mem::drop` with a value that derives the Copy trait.

### Example

```rust
let x: i32 = 42; // i32 implements Copy
std::mem::forget(x) // A copy of x is passed to the function, leaving the
                    // original unaffected
```

### Explanation

Calling `std::mem::forget` [does nothing for types that implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the value will be copied and moved into the function on invocation.

-----

Followed the instructions for uplift a clippy describe here: https://github.com/rust-lang/rust/pull/99696#pullrequestreview-1134072751

cc `@m-ou-se` (as T-libs-api leader because the uplifting was discussed in a recent meeting)
-rw-r--r--compiler/rustc_builtin_macros/src/format_foreign.rs4
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs2
-rw-r--r--compiler/rustc_lint/messages.ftl16
-rw-r--r--compiler/rustc_lint/src/drop_forget_useless.rs164
-rw-r--r--compiler/rustc_lint/src/lib.rs3
-rw-r--r--compiler/rustc_lint/src/lints.rs37
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs3
-rw-r--r--library/core/src/mem/mod.rs1
-rw-r--r--library/core/src/task/poll.rs2
-rw-r--r--library/core/src/task/ready.rs4
-rw-r--r--library/std/src/panicking.rs2
-rw-r--r--library/std/src/sys/sgx/waitqueue/mod.rs16
-rw-r--r--library/std/src/sys/unix/fs.rs2
-rw-r--r--library/std/src/thread/tests.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/drop_forget_ref.rs117
-rw-r--r--src/tools/clippy/clippy_lints/src/renamed_lints.rs4
-rw-r--r--src/tools/clippy/tests/ui/drop_forget_copy.rs86
-rw-r--r--src/tools/clippy/tests/ui/drop_forget_copy.stderr112
-rw-r--r--src/tools/clippy/tests/ui/drop_ref.stderr147
-rw-r--r--src/tools/clippy/tests/ui/forget_ref.rs50
-rw-r--r--src/tools/clippy/tests/ui/forget_ref.stderr111
-rw-r--r--src/tools/clippy/tests/ui/mem_forget.rs2
-rw-r--r--src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs2
-rw-r--r--src/tools/clippy/tests/ui/rename.fixed8
-rw-r--r--src/tools/clippy/tests/ui/rename.rs8
-rw-r--r--src/tools/clippy/tests/ui/rename.stderr112
-rw-r--r--src/tools/clippy/tests/ui/unknown_clippy_lints.fixed2
-rw-r--r--src/tools/clippy/tests/ui/unknown_clippy_lints.stderr2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs2
-rw-r--r--src/tools/miri/tests/fail/uninit_buffer.rs2
-rw-r--r--src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs2
-rw-r--r--src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs3
-rw-r--r--tests/ui/associated-inherent-types/inference.rs1
-rw-r--r--tests/ui/async-await/multiple-lifetimes/partial-relation.rs2
-rw-r--r--tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs1
-rw-r--r--tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs1
-rw-r--r--tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs2
-rw-r--r--tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs1
-rw-r--r--tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr2
-rw-r--r--tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs1
-rw-r--r--tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs2
-rw-r--r--tests/ui/consts/const_forget.rs2
-rw-r--r--tests/ui/consts/issue-104155.rs3
-rw-r--r--tests/ui/crate-leading-sep.rs2
-rw-r--r--tests/ui/drop/repeat-drop.rs2
-rw-r--r--tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed3
-rw-r--r--tests/ui/explicit/explicit-call-to-supertrait-dtor.rs3
-rw-r--r--tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs1
-rw-r--r--tests/ui/generator/drop-env.rs1
-rw-r--r--tests/ui/generator/issue-57017.no_drop_tracking.stderr42
-rw-r--r--tests/ui/generator/issue-57017.rs1
-rw-r--r--tests/ui/generator/non-static-is-unpin.rs1
-rw-r--r--tests/ui/generator/resume-arg-size.rs1
-rw-r--r--tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs1
-rw-r--r--tests/ui/illegal-ufcs-drop.fixed3
-rw-r--r--tests/ui/illegal-ufcs-drop.rs3
-rw-r--r--tests/ui/illegal-ufcs-drop.stderr2
-rw-r--r--tests/ui/lint/drop_copy.rs79
-rw-r--r--tests/ui/lint/drop_copy.stderr108
-rw-r--r--tests/ui/lint/drop_ref.rs (renamed from src/tools/clippy/tests/ui/drop_ref.rs)48
-rw-r--r--tests/ui/lint/drop_ref.stderr127
-rw-r--r--tests/ui/lint/forget_copy.rs56
-rw-r--r--tests/ui/lint/forget_copy.stderr88
-rw-r--r--tests/ui/lint/forget_ref.rs39
-rw-r--r--tests/ui/lint/forget_ref.stderr97
-rw-r--r--tests/ui/liveness/liveness-unused.rs2
-rw-r--r--tests/ui/macros/parse-complex-macro-invoc-op.rs1
-rw-r--r--tests/ui/never_type/never-assign-dead-code.rs1
-rw-r--r--tests/ui/never_type/never-assign-dead-code.stderr8
-rw-r--r--tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs2
-rw-r--r--tests/ui/nll/ty-outlives/projection-body.rs2
-rw-r--r--tests/ui/or-patterns/or-patterns-default-binding-modes.rs2
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs3
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs2
-rw-r--r--tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs2
-rw-r--r--tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs2
-rw-r--r--tests/ui/print_type_sizes/async.rs2
-rw-r--r--tests/ui/print_type_sizes/async.stdout8
-rw-r--r--tests/ui/print_type_sizes/generator_discr_placement.rs1
-rw-r--r--tests/ui/print_type_sizes/generator_discr_placement.stdout2
-rw-r--r--tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs6
-rw-r--r--tests/ui/regions/type-param-outlives-reempty-issue-74429.rs2
-rw-r--r--tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs2
-rw-r--r--tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs2
-rw-r--r--tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr30
-rw-r--r--tests/ui/rust-2018/remove-extern-crate.fixed1
-rw-r--r--tests/ui/rust-2018/remove-extern-crate.rs1
-rw-r--r--tests/ui/rust-2018/remove-extern-crate.stderr6
-rw-r--r--tests/ui/statics/issue-91050-1.rs2
-rw-r--r--tests/ui/traits/copy-guessing.rs3
-rw-r--r--tests/ui/traits/impl-evaluation-order.rs2
-rw-r--r--tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr4
-rw-r--r--tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs1
-rw-r--r--tests/ui/traits/new-solver/temporary-ambiguity.rs2
-rw-r--r--tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs2
-rw-r--r--tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr8
98 files changed, 1106 insertions, 772 deletions
diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs
index bd9e903b6ba..bd5356575ca 100644
--- a/compiler/rustc_builtin_macros/src/format_foreign.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign.rs
@@ -562,15 +562,13 @@ pub(crate) mod printf {
         }
 
         if let Type = state {
-            drop(c);
             type_ = at.slice_between(next).unwrap();
 
             // Don't use `move_to!` here, as we *can* be at the end of the input.
             at = next;
         }
 
-        drop(c);
-        drop(next);
+        let _ = c; // to avoid never used value
 
         end = at;
         let position = InnerSpan::new(start.at, end.at);
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index 88a0a81e276..9c139d17c18 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -828,7 +828,7 @@ where
                 } else {
                     match variables.probe(vid) {
                         TypeVariableValue::Known { value: u } => {
-                            drop(variables);
+                            drop(inner);
                             self.relate(u, u)
                         }
                         TypeVariableValue::Unknown { universe: _universe } => {
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 71cf644eb50..a5639404faf 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -520,3 +520,19 @@ lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its ass
     .specifically = this associated type bound is unsatisfied for `{$proj_ty}`
 
 lint_opaque_hidden_inferred_bound_sugg = add this bound
+
+lint_drop_ref = calls to `std::mem::drop` with a reference instead of an owned value does nothing
+    .label = argument has type `{$arg_ty}`
+    .note = use `let _ = ...` to ignore the expression or result
+
+lint_drop_copy = calls to `std::mem::drop` with a value that implements `Copy` does nothing
+    .label = argument has type `{$arg_ty}`
+    .note = use `let _ = ...` to ignore the expression or result
+
+lint_forget_ref = calls to `std::mem::forget` with a reference instead of an owned value does nothing
+    .label = argument has type `{$arg_ty}`
+    .note = use `let _ = ...` to ignore the expression or result
+
+lint_forget_copy = calls to `std::mem::forget` with a value that implements `Copy` does nothing
+    .label = argument has type `{$arg_ty}`
+    .note = use `let _ = ...` to ignore the expression or result
diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs
new file mode 100644
index 00000000000..259abc2af11
--- /dev/null
+++ b/compiler/rustc_lint/src/drop_forget_useless.rs
@@ -0,0 +1,164 @@
+use rustc_hir::{Arm, Expr, ExprKind, Node};
+use rustc_span::sym;
+
+use crate::{
+    lints::{DropCopyDiag, DropRefDiag, ForgetCopyDiag, ForgetRefDiag},
+    LateContext, LateLintPass, LintContext,
+};
+
+declare_lint! {
+    /// The `drop_ref` lint checks for calls to `std::mem::drop` with a reference
+    /// instead of an owned value.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// # fn operation_that_requires_mutex_to_be_unlocked() {} // just to make it compile
+    /// # let mutex = std::sync::Mutex::new(1); // just to make it compile
+    /// let mut lock_guard = mutex.lock();
+    /// std::mem::drop(&lock_guard); // Should have been drop(lock_guard), mutex
+    /// // still locked
+    /// operation_that_requires_mutex_to_be_unlocked();
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Calling `drop` on a reference will only drop the
+    /// reference itself, which is a no-op. It will not call the `drop` method (from
+    /// the `Drop` trait implementation) on the underlying referenced value, which
+    /// is likely what was intended.
+    pub DROP_REF,
+    Warn,
+    "calls to `std::mem::drop` with a reference instead of an owned value"
+}
+
+declare_lint! {
+    /// The `forget_ref` lint checks for calls to `std::mem::forget` with a reference
+    /// instead of an owned value.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// let x = Box::new(1);
+    /// std::mem::forget(&x); // Should have been forget(x), x will still be dropped
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Calling `forget` on a reference will only forget the
+    /// reference itself, which is a no-op. It will not forget the underlying
+    /// referenced value, which is likely what was intended.
+    pub FORGET_REF,
+    Warn,
+    "calls to `std::mem::forget` with a reference instead of an owned value"
+}
+
+declare_lint! {
+    /// The `drop_copy` lint checks for calls to `std::mem::drop` with a value
+    /// that derives the Copy trait.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// let x: i32 = 42; // i32 implements Copy
+    /// std::mem::drop(x); // A copy of x is passed to the function, leaving the
+    ///                    // original unaffected
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Calling `std::mem::drop` [does nothing for types that
+    /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the
+    /// value will be copied and moved into the function on invocation.
+    pub DROP_COPY,
+    Warn,
+    "calls to `std::mem::drop` with a value that implements Copy"
+}
+
+declare_lint! {
+    /// The `forget_copy` lint checks for calls to `std::mem::forget` with a value
+    /// that derives the Copy trait.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// let x: i32 = 42; // i32 implements Copy
+    /// std::mem::forget(x); // A copy of x is passed to the function, leaving the
+    ///                      // original unaffected
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Calling `std::mem::forget` [does nothing for types that
+    /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the
+    /// value will be copied and moved into the function on invocation.
+    ///
+    /// An alternative, but also valid, explanation is that Copy types do not
+    /// implement the Drop trait, which means they have no destructors. Without a
+    /// destructor, there is nothing for `std::mem::forget` to ignore.
+    pub FORGET_COPY,
+    Warn,
+    "calls to `std::mem::forget` with a value that implements Copy"
+}
+
+declare_lint_pass!(DropForgetUseless => [DROP_REF, FORGET_REF, DROP_COPY, FORGET_COPY]);
+
+impl<'tcx> LateLintPass<'tcx> for DropForgetUseless {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
+        if let ExprKind::Call(path, [arg]) = expr.kind
+            && let ExprKind::Path(ref qpath) = path.kind
+            && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
+            && let Some(fn_name) = cx.tcx.get_diagnostic_name(def_id)
+        {
+            let arg_ty = cx.typeck_results().expr_ty(arg);
+            let is_copy = arg_ty.is_copy_modulo_regions(cx.tcx, cx.param_env);
+            let drop_is_single_call_in_arm = is_single_call_in_arm(cx, arg, expr);
+            match fn_name {
+                sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => {
+                    cx.emit_spanned_lint(DROP_REF, expr.span, DropRefDiag { arg_ty, label: arg.span });
+                },
+                sym::mem_forget if arg_ty.is_ref() => {
+                    cx.emit_spanned_lint(FORGET_REF, expr.span, ForgetRefDiag { arg_ty, label: arg.span });
+                },
+                sym::mem_drop if is_copy && !drop_is_single_call_in_arm => {
+                    cx.emit_spanned_lint(DROP_COPY, expr.span, DropCopyDiag { arg_ty, label: arg.span });
+                }
+                sym::mem_forget if is_copy => {
+                    cx.emit_spanned_lint(FORGET_COPY, expr.span, ForgetCopyDiag { arg_ty, label: arg.span });
+                }
+                _ => return,
+            };
+        }
+    }
+}
+
+// Dropping returned value of a function, as in the following snippet is considered idiomatic, see
+// rust-lang/rust-clippy#9482 for examples.
+//
+// ```
+// match <var> {
+//     <pat> => drop(fn_with_side_effect_and_returning_some_value()),
+//     ..
+// }
+// ```
+fn is_single_call_in_arm<'tcx>(
+    cx: &LateContext<'tcx>,
+    arg: &'tcx Expr<'_>,
+    drop_expr: &'tcx Expr<'_>,
+) -> bool {
+    if matches!(arg.kind, ExprKind::Call(..) | ExprKind::MethodCall(..)) {
+        let parent_node = cx.tcx.hir().find_parent(drop_expr.hir_id);
+        if let Some(Node::Arm(Arm { body, .. })) = &parent_node {
+            return body.hir_id == drop_expr.hir_id;
+        }
+    }
+    false
+}
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 319eb2ea445..5c7016633c2 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -52,6 +52,7 @@ mod array_into_iter;
 pub mod builtin;
 mod context;
 mod deref_into_dyn_supertrait;
+mod drop_forget_useless;
 mod early;
 mod enum_intrinsics_non_enums;
 mod errors;
@@ -96,6 +97,7 @@ use rustc_span::Span;
 use array_into_iter::ArrayIntoIter;
 use builtin::*;
 use deref_into_dyn_supertrait::*;
+use drop_forget_useless::*;
 use enum_intrinsics_non_enums::EnumIntrinsicsNonEnums;
 use for_loops_over_fallibles::*;
 use hidden_unicode_codepoints::*;
@@ -201,6 +203,7 @@ late_lint_methods!(
         [
             ForLoopsOverFallibles: ForLoopsOverFallibles,
             DerefIntoDynSupertrait: DerefIntoDynSupertrait,
+            DropForgetUseless: DropForgetUseless,
             HardwiredLints: HardwiredLints,
             ImproperCTypesDeclarations: ImproperCTypesDeclarations,
             ImproperCTypesDefinitions: ImproperCTypesDefinitions,
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index d7bacc6485f..8e48806b504 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -662,6 +662,43 @@ pub struct ForLoopsOverFalliblesSuggestion<'a> {
     pub end_span: Span,
 }
 
+// drop_ref.rs
+#[derive(LintDiagnostic)]
+#[diag(lint_drop_ref)]
+#[note]
+pub struct DropRefDiag<'a> {
+    pub arg_ty: Ty<'a>,
+    #[label]
+    pub label: Span,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(lint_drop_copy)]
+#[note]
+pub struct DropCopyDiag<'a> {
+    pub arg_ty: Ty<'a>,
+    #[label]
+    pub label: Span,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(lint_forget_ref)]
+#[note]
+pub struct ForgetRefDiag<'a> {
+    pub arg_ty: Ty<'a>,
+    #[label]
+    pub label: Span,
+}
+
+#[derive(LintDiagnostic)]
+#[diag(lint_forget_copy)]
+#[note]
+pub struct ForgetCopyDiag<'a> {
+    pub arg_ty: Ty<'a>,
+    #[label]
+    pub label: Span,
+}
+
 // hidden_unicode_codepoints.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_hidden_unicode_codepoints)]
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 4b7014e3109..d7a7fdebda6 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -880,12 +880,11 @@ macro_rules! make_mir_visitor {
             ) {
                 let Constant {
                     span,
-                    user_ty,
+                    user_ty: _, // no visit method for this
                     literal,
                 } = constant;
 
                 self.visit_span($(& $mutability)? *span);
-                drop(user_ty); // no visit method for this
                 match literal {
                     ConstantKind::Ty(ct) => self.visit_ty_const($(&$mutability)? *ct, location),
                     ConstantKind::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)),
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 4913a6de918..289305253ec 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -968,6 +968,7 @@ pub const fn replace<T>(dest: &mut T, src: T) -> T {
 /// Integers and other types implementing [`Copy`] are unaffected by `drop`.
 ///
 /// ```
+/// # #![cfg_attr(not(bootstrap), allow(drop_copy))]
 /// #[derive(Copy, Clone)]
 /// struct Foo(u8);
 ///
diff --git a/library/core/src/task/poll.rs b/library/core/src/task/poll.rs
index 168516263f1..5283a576d1b 100644
--- a/library/core/src/task/poll.rs
+++ b/library/core/src/task/poll.rs
@@ -116,7 +116,7 @@ impl<T> Poll<T> {
     ///     let fut = Pin::new(&mut fut);
     ///
     ///     let num = fut.poll(cx).ready()?;
-    ///     # drop(num);
+    ///     # let _ = num; // to silence unused warning
     ///     // ... use num
     ///
     ///     Poll::Ready(())
diff --git a/library/core/src/task/ready.rs b/library/core/src/task/ready.rs
index b1daf545fbe..8d12625e88d 100644
--- a/library/core/src/task/ready.rs
+++ b/library/core/src/task/ready.rs
@@ -22,7 +22,7 @@ use core::task::Poll;
 ///     let fut = Pin::new(&mut fut);
 ///
 ///     let num = ready!(fut.poll(cx));
-///     # drop(num);
+///     # let _ = num;
 ///     // ... use num
 ///
 ///     Poll::Ready(())
@@ -44,7 +44,7 @@ use core::task::Poll;
 ///     Poll::Ready(t) => t,
 ///     Poll::Pending => return Poll::Pending,
 /// };
-///     # drop(num);
+///     # let _ = num; // to silence unused warning
 ///     # // ... use num
 ///     #
 ///     # Poll::Ready(())
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index a46a29cbad6..6d59266b6f8 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -541,7 +541,7 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
             // Lazily, the first time this gets called, run the actual string formatting.
             self.string.get_or_insert_with(|| {
                 let mut s = String::new();
-                drop(s.write_fmt(*inner));
+                let _err = s.write_fmt(*inner);
                 s
             })
         }
diff --git a/library/std/src/sys/sgx/waitqueue/mod.rs b/library/std/src/sys/sgx/waitqueue/mod.rs
index 61bb11d9a6f..5e1d859ee99 100644
--- a/library/std/src/sys/sgx/waitqueue/mod.rs
+++ b/library/std/src/sys/sgx/waitqueue/mod.rs
@@ -202,12 +202,18 @@ impl WaitQueue {
     pub fn notify_one<T>(
         mut guard: SpinMutexGuard<'_, WaitVariable<T>>,
     ) -> Result<WaitGuard<'_, T>, SpinMutexGuard<'_, WaitVariable<T>>> {
+        // SAFETY: lifetime of the pop() return value is limited to the map
+        // closure (The closure return value is 'static). The underlying
+        // stack frame won't be freed until after the WaitGuard created below
+        // is dropped.
         unsafe {
-            if let Some(entry) = guard.queue.inner.pop() {
+            let tcs = guard.queue.inner.pop().map(|entry| -> Tcs {
                 let mut entry_guard = entry.lock();
-                let tcs = entry_guard.tcs;
                 entry_guard.wake = true;
-                drop(entry);
+                entry_guard.tcs
+            });
+
+            if let Some(tcs) = tcs {
                 Ok(WaitGuard { mutex_guard: Some(guard), notified_tcs: NotifiedTcs::Single(tcs) })
             } else {
                 Err(guard)
@@ -223,6 +229,9 @@ impl WaitQueue {
     pub fn notify_all<T>(
         mut guard: SpinMutexGuard<'_, WaitVariable<T>>,
     ) -> Result<WaitGuard<'_, T>, SpinMutexGuard<'_, WaitVariable<T>>> {
+        // SAFETY: lifetime of the pop() return values are limited to the
+        // while loop body. The underlying stack frames won't be freed until
+        // after the WaitGuard created below is dropped.
         unsafe {
             let mut count = 0;
             while let Some(entry) = guard.queue.inner.pop() {
@@ -230,6 +239,7 @@ impl WaitQueue {
                 let mut entry_guard = entry.lock();
                 entry_guard.wake = true;
             }
+
             if let Some(count) = NonZeroUsize::new(count) {
                 Ok(WaitGuard { mutex_guard: Some(guard), notified_tcs: NotifiedTcs::All { count } })
             } else {
diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs
index 22d2ae39713..09db5b11dbf 100644
--- a/library/std/src/sys/unix/fs.rs
+++ b/library/std/src/sys/unix/fs.rs
@@ -1210,7 +1210,7 @@ impl File {
                 // Redox doesn't appear to support `UTIME_OMIT`.
                 // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore
                 // the same as for Redox.
-                drop(times);
+                let _ = times;
                 Err(io::const_io_error!(
                     io::ErrorKind::Unsupported,
                     "setting file times not supported",
diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs
index 6c9ce6fa0dd..b65e2572cc5 100644
--- a/library/std/src/thread/tests.rs
+++ b/library/std/src/thread/tests.rs
@@ -375,7 +375,9 @@ fn test_scoped_threads_nll() {
     // this is mostly a *compilation test* for this exact function:
     fn foo(x: &u8) {
         thread::scope(|s| {
-            s.spawn(|| drop(x));
+            s.spawn(|| match x {
+                _ => (),
+            });
         });
     }
     // let's also run it for good measure
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 79d0f6f3607..04993e49287 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -132,12 +132,8 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::doc::NEEDLESS_DOCTEST_MAIN_INFO,
     crate::doc::UNNECESSARY_SAFETY_DOC_INFO,
     crate::double_parens::DOUBLE_PARENS_INFO,
-    crate::drop_forget_ref::DROP_COPY_INFO,
     crate::drop_forget_ref::DROP_NON_DROP_INFO,
-    crate::drop_forget_ref::DROP_REF_INFO,
-    crate::drop_forget_ref::FORGET_COPY_INFO,
     crate::drop_forget_ref::FORGET_NON_DROP_INFO,
-    crate::drop_forget_ref::FORGET_REF_INFO,
     crate::drop_forget_ref::UNDROPPED_MANUALLY_DROPS_INFO,
     crate::duplicate_mod::DUPLICATE_MOD_INFO,
     crate::else_if_without_else::ELSE_IF_WITHOUT_ELSE_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
index 11e1bcdf12d..b2f7d026cc8 100644
--- a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
@@ -9,102 +9,6 @@ use rustc_span::sym;
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for calls to `std::mem::drop` with a reference
-    /// instead of an owned value.
-    ///
-    /// ### Why is this bad?
-    /// Calling `drop` on a reference will only drop the
-    /// reference itself, which is a no-op. It will not call the `drop` method (from
-    /// the `Drop` trait implementation) on the underlying referenced value, which
-    /// is likely what was intended.
-    ///
-    /// ### Example
-    /// ```ignore
-    /// let mut lock_guard = mutex.lock();
-    /// std::mem::drop(&lock_guard) // Should have been drop(lock_guard), mutex
-    /// // still locked
-    /// operation_that_requires_mutex_to_be_unlocked();
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub DROP_REF,
-    correctness,
-    "calls to `std::mem::drop` with a reference instead of an owned value"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for calls to `std::mem::forget` with a reference
-    /// instead of an owned value.
-    ///
-    /// ### Why is this bad?
-    /// Calling `forget` on a reference will only forget the
-    /// reference itself, which is a no-op. It will not forget the underlying
-    /// referenced
-    /// value, which is likely what was intended.
-    ///
-    /// ### Example
-    /// ```rust
-    /// let x = Box::new(1);
-    /// std::mem::forget(&x) // Should have been forget(x), x will still be dropped
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub FORGET_REF,
-    correctness,
-    "calls to `std::mem::forget` with a reference instead of an owned value"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for calls to `std::mem::drop` with a value
-    /// that derives the Copy trait
-    ///
-    /// ### Why is this bad?
-    /// Calling `std::mem::drop` [does nothing for types that
-    /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html), since the
-    /// value will be copied and moved into the function on invocation.
-    ///
-    /// ### Example
-    /// ```rust
-    /// let x: i32 = 42; // i32 implements Copy
-    /// std::mem::drop(x) // A copy of x is passed to the function, leaving the
-    ///                   // original unaffected
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub DROP_COPY,
-    correctness,
-    "calls to `std::mem::drop` with a value that implements Copy"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for calls to `std::mem::forget` with a value that
-    /// derives the Copy trait
-    ///
-    /// ### Why is this bad?
-    /// Calling `std::mem::forget` [does nothing for types that
-    /// implement Copy](https://doc.rust-lang.org/std/mem/fn.drop.html) since the
-    /// value will be copied and moved into the function on invocation.
-    ///
-    /// An alternative, but also valid, explanation is that Copy types do not
-    /// implement
-    /// the Drop trait, which means they have no destructors. Without a destructor,
-    /// there
-    /// is nothing for `std::mem::forget` to ignore.
-    ///
-    /// ### Example
-    /// ```rust
-    /// let x: i32 = 42; // i32 implements Copy
-    /// std::mem::forget(x) // A copy of x is passed to the function, leaving the
-    ///                     // original unaffected
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub FORGET_COPY,
-    correctness,
-    "calls to `std::mem::forget` with a value that implements Copy"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
     /// Checks for calls to `std::mem::drop` with a value that does not implement `Drop`.
     ///
     /// ### Why is this bad?
@@ -172,24 +76,12 @@ declare_clippy_lint! {
     "use of safe `std::mem::drop` function to drop a std::mem::ManuallyDrop, which will not drop the inner value"
 }
 
-const DROP_REF_SUMMARY: &str = "calls to `std::mem::drop` with a reference instead of an owned value. \
-                                Dropping a reference does nothing";
-const FORGET_REF_SUMMARY: &str = "calls to `std::mem::forget` with a reference instead of an owned value. \
-                                  Forgetting a reference does nothing";
-const DROP_COPY_SUMMARY: &str = "calls to `std::mem::drop` with a value that implements `Copy`. \
-                                 Dropping a copy leaves the original intact";
-const FORGET_COPY_SUMMARY: &str = "calls to `std::mem::forget` with a value that implements `Copy`. \
-                                   Forgetting a copy leaves the original intact";
 const DROP_NON_DROP_SUMMARY: &str = "call to `std::mem::drop` with a value that does not implement `Drop`. \
                                  Dropping such a type only extends its contained lifetimes";
 const FORGET_NON_DROP_SUMMARY: &str = "call to `std::mem::forget` with a value that does not implement `Drop`. \
                                    Forgetting such a type is the same as dropping it";
 
 declare_lint_pass!(DropForgetRef => [
-    DROP_REF,
-    FORGET_REF,
-    DROP_COPY,
-    FORGET_COPY,
     DROP_NON_DROP,
     FORGET_NON_DROP,
     UNDROPPED_MANUALLY_DROPS
@@ -206,10 +98,11 @@ 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_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),
+                // early return for uplifted lints: drop_ref, drop_copy, forget_ref, forget_copy
+                sym::mem_drop if arg_ty.is_ref() && !drop_is_single_call_in_arm => return,
+                sym::mem_forget if arg_ty.is_ref() => return,
+                sym::mem_drop if is_copy && !drop_is_single_call_in_arm => return,
+                sym::mem_forget if is_copy => return,
                 sym::mem_drop if is_type_lang_item(cx, arg_ty, LangItem::ManuallyDrop) => {
                     span_lint_and_help(
                         cx,
diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
index 5e81a01a461..52e22c0c630 100644
--- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
@@ -32,9 +32,13 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
     ("clippy::zero_width_space", "clippy::invisible_characters"),
     ("clippy::clone_double_ref", "suspicious_double_ref_op"),
     ("clippy::drop_bounds", "drop_bounds"),
+    ("clippy::drop_copy", "drop_copy"),
+    ("clippy::drop_ref", "drop_ref"),
     ("clippy::for_loop_over_option", "for_loops_over_fallibles"),
     ("clippy::for_loop_over_result", "for_loops_over_fallibles"),
     ("clippy::for_loops_over_fallibles", "for_loops_over_fallibles"),
+    ("clippy::forget_copy", "forget_copy"),
+    ("clippy::forget_ref", "forget_ref"),
     ("clippy::into_iter_on_array", "array_into_iter"),
     ("clippy::invalid_atomic_ordering", "invalid_atomic_ordering"),
     ("clippy::invalid_ref", "invalid_value"),
diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.rs b/src/tools/clippy/tests/ui/drop_forget_copy.rs
deleted file mode 100644
index a7276dd59f4..00000000000
--- a/src/tools/clippy/tests/ui/drop_forget_copy.rs
+++ /dev/null
@@ -1,86 +0,0 @@
-#![warn(clippy::drop_copy, clippy::forget_copy)]
-#![allow(clippy::toplevel_ref_arg, clippy::drop_ref, clippy::forget_ref, unused_mut)]
-
-use std::mem::{drop, forget};
-use std::vec::Vec;
-
-#[derive(Copy, Clone)]
-struct SomeStruct;
-
-struct AnotherStruct {
-    x: u8,
-    y: u8,
-    z: Vec<u8>,
-}
-
-impl Clone for AnotherStruct {
-    fn clone(&self) -> AnotherStruct {
-        AnotherStruct {
-            x: self.x,
-            y: self.y,
-            z: self.z.clone(),
-        }
-    }
-}
-
-fn main() {
-    let s1 = SomeStruct {};
-    let s2 = s1;
-    let s3 = &s1;
-    let mut s4 = s1;
-    let ref s5 = s1;
-
-    drop(s1);
-    drop(s2);
-    drop(s3);
-    drop(s4);
-    drop(s5);
-
-    forget(s1);
-    forget(s2);
-    forget(s3);
-    forget(s4);
-    forget(s5);
-
-    let a1 = AnotherStruct {
-        x: 255,
-        y: 0,
-        z: vec![1, 2, 3],
-    };
-    let a2 = &a1;
-    let mut a3 = a1.clone();
-    let ref a4 = a1;
-    let a5 = a1.clone();
-
-    drop(a2);
-    drop(a3);
-    drop(a4);
-    drop(a5);
-
-    forget(a2);
-    let a3 = &a1;
-    forget(a3);
-    forget(a4);
-    let a5 = a1.clone();
-    forget(a5);
-}
-
-#[allow(unused)]
-#[allow(clippy::unit_cmp)]
-fn issue9482(x: u8) {
-    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/src/tools/clippy/tests/ui/drop_forget_copy.stderr b/src/tools/clippy/tests/ui/drop_forget_copy.stderr
deleted file mode 100644
index 90bef1c3c43..00000000000
--- a/src/tools/clippy/tests/ui/drop_forget_copy.stderr
+++ /dev/null
@@ -1,112 +0,0 @@
-error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact
-  --> $DIR/drop_forget_copy.rs:33:5
-   |
-LL |     drop(s1);
-   |     ^^^^^^^^
-   |
-note: argument has type `SomeStruct`
-  --> $DIR/drop_forget_copy.rs:33:10
-   |
-LL |     drop(s1);
-   |          ^^
-   = note: `-D clippy::drop-copy` implied by `-D warnings`
-
-error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact
-  --> $DIR/drop_forget_copy.rs:34:5
-   |
-LL |     drop(s2);
-   |     ^^^^^^^^
-   |
-note: argument has type `SomeStruct`
-  --> $DIR/drop_forget_copy.rs:34:10
-   |
-LL |     drop(s2);
-   |          ^^
-
-error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact
-  --> $DIR/drop_forget_copy.rs:36:5
-   |
-LL |     drop(s4);
-   |     ^^^^^^^^
-   |
-note: argument has type `SomeStruct`
-  --> $DIR/drop_forget_copy.rs:36:10
-   |
-LL |     drop(s4);
-   |          ^^
-
-error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact
-  --> $DIR/drop_forget_copy.rs:39:5
-   |
-LL |     forget(s1);
-   |     ^^^^^^^^^^
-   |
-note: argument has type `SomeStruct`
-  --> $DIR/drop_forget_copy.rs:39:12
-   |
-LL |     forget(s1);
-   |            ^^
-   = note: `-D clippy::forget-copy` implied by `-D warnings`
-
-error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact
-  --> $DIR/drop_forget_copy.rs:40:5
-   |
-LL |     forget(s2);
-   |     ^^^^^^^^^^
-   |
-note: argument has type `SomeStruct`
-  --> $DIR/drop_forget_copy.rs:40:12
-   |
-LL |     forget(s2);
-   |            ^^
-
-error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetting a copy leaves the original intact
-  --> $DIR/drop_forget_copy.rs:42:5
-   |
-LL |     forget(s4);
-   |     ^^^^^^^^^^
-   |
-note: argument has type `SomeStruct`
-  --> $DIR/drop_forget_copy.rs:42:12
-   |
-LL |     forget(s4);
-   |            ^^
-
-error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a copy leaves the original intact
-  --> $DIR/drop_forget_copy.rs:80: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_forget_copy.rs:80: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 value that implements `Copy`. Dropping a copy leaves the original intact
-  --> $DIR/drop_forget_copy.rs:82:14
-   |
-LL |         3 if drop(println_and(14)) == () => (), // Lint, idiomatic use is only in body of `Arm`
-   |              ^^^^^^^^^^^^^^^^^^^^^
-   |
-note: argument has type `i32`
-  --> $DIR/drop_forget_copy.rs:82: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 value that implements `Copy`. Dropping a copy leaves the original intact
-  --> $DIR/drop_forget_copy.rs:83:14
-   |
-LL |         4 => drop(2),                           // Lint, not a fn/method call
-   |              ^^^^^^^
-   |
-note: argument has type `i32`
-  --> $DIR/drop_forget_copy.rs:83:19
-   |
-LL |         4 => drop(2),                           // Lint, not a fn/method call
-   |                   ^
-
-error: aborting due to 9 previous errors
-
diff --git a/src/tools/clippy/tests/ui/drop_ref.stderr b/src/tools/clippy/tests/ui/drop_ref.stderr
deleted file mode 100644
index 293b9f6de83..00000000000
--- a/src/tools/clippy/tests/ui/drop_ref.stderr
+++ /dev/null
@@ -1,147 +0,0 @@
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
-  --> $DIR/drop_ref.rs:11:5
-   |
-LL |     drop(&SomeStruct);
-   |     ^^^^^^^^^^^^^^^^^
-   |
-note: argument has type `&SomeStruct`
-  --> $DIR/drop_ref.rs:11:10
-   |
-LL |     drop(&SomeStruct);
-   |          ^^^^^^^^^^^
-   = note: `-D clippy::drop-ref` implied by `-D warnings`
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
-  --> $DIR/drop_ref.rs:14:5
-   |
-LL |     drop(&owned1);
-   |     ^^^^^^^^^^^^^
-   |
-note: argument has type `&SomeStruct`
-  --> $DIR/drop_ref.rs:14:10
-   |
-LL |     drop(&owned1);
-   |          ^^^^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
-  --> $DIR/drop_ref.rs:15:5
-   |
-LL |     drop(&&owned1);
-   |     ^^^^^^^^^^^^^^
-   |
-note: argument has type `&&SomeStruct`
-  --> $DIR/drop_ref.rs:15:10
-   |
-LL |     drop(&&owned1);
-   |          ^^^^^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
-  --> $DIR/drop_ref.rs:16:5
-   |
-LL |     drop(&mut owned1);
-   |     ^^^^^^^^^^^^^^^^^
-   |
-note: argument has type `&mut SomeStruct`
-  --> $DIR/drop_ref.rs:16:10
-   |
-LL |     drop(&mut owned1);
-   |          ^^^^^^^^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
-  --> $DIR/drop_ref.rs:20:5
-   |
-LL |     drop(reference1);
-   |     ^^^^^^^^^^^^^^^^
-   |
-note: argument has type `&SomeStruct`
-  --> $DIR/drop_ref.rs:20:10
-   |
-LL |     drop(reference1);
-   |          ^^^^^^^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
-  --> $DIR/drop_ref.rs:23:5
-   |
-LL |     drop(reference2);
-   |     ^^^^^^^^^^^^^^^^
-   |
-note: argument has type `&mut SomeStruct`
-  --> $DIR/drop_ref.rs:23:10
-   |
-LL |     drop(reference2);
-   |          ^^^^^^^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
-  --> $DIR/drop_ref.rs:26:5
-   |
-LL |     drop(reference3);
-   |     ^^^^^^^^^^^^^^^^
-   |
-note: argument has type `&SomeStruct`
-  --> $DIR/drop_ref.rs:26:10
-   |
-LL |     drop(reference3);
-   |          ^^^^^^^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
-  --> $DIR/drop_ref.rs:31:5
-   |
-LL |     drop(&val);
-   |     ^^^^^^^^^^
-   |
-note: argument has type `&T`
-  --> $DIR/drop_ref.rs:31:10
-   |
-LL |     drop(&val);
-   |          ^^^^
-
-error: calls to `std::mem::drop` with a reference instead of an owned value. Dropping a reference does nothing
-  --> $DIR/drop_ref.rs:39:5
-   |
-LL |     std::mem::drop(&SomeStruct);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: argument has type `&SomeStruct`
-  --> $DIR/drop_ref.rs:39:20
-   |
-LL |     std::mem::drop(&SomeStruct);
-   |                    ^^^^^^^^^^^
-
-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
-
diff --git a/src/tools/clippy/tests/ui/forget_ref.rs b/src/tools/clippy/tests/ui/forget_ref.rs
deleted file mode 100644
index 031b415f56f..00000000000
--- a/src/tools/clippy/tests/ui/forget_ref.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-#![warn(clippy::forget_ref)]
-#![allow(clippy::toplevel_ref_arg)]
-#![allow(clippy::unnecessary_wraps, clippy::forget_non_drop)]
-#![allow(clippy::borrow_deref_ref)]
-
-use std::mem::forget;
-
-struct SomeStruct;
-
-fn main() {
-    forget(&SomeStruct);
-
-    let mut owned = SomeStruct;
-    forget(&owned);
-    forget(&&owned);
-    forget(&mut owned);
-    forget(owned); //OK
-
-    let reference1 = &SomeStruct;
-    forget(&*reference1);
-
-    let reference2 = &mut SomeStruct;
-    forget(reference2);
-
-    let ref reference3 = SomeStruct;
-    forget(reference3);
-}
-
-#[allow(dead_code)]
-fn test_generic_fn_forget<T>(val: T) {
-    forget(&val);
-    forget(val); //OK
-}
-
-#[allow(dead_code)]
-fn test_similarly_named_function() {
-    fn forget<T>(_val: T) {}
-    forget(&SomeStruct); //OK; call to unrelated function which happens to have the same name
-    std::mem::forget(&SomeStruct);
-}
-
-#[derive(Copy, Clone)]
-pub struct Error;
-fn produce_half_owl_error() -> Result<(), Error> {
-    Ok(())
-}
-
-fn produce_half_owl_ok() -> Result<bool, ()> {
-    Ok(true)
-}
diff --git a/src/tools/clippy/tests/ui/forget_ref.stderr b/src/tools/clippy/tests/ui/forget_ref.stderr
deleted file mode 100644
index 011cdefc665..00000000000
--- a/src/tools/clippy/tests/ui/forget_ref.stderr
+++ /dev/null
@@ -1,111 +0,0 @@
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
-  --> $DIR/forget_ref.rs:11:5
-   |
-LL |     forget(&SomeStruct);
-   |     ^^^^^^^^^^^^^^^^^^^
-   |
-note: argument has type `&SomeStruct`
-  --> $DIR/forget_ref.rs:11:12
-   |
-LL |     forget(&SomeStruct);
-   |            ^^^^^^^^^^^
-   = note: `-D clippy::forget-ref` implied by `-D warnings`
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
-  --> $DIR/forget_ref.rs:14:5
-   |
-LL |     forget(&owned);
-   |     ^^^^^^^^^^^^^^
-   |
-note: argument has type `&SomeStruct`
-  --> $DIR/forget_ref.rs:14:12
-   |
-LL |     forget(&owned);
-   |            ^^^^^^
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
-  --> $DIR/forget_ref.rs:15:5
-   |
-LL |     forget(&&owned);
-   |     ^^^^^^^^^^^^^^^
-   |
-note: argument has type `&&SomeStruct`
-  --> $DIR/forget_ref.rs:15:12
-   |
-LL |     forget(&&owned);
-   |            ^^^^^^^
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
-  --> $DIR/forget_ref.rs:16:5
-   |
-LL |     forget(&mut owned);
-   |     ^^^^^^^^^^^^^^^^^^
-   |
-note: argument has type `&mut SomeStruct`
-  --> $DIR/forget_ref.rs:16:12
-   |
-LL |     forget(&mut owned);
-   |            ^^^^^^^^^^
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
-  --> $DIR/forget_ref.rs:20:5
-   |
-LL |     forget(&*reference1);
-   |     ^^^^^^^^^^^^^^^^^^^^
-   |
-note: argument has type `&SomeStruct`
-  --> $DIR/forget_ref.rs:20:12
-   |
-LL |     forget(&*reference1);
-   |            ^^^^^^^^^^^^
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
-  --> $DIR/forget_ref.rs:23:5
-   |
-LL |     forget(reference2);
-   |     ^^^^^^^^^^^^^^^^^^
-   |
-note: argument has type `&mut SomeStruct`
-  --> $DIR/forget_ref.rs:23:12
-   |
-LL |     forget(reference2);
-   |            ^^^^^^^^^^
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
-  --> $DIR/forget_ref.rs:26:5
-   |
-LL |     forget(reference3);
-   |     ^^^^^^^^^^^^^^^^^^
-   |
-note: argument has type `&SomeStruct`
-  --> $DIR/forget_ref.rs:26:12
-   |
-LL |     forget(reference3);
-   |            ^^^^^^^^^^
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
-  --> $DIR/forget_ref.rs:31:5
-   |
-LL |     forget(&val);
-   |     ^^^^^^^^^^^^
-   |
-note: argument has type `&T`
-  --> $DIR/forget_ref.rs:31:12
-   |
-LL |     forget(&val);
-   |            ^^^^
-
-error: calls to `std::mem::forget` with a reference instead of an owned value. Forgetting a reference does nothing
-  --> $DIR/forget_ref.rs:39:5
-   |
-LL |     std::mem::forget(&SomeStruct);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: argument has type `&SomeStruct`
-  --> $DIR/forget_ref.rs:39:22
-   |
-LL |     std::mem::forget(&SomeStruct);
-   |                      ^^^^^^^^^^^
-
-error: aborting due to 9 previous errors
-
diff --git a/src/tools/clippy/tests/ui/mem_forget.rs b/src/tools/clippy/tests/ui/mem_forget.rs
index e5b35c098a2..5137448a6d4 100644
--- a/src/tools/clippy/tests/ui/mem_forget.rs
+++ b/src/tools/clippy/tests/ui/mem_forget.rs
@@ -5,7 +5,7 @@ use std::mem as memstuff;
 use std::mem::forget as forgetSomething;
 
 #[warn(clippy::mem_forget)]
-#[allow(clippy::forget_copy)]
+#[allow(forget_copy)]
 fn main() {
     let five: i32 = 5;
     forgetSomething(five);
diff --git a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
index 73ef35c8c36..f28153e56b0 100644
--- a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
+++ b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
@@ -2,7 +2,7 @@
 #![allow(unused)]
 #![allow(deref_nullptr)]
 #![allow(clippy::unnecessary_operation)]
-#![allow(clippy::drop_copy)]
+#![allow(drop_copy)]
 #![warn(clippy::multiple_unsafe_ops_per_block)]
 
 extern crate proc_macros;
diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed
index 42a59f6d43d..9036f892612 100644
--- a/src/tools/clippy/tests/ui/rename.fixed
+++ b/src/tools/clippy/tests/ui/rename.fixed
@@ -29,7 +29,11 @@
 #![allow(clippy::invisible_characters)]
 #![allow(suspicious_double_ref_op)]
 #![allow(drop_bounds)]
+#![allow(drop_copy)]
+#![allow(drop_ref)]
 #![allow(for_loops_over_fallibles)]
+#![allow(forget_copy)]
+#![allow(forget_ref)]
 #![allow(array_into_iter)]
 #![allow(invalid_atomic_ordering)]
 #![allow(invalid_value)]
@@ -71,9 +75,13 @@
 #![warn(clippy::invisible_characters)]
 #![warn(suspicious_double_ref_op)]
 #![warn(drop_bounds)]
+#![warn(drop_copy)]
+#![warn(drop_ref)]
 #![warn(for_loops_over_fallibles)]
 #![warn(for_loops_over_fallibles)]
 #![warn(for_loops_over_fallibles)]
+#![warn(forget_copy)]
+#![warn(forget_ref)]
 #![warn(array_into_iter)]
 #![warn(invalid_atomic_ordering)]
 #![warn(invalid_value)]
diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs
index 4d173e8cbbf..43cabe810f3 100644
--- a/src/tools/clippy/tests/ui/rename.rs
+++ b/src/tools/clippy/tests/ui/rename.rs
@@ -29,7 +29,11 @@
 #![allow(clippy::invisible_characters)]
 #![allow(suspicious_double_ref_op)]
 #![allow(drop_bounds)]
+#![allow(drop_copy)]
+#![allow(drop_ref)]
 #![allow(for_loops_over_fallibles)]
+#![allow(forget_copy)]
+#![allow(forget_ref)]
 #![allow(array_into_iter)]
 #![allow(invalid_atomic_ordering)]
 #![allow(invalid_value)]
@@ -71,9 +75,13 @@
 #![warn(clippy::zero_width_space)]
 #![warn(clippy::clone_double_ref)]
 #![warn(clippy::drop_bounds)]
+#![warn(clippy::drop_copy)]
+#![warn(clippy::drop_ref)]
 #![warn(clippy::for_loop_over_option)]
 #![warn(clippy::for_loop_over_result)]
 #![warn(clippy::for_loops_over_fallibles)]
+#![warn(clippy::forget_copy)]
+#![warn(clippy::forget_ref)]
 #![warn(clippy::into_iter_on_array)]
 #![warn(clippy::invalid_atomic_ordering)]
 #![warn(clippy::invalid_ref)]
diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr
index 0da4ed7520c..1ad7cf412c8 100644
--- a/src/tools/clippy/tests/ui/rename.stderr
+++ b/src/tools/clippy/tests/ui/rename.stderr
@@ -1,5 +1,5 @@
 error: lint `clippy::almost_complete_letter_range` has been renamed to `clippy::almost_complete_range`
-  --> $DIR/rename.rs:44:9
+  --> $DIR/rename.rs:48:9
    |
 LL | #![warn(clippy::almost_complete_letter_range)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::almost_complete_range`
@@ -7,256 +7,280 @@ LL | #![warn(clippy::almost_complete_letter_range)]
    = note: `-D renamed-and-removed-lints` implied by `-D warnings`
 
 error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_names`
-  --> $DIR/rename.rs:45:9
+  --> $DIR/rename.rs:49:9
    |
 LL | #![warn(clippy::blacklisted_name)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names`
 
 error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions`
-  --> $DIR/rename.rs:46:9
+  --> $DIR/rename.rs:50:9
    |
 LL | #![warn(clippy::block_in_if_condition_expr)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
 
 error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions`
-  --> $DIR/rename.rs:47:9
+  --> $DIR/rename.rs:51:9
    |
 LL | #![warn(clippy::block_in_if_condition_stmt)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
 
 error: lint `clippy::box_vec` has been renamed to `clippy::box_collection`
-  --> $DIR/rename.rs:48:9
+  --> $DIR/rename.rs:52:9
    |
 LL | #![warn(clippy::box_vec)]
    |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection`
 
 error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`
-  --> $DIR/rename.rs:49:9
+  --> $DIR/rename.rs:53:9
    |
 LL | #![warn(clippy::const_static_lifetime)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes`
 
 error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity`
-  --> $DIR/rename.rs:50:9
+  --> $DIR/rename.rs:54:9
    |
 LL | #![warn(clippy::cyclomatic_complexity)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity`
 
 error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq`
-  --> $DIR/rename.rs:51:9
+  --> $DIR/rename.rs:55:9
    |
 LL | #![warn(clippy::derive_hash_xor_eq)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq`
 
 error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods`
-  --> $DIR/rename.rs:52:9
+  --> $DIR/rename.rs:56:9
    |
 LL | #![warn(clippy::disallowed_method)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods`
 
 error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types`
-  --> $DIR/rename.rs:53:9
+  --> $DIR/rename.rs:57:9
    |
 LL | #![warn(clippy::disallowed_type)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types`
 
 error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression`
-  --> $DIR/rename.rs:54:9
+  --> $DIR/rename.rs:58:9
    |
 LL | #![warn(clippy::eval_order_dependence)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression`
 
 error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
-  --> $DIR/rename.rs:55:9
+  --> $DIR/rename.rs:59:9
    |
 LL | #![warn(clippy::identity_conversion)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion`
 
 error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok`
-  --> $DIR/rename.rs:56:9
+  --> $DIR/rename.rs:60:9
    |
 LL | #![warn(clippy::if_let_some_result)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok`
 
 error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr`
-  --> $DIR/rename.rs:57:9
+  --> $DIR/rename.rs:61:9
    |
 LL | #![warn(clippy::logic_bug)]
    |         ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr`
 
 error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`
-  --> $DIR/rename.rs:58:9
+  --> $DIR/rename.rs:62:9
    |
 LL | #![warn(clippy::new_without_default_derive)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`
 
 error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map`
-  --> $DIR/rename.rs:59:9
+  --> $DIR/rename.rs:63:9
    |
 LL | #![warn(clippy::option_and_then_some)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map`
 
 error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used`
-  --> $DIR/rename.rs:60:9
+  --> $DIR/rename.rs:64:9
    |
 LL | #![warn(clippy::option_expect_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
 
 error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or`
-  --> $DIR/rename.rs:61:9
+  --> $DIR/rename.rs:65:9
    |
 LL | #![warn(clippy::option_map_unwrap_or)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
 
 error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
-  --> $DIR/rename.rs:62:9
+  --> $DIR/rename.rs:66:9
    |
 LL | #![warn(clippy::option_map_unwrap_or_else)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
 
 error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used`
-  --> $DIR/rename.rs:63:9
+  --> $DIR/rename.rs:67:9
    |
 LL | #![warn(clippy::option_unwrap_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
 
 error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow`
-  --> $DIR/rename.rs:64:9
+  --> $DIR/rename.rs:68:9
    |
 LL | #![warn(clippy::ref_in_deref)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow`
 
 error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used`
-  --> $DIR/rename.rs:65:9
+  --> $DIR/rename.rs:69:9
    |
 LL | #![warn(clippy::result_expect_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
 
 error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
-  --> $DIR/rename.rs:66:9
+  --> $DIR/rename.rs:70:9
    |
 LL | #![warn(clippy::result_map_unwrap_or_else)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
 
 error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used`
-  --> $DIR/rename.rs:67:9
+  --> $DIR/rename.rs:71:9
    |
 LL | #![warn(clippy::result_unwrap_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
 
 error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str`
-  --> $DIR/rename.rs:68:9
+  --> $DIR/rename.rs:72:9
    |
 LL | #![warn(clippy::single_char_push_str)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str`
 
 error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`
-  --> $DIR/rename.rs:69:9
+  --> $DIR/rename.rs:73:9
    |
 LL | #![warn(clippy::stutter)]
    |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`
 
 error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl`
-  --> $DIR/rename.rs:70:9
+  --> $DIR/rename.rs:74:9
    |
 LL | #![warn(clippy::to_string_in_display)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl`
 
 error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters`
-  --> $DIR/rename.rs:71:9
+  --> $DIR/rename.rs:75:9
    |
 LL | #![warn(clippy::zero_width_space)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
 
 error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op`
-  --> $DIR/rename.rs:72:9
+  --> $DIR/rename.rs:76:9
    |
 LL | #![warn(clippy::clone_double_ref)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op`
 
 error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
-  --> $DIR/rename.rs:73:9
+  --> $DIR/rename.rs:77:9
    |
 LL | #![warn(clippy::drop_bounds)]
    |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
 
+error: lint `clippy::drop_copy` has been renamed to `drop_copy`
+  --> $DIR/rename.rs:78:9
+   |
+LL | #![warn(clippy::drop_copy)]
+   |         ^^^^^^^^^^^^^^^^^ help: use the new name: `drop_copy`
+
+error: lint `clippy::drop_ref` has been renamed to `drop_ref`
+  --> $DIR/rename.rs:79:9
+   |
+LL | #![warn(clippy::drop_ref)]
+   |         ^^^^^^^^^^^^^^^^ help: use the new name: `drop_ref`
+
 error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles`
-  --> $DIR/rename.rs:74:9
+  --> $DIR/rename.rs:80:9
    |
 LL | #![warn(clippy::for_loop_over_option)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
 
 error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles`
-  --> $DIR/rename.rs:75:9
+  --> $DIR/rename.rs:81:9
    |
 LL | #![warn(clippy::for_loop_over_result)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
 
 error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles`
-  --> $DIR/rename.rs:76:9
+  --> $DIR/rename.rs:82:9
    |
 LL | #![warn(clippy::for_loops_over_fallibles)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
 
+error: lint `clippy::forget_copy` has been renamed to `forget_copy`
+  --> $DIR/rename.rs:83:9
+   |
+LL | #![warn(clippy::forget_copy)]
+   |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forget_copy`
+
+error: lint `clippy::forget_ref` has been renamed to `forget_ref`
+  --> $DIR/rename.rs:84:9
+   |
+LL | #![warn(clippy::forget_ref)]
+   |         ^^^^^^^^^^^^^^^^^^ help: use the new name: `forget_ref`
+
 error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
-  --> $DIR/rename.rs:77:9
+  --> $DIR/rename.rs:85:9
    |
 LL | #![warn(clippy::into_iter_on_array)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter`
 
 error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`
-  --> $DIR/rename.rs:78:9
+  --> $DIR/rename.rs:86:9
    |
 LL | #![warn(clippy::invalid_atomic_ordering)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`
 
 error: lint `clippy::invalid_ref` has been renamed to `invalid_value`
-  --> $DIR/rename.rs:79:9
+  --> $DIR/rename.rs:87:9
    |
 LL | #![warn(clippy::invalid_ref)]
    |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
 
 error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
-  --> $DIR/rename.rs:80:9
+  --> $DIR/rename.rs:88:9
    |
 LL | #![warn(clippy::let_underscore_drop)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop`
 
 error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
-  --> $DIR/rename.rs:81:9
+  --> $DIR/rename.rs:89:9
    |
 LL | #![warn(clippy::mem_discriminant_non_enum)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
 
 error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
-  --> $DIR/rename.rs:82:9
+  --> $DIR/rename.rs:90:9
    |
 LL | #![warn(clippy::panic_params)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
 
 error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally`
-  --> $DIR/rename.rs:83:9
+  --> $DIR/rename.rs:91:9
    |
 LL | #![warn(clippy::positional_named_format_parameters)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally`
 
 error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr`
-  --> $DIR/rename.rs:84:9
+  --> $DIR/rename.rs:92:9
    |
 LL | #![warn(clippy::temporary_cstring_as_ptr)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr`
 
 error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
-  --> $DIR/rename.rs:85:9
+  --> $DIR/rename.rs:93:9
    |
 LL | #![warn(clippy::unknown_clippy_lints)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
 
 error: lint `clippy::unused_label` has been renamed to `unused_labels`
-  --> $DIR/rename.rs:86:9
+  --> $DIR/rename.rs:94:9
    |
 LL | #![warn(clippy::unused_label)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
 
-error: aborting due to 43 previous errors
+error: aborting due to 47 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed b/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed
index 0c269d650c8..49c0e4dc7eb 100644
--- a/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed
+++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.fixed
@@ -10,7 +10,7 @@
 #[warn(clippy::unnecessary_cast)]
 #[warn(clippy::useless_transmute)]
 // Shouldn't suggest rustc lint name(`dead_code`)
-#[warn(clippy::drop_copy)]
+#[warn(clippy::eq_op)]
 // Shouldn't suggest removed/deprecated clippy lint name(`unused_collect`)
 #[warn(clippy::unused_self)]
 // Shouldn't suggest renamed clippy lint name(`const_static_lifetime`)
diff --git a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr
index 421bf5ffa9a..584c428932f 100644
--- a/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr
+++ b/src/tools/clippy/tests/ui/unknown_clippy_lints.stderr
@@ -34,7 +34,7 @@ error: unknown lint: `clippy::dead_cod`
   --> $DIR/unknown_clippy_lints.rs:13:8
    |
 LL | #[warn(clippy::dead_cod)]
-   |        ^^^^^^^^^^^^^^^^ help: did you mean: `clippy::drop_copy`
+   |        ^^^^^^^^^^^^^^^^ help: did you mean: `clippy::eq_op`
 
 error: unknown lint: `clippy::unused_colle`
   --> $DIR/unknown_clippy_lints.rs:15:8
diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs b/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs
index 70c51e671fe..bf4204c61fd 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_write2.rs
@@ -1,3 +1,5 @@
+#![allow(drop_ref)]
+
 fn main() {
     let target = &mut 42;
     let target2 = target as *mut _;
diff --git a/src/tools/miri/tests/fail/uninit_buffer.rs b/src/tools/miri/tests/fail/uninit_buffer.rs
index 8819c53a4f9..8a330058375 100644
--- a/src/tools/miri/tests/fail/uninit_buffer.rs
+++ b/src/tools/miri/tests/fail/uninit_buffer.rs
@@ -1,5 +1,7 @@
 //@error-in-other-file: memory is uninitialized at [0x4..0x10]
 
+#![allow(drop_copy)]
+
 use std::alloc::{alloc, dealloc, Layout};
 use std::slice::from_raw_parts;
 
diff --git a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs
index e788c079cb4..e4d9404c2ba 100644
--- a/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs
+++ b/src/tools/miri/tests/fail/uninit_buffer_with_provenance.rs
@@ -2,6 +2,8 @@
 //@normalize-stderr-test: "a[0-9]+" -> "ALLOC"
 #![feature(strict_provenance)]
 
+#![allow(drop_copy)]
+
 // Test printing allocations that contain single-byte provenance.
 
 use std::alloc::{alloc, dealloc, Layout};
diff --git a/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs b/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs
index ce3c8b7d5f1..9f743f0b566 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs
@@ -1,5 +1,8 @@
 //@compile-flags: -Zmiri-retag-fields
 // Checks that the test does not run forever (which relies on a fast path).
+
+#![allow(drop_copy)]
+
 fn main() {
     let array = [(); usize::MAX];
     drop(array); // Pass the array to a function, retagging its fields
diff --git a/tests/ui/associated-inherent-types/inference.rs b/tests/ui/associated-inherent-types/inference.rs
index 38179214fa1..7d6d26003f6 100644
--- a/tests/ui/associated-inherent-types/inference.rs
+++ b/tests/ui/associated-inherent-types/inference.rs
@@ -3,6 +3,7 @@
 
 #![feature(inherent_associated_types)]
 #![allow(incomplete_features)]
+#![allow(drop_copy)]
 
 use std::convert::identity;
 
diff --git a/tests/ui/async-await/multiple-lifetimes/partial-relation.rs b/tests/ui/async-await/multiple-lifetimes/partial-relation.rs
index 02b105999f5..7375cb6d3a0 100644
--- a/tests/ui/async-await/multiple-lifetimes/partial-relation.rs
+++ b/tests/ui/async-await/multiple-lifetimes/partial-relation.rs
@@ -4,7 +4,7 @@
 async fn lotsa_lifetimes<'a, 'b, 'c>(a: &'a u32, b: &'b u32, c: &'c u32) -> (&'a u32, &'b u32)
     where 'b: 'a
 {
-    drop((a, c));
+    let _ = (a, c);
     (b, b)
 }
 
diff --git a/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs b/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs
index 0229ca37a69..9163c8ed6fb 100644
--- a/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs
+++ b/tests/ui/borrowck/borrowck-closures-slice-patterns-ok.rs
@@ -1,6 +1,7 @@
 // Check that closure captures for slice patterns are inferred correctly
 
 #![allow(unused_variables)]
+#![allow(drop_ref)]
 
 // run-pass
 
diff --git a/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs b/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs
index dd6708582c1..a88b323e0bf 100644
--- a/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs
+++ b/tests/ui/borrowck/borrowck-field-sensitivity-rpass.rs
@@ -1,6 +1,7 @@
 // run-pass
 #![allow(unused_mut)]
 #![allow(unused_variables)]
+#![allow(drop_copy)]
 // pretty-expanded FIXME #23616
 
 struct A { a: isize, b: Box<isize> }
diff --git a/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs b/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs
index 1cf763f66fd..40c6bfeeb43 100644
--- a/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs
+++ b/tests/ui/borrowck/borrowck-use-mut-borrow-rpass.rs
@@ -1,6 +1,8 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
+#![allow(drop_copy)]
+
 struct A { a: isize, b: Box<isize> }
 
 fn field_copy_after_field_borrow() {
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs
index ff5d284614b..bc7295a0826 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs
+++ b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.rs
@@ -1,6 +1,7 @@
 // run-pass
 
 #![warn(rust_2021_incompatible_closure_captures)]
+#![allow(drop_ref, drop_copy)]
 
 fn main() {
     if let a = "" {
diff --git a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr
index 36a80e694e8..2609e2951ec 100644
--- a/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr
+++ b/tests/ui/closures/2229_closure_analysis/migrations/issue-78720.stderr
@@ -1,5 +1,5 @@
 warning: irrefutable `if let` pattern
-  --> $DIR/issue-78720.rs:6:8
+  --> $DIR/issue-78720.rs:7:8
    |
 LL |     if let a = "" {
    |        ^^^^^^^^^^
diff --git a/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs b/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs
index 033fd6f1775..0f15f664e75 100644
--- a/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs
+++ b/tests/ui/closures/2229_closure_analysis/optimization/edge_case_run_pass.rs
@@ -3,6 +3,7 @@
 
 #![allow(unused)]
 #![allow(dead_code)]
+#![allow(drop_ref)]
 
 struct Int(i32);
 struct B<'a>(&'a i32);
diff --git a/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs b/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs
index 477fdd613f5..a097424a021 100644
--- a/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs
+++ b/tests/ui/closures/2229_closure_analysis/run_pass/drop_then_use_fake_reads.rs
@@ -1,6 +1,8 @@
 // edition:2021
 // check-pass
+
 #![feature(rustc_attrs)]
+#![allow(drop_ref)]
 
 fn main() {
     let mut x = 1;
diff --git a/tests/ui/consts/const_forget.rs b/tests/ui/consts/const_forget.rs
index ec7dde8c9ec..acdd6a54cf4 100644
--- a/tests/ui/consts/const_forget.rs
+++ b/tests/ui/consts/const_forget.rs
@@ -1,5 +1,7 @@
 // check-pass
 
+#![allow(forget_copy)]
+
 use std::mem::forget;
 
 const _: () = forget(0i32);
diff --git a/tests/ui/consts/issue-104155.rs b/tests/ui/consts/issue-104155.rs
index 1cc8f81b0d2..b3821f467b6 100644
--- a/tests/ui/consts/issue-104155.rs
+++ b/tests/ui/consts/issue-104155.rs
@@ -1,4 +1,7 @@
 // check-pass
+
+#![allow(forget_copy)]
+
 const _: () = core::mem::forget(Box::<u32>::default);
 const _: () = core::mem::forget(|| Box::<u32>::default());
 
diff --git a/tests/ui/crate-leading-sep.rs b/tests/ui/crate-leading-sep.rs
index ca5905fab41..8d1d0b4fcdf 100644
--- a/tests/ui/crate-leading-sep.rs
+++ b/tests/ui/crate-leading-sep.rs
@@ -1,6 +1,8 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
+#![allow(drop_copy)]
+
 fn main() {
     use ::std::mem;
     mem::drop(2_usize);
diff --git a/tests/ui/drop/repeat-drop.rs b/tests/ui/drop/repeat-drop.rs
index 8fd46ecaf44..659d35db657 100644
--- a/tests/ui/drop/repeat-drop.rs
+++ b/tests/ui/drop/repeat-drop.rs
@@ -1,6 +1,8 @@
 // run-pass
 // needs-unwind
 
+#![allow(drop_ref, drop_copy)]
+
 static mut CHECK: usize = 0;
 
 struct DropChecker(usize);
diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed b/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed
index 47c4c9f67b6..0bc4feed329 100644
--- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed
+++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed
@@ -1,4 +1,7 @@
 // run-rustfix
+
+#![allow(drop_ref)]
+
 struct Foo {
     x: isize
 }
diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs b/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs
index c698de50c75..26ae6698d66 100644
--- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs
+++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs
@@ -1,4 +1,7 @@
 // run-rustfix
+
+#![allow(drop_ref)]
+
 struct Foo {
     x: isize
 }
diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr b/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr
index 7f5106eb57e..c7067117349 100644
--- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr
+++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr
@@ -1,5 +1,5 @@
 error[E0040]: explicit use of destructor method
-  --> $DIR/explicit-call-to-supertrait-dtor.rs:19:14
+  --> $DIR/explicit-call-to-supertrait-dtor.rs:22:14
    |
 LL |         self.drop();
    |         -----^^^^--
diff --git a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs
index 0680d234403..dce94c9eab2 100644
--- a/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs
+++ b/tests/ui/feature-gates/feature-gate-unsafe_pin_internals.rs
@@ -13,5 +13,4 @@ fn non_unsafe_pin_new_unchecked<T>(pointer: &mut T) -> Pin<&mut T> {
 fn main() {
     let mut self_referential = PhantomPinned;
     let _: Pin<&mut PhantomPinned> = non_unsafe_pin_new_unchecked(&mut self_referential);
-    core::mem::forget(self_referential); // move and disable drop glue!
 }
diff --git a/tests/ui/generator/drop-env.rs b/tests/ui/generator/drop-env.rs
index 66dfb8c2c09..cb46953dac3 100644
--- a/tests/ui/generator/drop-env.rs
+++ b/tests/ui/generator/drop-env.rs
@@ -4,6 +4,7 @@
 //[nomiropt]compile-flags: -Z mir-opt-level=0
 
 #![feature(generators, generator_trait)]
+#![allow(drop_copy)]
 
 use std::ops::Generator;
 use std::pin::Pin;
diff --git a/tests/ui/generator/issue-57017.no_drop_tracking.stderr b/tests/ui/generator/issue-57017.no_drop_tracking.stderr
index 06d2d23b9ef..f7b8e198cc4 100644
--- a/tests/ui/generator/issue-57017.no_drop_tracking.stderr
+++ b/tests/ui/generator/issue-57017.no_drop_tracking.stderr
@@ -1,5 +1,5 @@
 error: generator cannot be sent between threads safely
-  --> $DIR/issue-57017.rs:31:25
+  --> $DIR/issue-57017.rs:32:25
    |
 LL |               assert_send(g);
    |                           ^ generator is not `Send`
@@ -15,7 +15,7 @@ LL | |     );
    |
    = help: the trait `Sync` is not implemented for `copy::unsync::Client`
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-57017.rs:29:28
+  --> $DIR/issue-57017.rs:30:28
    |
 LL |               let g = move || match drop(&$name::unsync::Client::default()) {
    |                                          --------------------------------- has type `&copy::unsync::Client` which is not `Send`
@@ -33,14 +33,14 @@ LL | |         }
 LL | |     );
    | |_____- in this macro invocation
 note: required by a bound in `assert_send`
-  --> $DIR/issue-57017.rs:51:19
+  --> $DIR/issue-57017.rs:52:19
    |
 LL | fn assert_send<T: Send>(_thing: T) {}
    |                   ^^^^ required by this bound in `assert_send`
    = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: generator cannot be sent between threads safely
-  --> $DIR/issue-57017.rs:43:25
+  --> $DIR/issue-57017.rs:44:25
    |
 LL |               assert_send(g);
    |                           ^ generator is not `Send`
@@ -54,9 +54,9 @@ LL | |         }
 LL | |     );
    | |_____- in this macro invocation
    |
-   = help: within `[generator@$DIR/issue-57017.rs:40:21: 40:28]`, the trait `Send` is not implemented for `copy::unsend::Client`
+   = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `copy::unsend::Client`
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-57017.rs:41:28
+  --> $DIR/issue-57017.rs:42:28
    |
 LL |               let g = move || match drop($name::unsend::Client::default()) {
    |                                          -------------------------------- has type `copy::unsend::Client` which is not `Send`
@@ -74,14 +74,14 @@ LL | |         }
 LL | |     );
    | |_____- in this macro invocation
 note: required by a bound in `assert_send`
-  --> $DIR/issue-57017.rs:51:19
+  --> $DIR/issue-57017.rs:52:19
    |
 LL | fn assert_send<T: Send>(_thing: T) {}
    |                   ^^^^ required by this bound in `assert_send`
    = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: generator cannot be sent between threads safely
-  --> $DIR/issue-57017.rs:31:25
+  --> $DIR/issue-57017.rs:32:25
    |
 LL |               assert_send(g);
    |                           ^ generator is not `Send`
@@ -97,7 +97,7 @@ LL | |     );
    |
    = help: the trait `Sync` is not implemented for `derived_drop::unsync::Client`
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-57017.rs:29:28
+  --> $DIR/issue-57017.rs:30:28
    |
 LL |               let g = move || match drop(&$name::unsync::Client::default()) {
    |                                          --------------------------------- has type `&derived_drop::unsync::Client` which is not `Send`
@@ -115,14 +115,14 @@ LL | |         }
 LL | |     );
    | |_____- in this macro invocation
 note: required by a bound in `assert_send`
-  --> $DIR/issue-57017.rs:51:19
+  --> $DIR/issue-57017.rs:52:19
    |
 LL | fn assert_send<T: Send>(_thing: T) {}
    |                   ^^^^ required by this bound in `assert_send`
    = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: generator cannot be sent between threads safely
-  --> $DIR/issue-57017.rs:43:25
+  --> $DIR/issue-57017.rs:44:25
    |
 LL |               assert_send(g);
    |                           ^ generator is not `Send`
@@ -136,9 +136,9 @@ LL | |         }
 LL | |     );
    | |_____- in this macro invocation
    |
-   = help: within `[generator@$DIR/issue-57017.rs:40:21: 40:28]`, the trait `Send` is not implemented for `derived_drop::unsend::Client`
+   = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `derived_drop::unsend::Client`
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-57017.rs:41:28
+  --> $DIR/issue-57017.rs:42:28
    |
 LL |               let g = move || match drop($name::unsend::Client::default()) {
    |                                          -------------------------------- has type `derived_drop::unsend::Client` which is not `Send`
@@ -156,14 +156,14 @@ LL | |         }
 LL | |     );
    | |_____- in this macro invocation
 note: required by a bound in `assert_send`
-  --> $DIR/issue-57017.rs:51:19
+  --> $DIR/issue-57017.rs:52:19
    |
 LL | fn assert_send<T: Send>(_thing: T) {}
    |                   ^^^^ required by this bound in `assert_send`
    = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: generator cannot be sent between threads safely
-  --> $DIR/issue-57017.rs:31:25
+  --> $DIR/issue-57017.rs:32:25
    |
 LL |               assert_send(g);
    |                           ^ generator is not `Send`
@@ -179,7 +179,7 @@ LL | |     );
    |
    = help: the trait `Sync` is not implemented for `significant_drop::unsync::Client`
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-57017.rs:29:28
+  --> $DIR/issue-57017.rs:30:28
    |
 LL |               let g = move || match drop(&$name::unsync::Client::default()) {
    |                                          --------------------------------- has type `&significant_drop::unsync::Client` which is not `Send`
@@ -197,14 +197,14 @@ LL | |         }
 LL | |     );
    | |_____- in this macro invocation
 note: required by a bound in `assert_send`
-  --> $DIR/issue-57017.rs:51:19
+  --> $DIR/issue-57017.rs:52:19
    |
 LL | fn assert_send<T: Send>(_thing: T) {}
    |                   ^^^^ required by this bound in `assert_send`
    = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: generator cannot be sent between threads safely
-  --> $DIR/issue-57017.rs:43:25
+  --> $DIR/issue-57017.rs:44:25
    |
 LL |               assert_send(g);
    |                           ^ generator is not `Send`
@@ -218,9 +218,9 @@ LL | |         }
 LL | |     );
    | |_____- in this macro invocation
    |
-   = help: within `[generator@$DIR/issue-57017.rs:40:21: 40:28]`, the trait `Send` is not implemented for `significant_drop::unsend::Client`
+   = help: within `[generator@$DIR/issue-57017.rs:41:21: 41:28]`, the trait `Send` is not implemented for `significant_drop::unsend::Client`
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-57017.rs:41:28
+  --> $DIR/issue-57017.rs:42:28
    |
 LL |               let g = move || match drop($name::unsend::Client::default()) {
    |                                          -------------------------------- has type `significant_drop::unsend::Client` which is not `Send`
@@ -238,7 +238,7 @@ LL | |         }
 LL | |     );
    | |_____- in this macro invocation
 note: required by a bound in `assert_send`
-  --> $DIR/issue-57017.rs:51:19
+  --> $DIR/issue-57017.rs:52:19
    |
 LL | fn assert_send<T: Send>(_thing: T) {}
    |                   ^^^^ required by this bound in `assert_send`
diff --git a/tests/ui/generator/issue-57017.rs b/tests/ui/generator/issue-57017.rs
index 03b00ac99ad..918d233bf4e 100644
--- a/tests/ui/generator/issue-57017.rs
+++ b/tests/ui/generator/issue-57017.rs
@@ -5,6 +5,7 @@
 // [drop_tracking_mir] build-pass
 
 #![feature(generators, negative_impls)]
+#![allow(drop_ref, drop_copy)]
 
 macro_rules! type_combinations {
     (
diff --git a/tests/ui/generator/non-static-is-unpin.rs b/tests/ui/generator/non-static-is-unpin.rs
index 17e23f5bcd2..adba800e25a 100644
--- a/tests/ui/generator/non-static-is-unpin.rs
+++ b/tests/ui/generator/non-static-is-unpin.rs
@@ -3,6 +3,7 @@
 // run-pass
 
 #![feature(generators, generator_trait)]
+#![allow(drop_copy)]
 
 use std::marker::{PhantomPinned, Unpin};
 
diff --git a/tests/ui/generator/resume-arg-size.rs b/tests/ui/generator/resume-arg-size.rs
index b93dc54f7a9..19618f8d0aa 100644
--- a/tests/ui/generator/resume-arg-size.rs
+++ b/tests/ui/generator/resume-arg-size.rs
@@ -1,4 +1,5 @@
 #![feature(generators)]
+#![allow(drop_copy)]
 
 // run-pass
 
diff --git a/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs b/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs
index cf65de2bc23..214267372bf 100644
--- a/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs
+++ b/tests/ui/hygiene/stdlib-prelude-from-opaque-late.rs
@@ -1,6 +1,7 @@
 // check-pass
 
 #![feature(decl_macro)]
+#![allow(drop_copy)]
 
 macro mac() {
     mod m {
diff --git a/tests/ui/illegal-ufcs-drop.fixed b/tests/ui/illegal-ufcs-drop.fixed
index d73b391be06..8783682dec4 100644
--- a/tests/ui/illegal-ufcs-drop.fixed
+++ b/tests/ui/illegal-ufcs-drop.fixed
@@ -1,4 +1,7 @@
 // run-rustfix
+
+#![allow(drop_ref)]
+
 struct Foo;
 
 impl Drop for Foo {
diff --git a/tests/ui/illegal-ufcs-drop.rs b/tests/ui/illegal-ufcs-drop.rs
index 11411f55494..29774306ec6 100644
--- a/tests/ui/illegal-ufcs-drop.rs
+++ b/tests/ui/illegal-ufcs-drop.rs
@@ -1,4 +1,7 @@
 // run-rustfix
+
+#![allow(drop_ref)]
+
 struct Foo;
 
 impl Drop for Foo {
diff --git a/tests/ui/illegal-ufcs-drop.stderr b/tests/ui/illegal-ufcs-drop.stderr
index 91f47d5e456..7a5c0612c07 100644
--- a/tests/ui/illegal-ufcs-drop.stderr
+++ b/tests/ui/illegal-ufcs-drop.stderr
@@ -1,5 +1,5 @@
 error[E0040]: explicit use of destructor method
-  --> $DIR/illegal-ufcs-drop.rs:9:5
+  --> $DIR/illegal-ufcs-drop.rs:12:5
    |
 LL |     Drop::drop(&mut Foo)
    |     ^^^^^^^^^^
diff --git a/tests/ui/lint/drop_copy.rs b/tests/ui/lint/drop_copy.rs
new file mode 100644
index 00000000000..0adcd34505f
--- /dev/null
+++ b/tests/ui/lint/drop_copy.rs
@@ -0,0 +1,79 @@
+// check-pass
+
+#![warn(drop_copy)]
+
+use std::mem::drop;
+use std::vec::Vec;
+
+#[derive(Copy, Clone)]
+struct SomeStruct;
+
+struct AnotherStruct {
+    x: u8,
+    y: u8,
+    z: Vec<u8>,
+}
+
+impl Clone for AnotherStruct {
+    fn clone(&self) -> AnotherStruct {
+        AnotherStruct {
+            x: self.x,
+            y: self.y,
+            z: self.z.clone(),
+        }
+    }
+}
+
+fn main() {
+    let s1 = SomeStruct {};
+    let s2 = s1;
+    let s3 = &s1;
+    let mut s4 = s1;
+    let ref s5 = s1;
+
+    drop(s1); //~ WARN calls to `std::mem::drop`
+    drop(s2); //~ WARN calls to `std::mem::drop`
+    drop(s3); //~ WARN calls to `std::mem::drop`
+    drop(s4); //~ WARN calls to `std::mem::drop`
+    drop(s5); //~ WARN calls to `std::mem::drop`
+
+    let a1 = AnotherStruct {
+        x: 255,
+        y: 0,
+        z: vec![1, 2, 3],
+    };
+    let a2 = &a1;
+    let mut a3 = a1.clone();
+    let ref a4 = a1;
+    let a5 = a1.clone();
+
+    drop(a2); //~ WARN calls to `std::mem::drop`
+    drop(a3);
+    drop(a4); //~ WARN calls to `std::mem::drop`
+    drop(a5);
+}
+
+#[allow(unused)]
+#[allow(clippy::unit_cmp)]
+fn issue9482(x: u8) {
+    fn println_and<T>(t: T) -> T {
+        println!("foo");
+        t
+    }
+
+    match x {
+        // Don't lint (copy type), we only care about side-effects
+        0 => drop(println_and(12)),
+        // Don't lint (no copy type), we only care about side-effects
+        1 => drop(println_and(String::new())),
+        2 => {
+            // Lint, even if we only care about the side-effect, it's already in a block
+            drop(println_and(13)); //~ WARN calls to `std::mem::drop`
+        },
+         // Lint, idiomatic use is only in body of `Arm`
+        3 if drop(println_and(14)) == () => (), //~ WARN calls to `std::mem::drop`
+        // Lint, not a fn/method call
+        4 => drop(2),//~ WARN calls to `std::mem::drop`
+        _ => (),
+    }
+}
diff --git a/tests/ui/lint/drop_copy.stderr b/tests/ui/lint/drop_copy.stderr
new file mode 100644
index 00000000000..db8e89ad295
--- /dev/null
+++ b/tests/ui/lint/drop_copy.stderr
@@ -0,0 +1,108 @@
+warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
+  --> $DIR/drop_copy.rs:34:5
+   |
+LL |     drop(s1);
+   |     ^^^^^--^
+   |          |
+   |          argument has type `SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+note: the lint level is defined here
+  --> $DIR/drop_copy.rs:3:9
+   |
+LL | #![warn(drop_copy)]
+   |         ^^^^^^^^^
+
+warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
+  --> $DIR/drop_copy.rs:35:5
+   |
+LL |     drop(s2);
+   |     ^^^^^--^
+   |          |
+   |          argument has type `SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_copy.rs:36:5
+   |
+LL |     drop(s3);
+   |     ^^^^^--^
+   |          |
+   |          argument has type `&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+   = note: `#[warn(drop_ref)]` on by default
+
+warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
+  --> $DIR/drop_copy.rs:37:5
+   |
+LL |     drop(s4);
+   |     ^^^^^--^
+   |          |
+   |          argument has type `SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_copy.rs:38:5
+   |
+LL |     drop(s5);
+   |     ^^^^^--^
+   |          |
+   |          argument has type `&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_copy.rs:50:5
+   |
+LL |     drop(a2);
+   |     ^^^^^--^
+   |          |
+   |          argument has type `&AnotherStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_copy.rs:52:5
+   |
+LL |     drop(a4);
+   |     ^^^^^--^
+   |          |
+   |          argument has type `&AnotherStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
+  --> $DIR/drop_copy.rs:71:13
+   |
+LL |             drop(println_and(13));
+   |             ^^^^^---------------^
+   |                  |
+   |                  argument has type `i32`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
+  --> $DIR/drop_copy.rs:74:14
+   |
+LL |         3 if drop(println_and(14)) == () => (),
+   |              ^^^^^---------------^
+   |                   |
+   |                   argument has type `i32`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a value that implements `Copy` does nothing
+  --> $DIR/drop_copy.rs:76:14
+   |
+LL |         4 => drop(2),
+   |              ^^^^^-^
+   |                   |
+   |                   argument has type `i32`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: 10 warnings emitted
+
diff --git a/src/tools/clippy/tests/ui/drop_ref.rs b/tests/ui/lint/drop_ref.rs
index 10044e65f11..db4f7569f6f 100644
--- a/src/tools/clippy/tests/ui/drop_ref.rs
+++ b/tests/ui/lint/drop_ref.rs
@@ -1,42 +1,39 @@
-#![warn(clippy::drop_ref)]
-#![allow(clippy::toplevel_ref_arg)]
-#![allow(clippy::map_err_ignore)]
-#![allow(clippy::unnecessary_wraps, clippy::drop_non_drop)]
+// check-pass
 
-use std::mem::drop;
+#![warn(drop_ref)]
 
 struct SomeStruct;
 
 fn main() {
-    drop(&SomeStruct);
+    drop(&SomeStruct); //~ WARN calls to `std::mem::drop`
 
     let mut owned1 = SomeStruct;
-    drop(&owned1);
-    drop(&&owned1);
-    drop(&mut owned1);
-    drop(owned1); //OK
+    drop(&owned1); //~ WARN calls to `std::mem::drop`
+    drop(&&owned1); //~ WARN calls to `std::mem::drop`
+    drop(&mut owned1); //~ WARN calls to `std::mem::drop`
+    drop(owned1);
 
     let reference1 = &SomeStruct;
-    drop(reference1);
+    drop(reference1); //~ WARN calls to `std::mem::drop`
 
     let reference2 = &mut SomeStruct;
-    drop(reference2);
+    drop(reference2); //~ WARN calls to `std::mem::drop`
 
     let ref reference3 = SomeStruct;
-    drop(reference3);
+    drop(reference3); //~ WARN calls to `std::mem::drop`
 }
 
 #[allow(dead_code)]
 fn test_generic_fn_drop<T>(val: T) {
-    drop(&val);
-    drop(val); //OK
+    drop(&val); //~ WARN calls to `std::mem::drop`
+    drop(val);
 }
 
 #[allow(dead_code)]
 fn test_similarly_named_function() {
     fn drop<T>(_val: T) {}
     drop(&SomeStruct); //OK; call to unrelated function which happens to have the same name
-    std::mem::drop(&SomeStruct);
+    std::mem::drop(&SomeStruct); //~ WARN calls to `std::mem::drop`
 }
 
 #[derive(Copy, Clone)]
@@ -77,21 +74,26 @@ fn test_owl_result_2() -> Result<u8, ()> {
 #[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.
+    // 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
+        // Don't lint (copy type), we only care about side-effects
+        0 => drop(println_and(&12)),
+        // Don't lint (no copy type), we only care about side-effects
+        1 => drop(println_and(&String::new())),
         2 => {
-            drop(println_and(&13)); // Lint, even if we only care about the side-effect, it's already in a block
+            // Lint, even if we only care about the side-effect, it's already in a block
+            drop(println_and(&13)); //~ WARN calls to `std::mem::drop`
         },
-        3 if drop(println_and(&14)) == () => (), // Lint, idiomatic use is only in body of `Arm`
-        4 => drop(&2),                           // Lint, not a fn/method call
+        // Lint, idiomatic use is only in body of `Arm`
+        3 if drop(println_and(&14)) == () => (), //~ WARN calls to `std::mem::drop`
+         // Lint, not a fn/method call
+        4 => drop(&2), //~ WARN calls to `std::mem::drop`
         _ => (),
     }
 }
diff --git a/tests/ui/lint/drop_ref.stderr b/tests/ui/lint/drop_ref.stderr
new file mode 100644
index 00000000000..04c988fe99d
--- /dev/null
+++ b/tests/ui/lint/drop_ref.stderr
@@ -0,0 +1,127 @@
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_ref.rs:8:5
+   |
+LL |     drop(&SomeStruct);
+   |     ^^^^^-----------^
+   |          |
+   |          argument has type `&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+note: the lint level is defined here
+  --> $DIR/drop_ref.rs:3:9
+   |
+LL | #![warn(drop_ref)]
+   |         ^^^^^^^^
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_ref.rs:11:5
+   |
+LL |     drop(&owned1);
+   |     ^^^^^-------^
+   |          |
+   |          argument has type `&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_ref.rs:12:5
+   |
+LL |     drop(&&owned1);
+   |     ^^^^^--------^
+   |          |
+   |          argument has type `&&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_ref.rs:13:5
+   |
+LL |     drop(&mut owned1);
+   |     ^^^^^-----------^
+   |          |
+   |          argument has type `&mut SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_ref.rs:17:5
+   |
+LL |     drop(reference1);
+   |     ^^^^^----------^
+   |          |
+   |          argument has type `&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_ref.rs:20:5
+   |
+LL |     drop(reference2);
+   |     ^^^^^----------^
+   |          |
+   |          argument has type `&mut SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_ref.rs:23:5
+   |
+LL |     drop(reference3);
+   |     ^^^^^----------^
+   |          |
+   |          argument has type `&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_ref.rs:28:5
+   |
+LL |     drop(&val);
+   |     ^^^^^----^
+   |          |
+   |          argument has type `&T`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_ref.rs:36:5
+   |
+LL |     std::mem::drop(&SomeStruct);
+   |     ^^^^^^^^^^^^^^^-----------^
+   |                    |
+   |                    argument has type `&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_ref.rs:91:13
+   |
+LL |             drop(println_and(&13));
+   |             ^^^^^----------------^
+   |                  |
+   |                  argument has type `&i32`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_ref.rs:94:14
+   |
+LL |         3 if drop(println_and(&14)) == () => (),
+   |              ^^^^^----------------^
+   |                   |
+   |                   argument has type `&i32`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::drop` with a reference instead of an owned value does nothing
+  --> $DIR/drop_ref.rs:96:14
+   |
+LL |         4 => drop(&2),
+   |              ^^^^^--^
+   |                   |
+   |                   argument has type `&i32`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: 12 warnings emitted
+
diff --git a/tests/ui/lint/forget_copy.rs b/tests/ui/lint/forget_copy.rs
new file mode 100644
index 00000000000..a6b17b76971
--- /dev/null
+++ b/tests/ui/lint/forget_copy.rs
@@ -0,0 +1,56 @@
+// check-pass
+
+#![warn(forget_copy)]
+
+use std::mem::forget;
+use std::vec::Vec;
+
+#[derive(Copy, Clone)]
+struct SomeStruct;
+
+struct AnotherStruct {
+    x: u8,
+    y: u8,
+    z: Vec<u8>,
+}
+
+impl Clone for AnotherStruct {
+    fn clone(&self) -> AnotherStruct {
+        AnotherStruct {
+            x: self.x,
+            y: self.y,
+            z: self.z.clone(),
+        }
+    }
+}
+
+fn main() {
+    let s1 = SomeStruct {};
+    let s2 = s1;
+    let s3 = &s1;
+    let mut s4 = s1;
+    let ref s5 = s1;
+
+    forget(s1); //~ WARN calls to `std::mem::forget`
+    forget(s2); //~ WARN calls to `std::mem::forget`
+    forget(s3); //~ WARN calls to `std::mem::forget`
+    forget(s4); //~ WARN calls to `std::mem::forget`
+    forget(s5); //~ WARN calls to `std::mem::forget`
+
+    let a1 = AnotherStruct {
+        x: 255,
+        y: 0,
+        z: vec![1, 2, 3],
+    };
+    let a2 = &a1;
+    let mut a3 = a1.clone();
+    let ref a4 = a1;
+    let a5 = a1.clone();
+
+    forget(a2); //~ WARN calls to `std::mem::forget`
+    let a3 = &a1;
+    forget(a3); //~ WARN calls to `std::mem::forget`
+    forget(a4); //~ WARN calls to `std::mem::forget`
+    let a5 = a1.clone();
+    forget(a5);
+}
diff --git a/tests/ui/lint/forget_copy.stderr b/tests/ui/lint/forget_copy.stderr
new file mode 100644
index 00000000000..37bc8a8854e
--- /dev/null
+++ b/tests/ui/lint/forget_copy.stderr
@@ -0,0 +1,88 @@
+warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing
+  --> $DIR/forget_copy.rs:34:5
+   |
+LL |     forget(s1);
+   |     ^^^^^^^--^
+   |            |
+   |            argument has type `SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+note: the lint level is defined here
+  --> $DIR/forget_copy.rs:3:9
+   |
+LL | #![warn(forget_copy)]
+   |         ^^^^^^^^^^^
+
+warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing
+  --> $DIR/forget_copy.rs:35:5
+   |
+LL |     forget(s2);
+   |     ^^^^^^^--^
+   |            |
+   |            argument has type `SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+  --> $DIR/forget_copy.rs:36:5
+   |
+LL |     forget(s3);
+   |     ^^^^^^^--^
+   |            |
+   |            argument has type `&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+   = note: `#[warn(forget_ref)]` on by default
+
+warning: calls to `std::mem::forget` with a value that implements `Copy` does nothing
+  --> $DIR/forget_copy.rs:37:5
+   |
+LL |     forget(s4);
+   |     ^^^^^^^--^
+   |            |
+   |            argument has type `SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+  --> $DIR/forget_copy.rs:38:5
+   |
+LL |     forget(s5);
+   |     ^^^^^^^--^
+   |            |
+   |            argument has type `&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+  --> $DIR/forget_copy.rs:50:5
+   |
+LL |     forget(a2);
+   |     ^^^^^^^--^
+   |            |
+   |            argument has type `&AnotherStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+  --> $DIR/forget_copy.rs:52:5
+   |
+LL |     forget(a3);
+   |     ^^^^^^^--^
+   |            |
+   |            argument has type `&AnotherStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+  --> $DIR/forget_copy.rs:53:5
+   |
+LL |     forget(a4);
+   |     ^^^^^^^--^
+   |            |
+   |            argument has type `&AnotherStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: 8 warnings emitted
+
diff --git a/tests/ui/lint/forget_ref.rs b/tests/ui/lint/forget_ref.rs
new file mode 100644
index 00000000000..13f6d4be3d1
--- /dev/null
+++ b/tests/ui/lint/forget_ref.rs
@@ -0,0 +1,39 @@
+// check-pass
+
+#![warn(forget_ref)]
+
+use std::mem::forget;
+
+struct SomeStruct;
+
+fn main() {
+    forget(&SomeStruct); //~ WARN calls to `std::mem::forget`
+
+    let mut owned = SomeStruct;
+    forget(&owned); //~ WARN calls to `std::mem::forget`
+    forget(&&owned); //~ WARN calls to `std::mem::forget`
+    forget(&mut owned); //~ WARN calls to `std::mem::forget`
+    forget(owned);
+
+    let reference1 = &SomeStruct;
+    forget(&*reference1); //~ WARN calls to `std::mem::forget`
+
+    let reference2 = &mut SomeStruct;
+    forget(reference2); //~ WARN calls to `std::mem::forget`
+
+    let ref reference3 = SomeStruct;
+    forget(reference3); //~ WARN calls to `std::mem::forget`
+}
+
+#[allow(dead_code)]
+fn test_generic_fn_forget<T>(val: T) {
+    forget(&val); //~ WARN calls to `std::mem::forget`
+    forget(val);
+}
+
+#[allow(dead_code)]
+fn test_similarly_named_function() {
+    fn forget<T>(_val: T) {}
+    forget(&SomeStruct); //OK; call to unrelated function which happens to have the same name
+    std::mem::forget(&SomeStruct); //~ WARN calls to `std::mem::forget`
+}
diff --git a/tests/ui/lint/forget_ref.stderr b/tests/ui/lint/forget_ref.stderr
new file mode 100644
index 00000000000..63fc7791980
--- /dev/null
+++ b/tests/ui/lint/forget_ref.stderr
@@ -0,0 +1,97 @@
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+  --> $DIR/forget_ref.rs:10:5
+   |
+LL |     forget(&SomeStruct);
+   |     ^^^^^^^-----------^
+   |            |
+   |            argument has type `&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+note: the lint level is defined here
+  --> $DIR/forget_ref.rs:3:9
+   |
+LL | #![warn(forget_ref)]
+   |         ^^^^^^^^^^
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+  --> $DIR/forget_ref.rs:13:5
+   |
+LL |     forget(&owned);
+   |     ^^^^^^^------^
+   |            |
+   |            argument has type `&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+  --> $DIR/forget_ref.rs:14:5
+   |
+LL |     forget(&&owned);
+   |     ^^^^^^^-------^
+   |            |
+   |            argument has type `&&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+  --> $DIR/forget_ref.rs:15:5
+   |
+LL |     forget(&mut owned);
+   |     ^^^^^^^----------^
+   |            |
+   |            argument has type `&mut SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+  --> $DIR/forget_ref.rs:19:5
+   |
+LL |     forget(&*reference1);
+   |     ^^^^^^^------------^
+   |            |
+   |            argument has type `&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+  --> $DIR/forget_ref.rs:22:5
+   |
+LL |     forget(reference2);
+   |     ^^^^^^^----------^
+   |            |
+   |            argument has type `&mut SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+  --> $DIR/forget_ref.rs:25:5
+   |
+LL |     forget(reference3);
+   |     ^^^^^^^----------^
+   |            |
+   |            argument has type `&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+  --> $DIR/forget_ref.rs:30:5
+   |
+LL |     forget(&val);
+   |     ^^^^^^^----^
+   |            |
+   |            argument has type `&T`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: calls to `std::mem::forget` with a reference instead of an owned value does nothing
+  --> $DIR/forget_ref.rs:38:5
+   |
+LL |     std::mem::forget(&SomeStruct);
+   |     ^^^^^^^^^^^^^^^^^-----------^
+   |                      |
+   |                      argument has type `&SomeStruct`
+   |
+   = note: use `let _ = ...` to ignore the expression or result
+
+warning: 9 warnings emitted
+
diff --git a/tests/ui/liveness/liveness-unused.rs b/tests/ui/liveness/liveness-unused.rs
index 9c7be15fcc8..8ef6ab1b6ff 100644
--- a/tests/ui/liveness/liveness-unused.rs
+++ b/tests/ui/liveness/liveness-unused.rs
@@ -1,7 +1,7 @@
 #![warn(unused)]
 #![deny(unused_variables)]
 #![deny(unused_assignments)]
-#![allow(dead_code, non_camel_case_types, trivial_numeric_casts)]
+#![allow(dead_code, non_camel_case_types, trivial_numeric_casts, drop_copy)]
 
 use std::ops::AddAssign;
 
diff --git a/tests/ui/macros/parse-complex-macro-invoc-op.rs b/tests/ui/macros/parse-complex-macro-invoc-op.rs
index 8fef9b0ed87..c50dfdf0116 100644
--- a/tests/ui/macros/parse-complex-macro-invoc-op.rs
+++ b/tests/ui/macros/parse-complex-macro-invoc-op.rs
@@ -4,6 +4,7 @@
 #![allow(unused_assignments)]
 #![allow(unused_variables)]
 #![allow(stable_features)]
+#![allow(drop_copy)]
 
 // Test parsing binary operators after macro invocations.
 
diff --git a/tests/ui/never_type/never-assign-dead-code.rs b/tests/ui/never_type/never-assign-dead-code.rs
index 7bb7c87097c..e95a992d780 100644
--- a/tests/ui/never_type/never-assign-dead-code.rs
+++ b/tests/ui/never_type/never-assign-dead-code.rs
@@ -3,6 +3,7 @@
 // check-pass
 
 #![feature(never_type)]
+#![allow(drop_copy)]
 #![warn(unused)]
 
 fn main() {
diff --git a/tests/ui/never_type/never-assign-dead-code.stderr b/tests/ui/never_type/never-assign-dead-code.stderr
index 521b82023c9..5660bde5c27 100644
--- a/tests/ui/never_type/never-assign-dead-code.stderr
+++ b/tests/ui/never_type/never-assign-dead-code.stderr
@@ -1,5 +1,5 @@
 warning: unreachable statement
-  --> $DIR/never-assign-dead-code.rs:10:5
+  --> $DIR/never-assign-dead-code.rs:11:5
    |
 LL |     let x: ! = panic!("aah");
    |                ------------- any code following this expression is unreachable
@@ -7,14 +7,14 @@ LL |     drop(x);
    |     ^^^^^^^^ unreachable statement
    |
 note: the lint level is defined here
-  --> $DIR/never-assign-dead-code.rs:6:9
+  --> $DIR/never-assign-dead-code.rs:7:9
    |
 LL | #![warn(unused)]
    |         ^^^^^^
    = note: `#[warn(unreachable_code)]` implied by `#[warn(unused)]`
 
 warning: unreachable call
-  --> $DIR/never-assign-dead-code.rs:10:5
+  --> $DIR/never-assign-dead-code.rs:11:5
    |
 LL |     drop(x);
    |     ^^^^ - any code following this expression is unreachable
@@ -22,7 +22,7 @@ LL |     drop(x);
    |     unreachable call
 
 warning: unused variable: `x`
-  --> $DIR/never-assign-dead-code.rs:9:9
+  --> $DIR/never-assign-dead-code.rs:10:9
    |
 LL |     let x: ! = panic!("aah");
    |         ^ help: if this is intentional, prefix it with an underscore: `_x`
diff --git a/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs b/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs
index 7cc0acf45f2..73ceaeeb875 100644
--- a/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs
+++ b/tests/ui/nll/relate_tys/hr-fn-aba-as-aaa.rs
@@ -5,6 +5,8 @@
 // check-pass
 // compile-flags:-Zno-leak-check
 
+#![allow(drop_copy)]
+
 fn make_it() -> for<'a, 'b> fn(&'a u32, &'b u32) -> &'a u32 {
     panic!()
 }
diff --git a/tests/ui/nll/ty-outlives/projection-body.rs b/tests/ui/nll/ty-outlives/projection-body.rs
index b03a539ebdb..bff9058a507 100644
--- a/tests/ui/nll/ty-outlives/projection-body.rs
+++ b/tests/ui/nll/ty-outlives/projection-body.rs
@@ -3,6 +3,8 @@
 //
 // check-pass
 
+#![allow(drop_ref)]
+
 trait MyTrait<'a> {
     type Output;
 }
diff --git a/tests/ui/or-patterns/or-patterns-default-binding-modes.rs b/tests/ui/or-patterns/or-patterns-default-binding-modes.rs
index e56f9ffe23c..c138d99d303 100644
--- a/tests/ui/or-patterns/or-patterns-default-binding-modes.rs
+++ b/tests/ui/or-patterns/or-patterns-default-binding-modes.rs
@@ -3,6 +3,8 @@
 // check-pass
 
 #![allow(irrefutable_let_patterns)]
+#![allow(drop_copy)]
+#![allow(drop_ref)]
 
 fn main() {
     // A regression test for a mistake we made at one point:
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs
index fbdefd9d36c..965204bf240 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs
@@ -2,6 +2,9 @@
 
 // Test `@` patterns combined with `box` patterns.
 
+#![allow(drop_ref)]
+#![allow(drop_copy)]
+
 #![feature(box_patterns)]
 
 #[derive(Copy, Clone)]
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs
index 0108861cfce..3eb5d2cbf54 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs
@@ -2,6 +2,8 @@
 
 // Test `Copy` bindings in the rhs of `@` patterns.
 
+#![allow(drop_copy)]
+
 #[derive(Copy, Clone)]
 struct C;
 
diff --git a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs
index 5445696fdff..0550238549e 100644
--- a/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs
+++ b/tests/ui/pattern/move-ref-patterns/borrowck-move-ref-pattern-pass.rs
@@ -1,5 +1,7 @@
 // check-pass
 
+#![allow(drop_ref)]
+
 fn main() {}
 
 struct U;
diff --git a/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs b/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs
index 583f70f41aa..788975d960a 100644
--- a/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs
+++ b/tests/ui/pattern/move-ref-patterns/move-ref-patterns-closure-captures-pass.rs
@@ -1,5 +1,7 @@
 // check-pass
 
+#![allow(drop_ref)]
+
 fn main() {
     struct U;
     fn accept_fn_once(_: impl FnOnce()) {}
diff --git a/tests/ui/print_type_sizes/async.rs b/tests/ui/print_type_sizes/async.rs
index 1598b069691..c73268dc46a 100644
--- a/tests/ui/print_type_sizes/async.rs
+++ b/tests/ui/print_type_sizes/async.rs
@@ -3,6 +3,8 @@
 // build-pass
 // ignore-pass
 
+#![allow(drop_copy)]
+
 async fn wait() {}
 
 pub async fn test(arg: [u8; 8192]) {
diff --git a/tests/ui/print_type_sizes/async.stdout b/tests/ui/print_type_sizes/async.stdout
index 1c6887412be..873def9031a 100644
--- a/tests/ui/print_type_sizes/async.stdout
+++ b/tests/ui/print_type_sizes/async.stdout
@@ -1,4 +1,4 @@
-print-type-size type: `[async fn body@$DIR/async.rs:8:36: 11:2]`: 16386 bytes, alignment: 1 bytes
+print-type-size type: `[async fn body@$DIR/async.rs:10:36: 13:2]`: 16386 bytes, alignment: 1 bytes
 print-type-size     discriminant: 1 bytes
 print-type-size     variant `Unresumed`: 8192 bytes
 print-type-size         upvar `.arg`: 8192 bytes
@@ -16,14 +16,14 @@ print-type-size type: `std::mem::MaybeUninit<[u8; 8192]>`: 8192 bytes, alignment
 print-type-size     variant `MaybeUninit`: 8192 bytes
 print-type-size         field `.uninit`: 0 bytes
 print-type-size         field `.value`: 8192 bytes
-print-type-size type: `[async fn body@$DIR/async.rs:6:17: 6:19]`: 1 bytes, alignment: 1 bytes
+print-type-size type: `[async fn body@$DIR/async.rs:8:17: 8:19]`: 1 bytes, alignment: 1 bytes
 print-type-size     discriminant: 1 bytes
 print-type-size     variant `Unresumed`: 0 bytes
 print-type-size     variant `Returned`: 0 bytes
 print-type-size     variant `Panicked`: 0 bytes
-print-type-size type: `std::mem::ManuallyDrop<[async fn body@$DIR/async.rs:6:17: 6:19]>`: 1 bytes, alignment: 1 bytes
+print-type-size type: `std::mem::ManuallyDrop<[async fn body@$DIR/async.rs:8:17: 8:19]>`: 1 bytes, alignment: 1 bytes
 print-type-size     field `.value`: 1 bytes
-print-type-size type: `std::mem::MaybeUninit<[async fn body@$DIR/async.rs:6:17: 6:19]>`: 1 bytes, alignment: 1 bytes
+print-type-size type: `std::mem::MaybeUninit<[async fn body@$DIR/async.rs:8:17: 8:19]>`: 1 bytes, alignment: 1 bytes
 print-type-size     variant `MaybeUninit`: 1 bytes
 print-type-size         field `.uninit`: 0 bytes
 print-type-size         field `.value`: 1 bytes
diff --git a/tests/ui/print_type_sizes/generator_discr_placement.rs b/tests/ui/print_type_sizes/generator_discr_placement.rs
index 1a85fe95bb6..a77a03f0a8a 100644
--- a/tests/ui/print_type_sizes/generator_discr_placement.rs
+++ b/tests/ui/print_type_sizes/generator_discr_placement.rs
@@ -6,6 +6,7 @@
 
 // Avoid emitting panic handlers, like the rest of these tests...
 #![feature(generators)]
+#![allow(drop_copy)]
 
 pub fn foo() {
     let a = || {
diff --git a/tests/ui/print_type_sizes/generator_discr_placement.stdout b/tests/ui/print_type_sizes/generator_discr_placement.stdout
index f2a11c7a33b..fe0022cf5f4 100644
--- a/tests/ui/print_type_sizes/generator_discr_placement.stdout
+++ b/tests/ui/print_type_sizes/generator_discr_placement.stdout
@@ -1,4 +1,4 @@
-print-type-size type: `[generator@$DIR/generator_discr_placement.rs:11:13: 11:15]`: 8 bytes, alignment: 4 bytes
+print-type-size type: `[generator@$DIR/generator_discr_placement.rs:12:13: 12:15]`: 8 bytes, alignment: 4 bytes
 print-type-size     discriminant: 1 bytes
 print-type-size     variant `Unresumed`: 0 bytes
 print-type-size     variant `Suspend0`: 7 bytes
diff --git a/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs b/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs
index a65c17e0efc..5ae5ebb450e 100644
--- a/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs
+++ b/tests/ui/regions/type-param-outlives-reempty-issue-74429-2.rs
@@ -55,11 +55,11 @@ where
 }
 
 pub fn x<T: Copy>(a: Array<T>) {
-    // drop just avoids a must_use warning
-    drop((0..1).filter(|_| true));
+    // _ just avoids a must_use warning
+    let _ = (0..1).filter(|_| true);
     let y = a.index_axis();
     a.axis_iter().for_each(|_| {
-        drop(y);
+        let _ = y;
     });
 }
 
diff --git a/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs b/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs
index d463f311c34..af2bb09805a 100644
--- a/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs
+++ b/tests/ui/regions/type-param-outlives-reempty-issue-74429.rs
@@ -3,6 +3,8 @@
 
 // check-pass
 
+#![allow(drop_copy)]
+
 use std::marker::PhantomData;
 
 fn apply<T, F: FnOnce(T)>(_: T, _: F) {}
diff --git a/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs b/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs
index be775b37f7b..8f45b989f13 100644
--- a/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs
+++ b/tests/ui/rfc-2008-non-exhaustive/borrowck-exhaustive.rs
@@ -3,6 +3,8 @@
 
 // check-pass
 
+#![allow(drop_ref)]
+
 // aux-build:monovariants.rs
 extern crate monovariants;
 
diff --git a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
index 04d924a9aed..4c1562790d5 100644
--- a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
+++ b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
@@ -4,6 +4,8 @@
 // Tests ensuring that `dbg!(expr)` has the expected run-time behavior.
 // as well as some compile time properties we expect.
 
+#![allow(drop_copy)]
+
 #[derive(Copy, Clone, Debug)]
 struct Unit;
 
diff --git a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr
index 49d72158e92..a20a6062c13 100644
--- a/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr
+++ b/tests/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr
@@ -1,28 +1,28 @@
-[$DIR/dbg-macro-expected-behavior.rs:20] Unit = Unit
-[$DIR/dbg-macro-expected-behavior.rs:21] a = Unit
-[$DIR/dbg-macro-expected-behavior.rs:27] Point { x: 42, y: 24 } = Point {
+[$DIR/dbg-macro-expected-behavior.rs:22] Unit = Unit
+[$DIR/dbg-macro-expected-behavior.rs:23] a = Unit
+[$DIR/dbg-macro-expected-behavior.rs:29] Point { x: 42, y: 24 } = Point {
     x: 42,
     y: 24,
 }
-[$DIR/dbg-macro-expected-behavior.rs:28] b = Point {
+[$DIR/dbg-macro-expected-behavior.rs:30] b = Point {
     x: 42,
     y: 24,
 }
-[$DIR/dbg-macro-expected-behavior.rs:36]
-[$DIR/dbg-macro-expected-behavior.rs:40] &a = NoCopy(
+[$DIR/dbg-macro-expected-behavior.rs:38]
+[$DIR/dbg-macro-expected-behavior.rs:42] &a = NoCopy(
     1337,
 )
-[$DIR/dbg-macro-expected-behavior.rs:40] dbg!(& a) = NoCopy(
+[$DIR/dbg-macro-expected-behavior.rs:42] dbg!(& a) = NoCopy(
     1337,
 )
-[$DIR/dbg-macro-expected-behavior.rs:45] f(&42) = 42
+[$DIR/dbg-macro-expected-behavior.rs:47] f(&42) = 42
 before
-[$DIR/dbg-macro-expected-behavior.rs:50] { foo += 1; eprintln!("before"); 7331 } = 7331
-[$DIR/dbg-macro-expected-behavior.rs:58] ("Yeah",) = (
+[$DIR/dbg-macro-expected-behavior.rs:52] { foo += 1; eprintln!("before"); 7331 } = 7331
+[$DIR/dbg-macro-expected-behavior.rs:60] ("Yeah",) = (
     "Yeah",
 )
-[$DIR/dbg-macro-expected-behavior.rs:61] 1 = 1
-[$DIR/dbg-macro-expected-behavior.rs:61] 2 = 2
-[$DIR/dbg-macro-expected-behavior.rs:65] 1u8 = 1
-[$DIR/dbg-macro-expected-behavior.rs:65] 2u32 = 2
-[$DIR/dbg-macro-expected-behavior.rs:65] "Yeah" = "Yeah"
+[$DIR/dbg-macro-expected-behavior.rs:63] 1 = 1
+[$DIR/dbg-macro-expected-behavior.rs:63] 2 = 2
+[$DIR/dbg-macro-expected-behavior.rs:67] 1u8 = 1
+[$DIR/dbg-macro-expected-behavior.rs:67] 2u32 = 2
+[$DIR/dbg-macro-expected-behavior.rs:67] "Yeah" = "Yeah"
diff --git a/tests/ui/rust-2018/remove-extern-crate.fixed b/tests/ui/rust-2018/remove-extern-crate.fixed
index 15e0ccc5256..4ed4d610025 100644
--- a/tests/ui/rust-2018/remove-extern-crate.fixed
+++ b/tests/ui/rust-2018/remove-extern-crate.fixed
@@ -5,6 +5,7 @@
 // compile-flags:--extern remove_extern_crate
 
 #![warn(rust_2018_idioms)]
+#![allow(drop_copy)]
 
  //~ WARNING unused extern crate
 // Shouldn't suggest changing to `use`, as `another_name`
diff --git a/tests/ui/rust-2018/remove-extern-crate.rs b/tests/ui/rust-2018/remove-extern-crate.rs
index aec0bc7c374..5dafdb2b7b7 100644
--- a/tests/ui/rust-2018/remove-extern-crate.rs
+++ b/tests/ui/rust-2018/remove-extern-crate.rs
@@ -5,6 +5,7 @@
 // compile-flags:--extern remove_extern_crate
 
 #![warn(rust_2018_idioms)]
+#![allow(drop_copy)]
 
 extern crate core; //~ WARNING unused extern crate
 // Shouldn't suggest changing to `use`, as `another_name`
diff --git a/tests/ui/rust-2018/remove-extern-crate.stderr b/tests/ui/rust-2018/remove-extern-crate.stderr
index d07358e471b..f752cac8ed6 100644
--- a/tests/ui/rust-2018/remove-extern-crate.stderr
+++ b/tests/ui/rust-2018/remove-extern-crate.stderr
@@ -1,5 +1,5 @@
 warning: unused extern crate
-  --> $DIR/remove-extern-crate.rs:9:1
+  --> $DIR/remove-extern-crate.rs:10:1
    |
 LL | extern crate core;
    | ^^^^^^^^^^^^^^^^^^ help: remove it
@@ -12,7 +12,7 @@ LL | #![warn(rust_2018_idioms)]
    = note: `#[warn(unused_extern_crates)]` implied by `#[warn(rust_2018_idioms)]`
 
 warning: `extern crate` is not idiomatic in the new edition
-  --> $DIR/remove-extern-crate.rs:33:5
+  --> $DIR/remove-extern-crate.rs:34:5
    |
 LL |     extern crate core;
    |     ^^^^^^^^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL |     use core;
    |     ~~~
 
 warning: `extern crate` is not idiomatic in the new edition
-  --> $DIR/remove-extern-crate.rs:43:5
+  --> $DIR/remove-extern-crate.rs:44:5
    |
 LL |     pub extern crate core;
    |     ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/statics/issue-91050-1.rs b/tests/ui/statics/issue-91050-1.rs
index 403a41462ef..f59bcf0b803 100644
--- a/tests/ui/statics/issue-91050-1.rs
+++ b/tests/ui/statics/issue-91050-1.rs
@@ -12,6 +12,8 @@
 //
 // In regular builds, the bad cast was UB, like "Invalid LLVMRustVisibility value!"
 
+#![allow(drop_copy)]
+
 pub mod before {
     #[no_mangle]
     pub static GLOBAL1: [u8; 1] = [1];
diff --git a/tests/ui/traits/copy-guessing.rs b/tests/ui/traits/copy-guessing.rs
index f031dd9ca48..558303c2e40 100644
--- a/tests/ui/traits/copy-guessing.rs
+++ b/tests/ui/traits/copy-guessing.rs
@@ -1,5 +1,8 @@
 // run-pass
+
 #![allow(dead_code)]
+#![allow(drop_copy)]
+
 // "guessing" in trait selection can affect `copy_or_move`. Check that this
 // is correctly handled. I am not sure what is the "correct" behaviour,
 // but we should at least not ICE.
diff --git a/tests/ui/traits/impl-evaluation-order.rs b/tests/ui/traits/impl-evaluation-order.rs
index 57809d89aa6..256ce992eef 100644
--- a/tests/ui/traits/impl-evaluation-order.rs
+++ b/tests/ui/traits/impl-evaluation-order.rs
@@ -6,6 +6,8 @@
 
 // check-pass
 
+#![allow(drop_copy)]
+
 trait A {
     type B;
 }
diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
index 6a926534e07..4aefdd6bb07 100644
--- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
+++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `impl Future<Output = ()>` cannot be sent between threads safely
-  --> $DIR/auto-with-drop_tracking_mir.rs:24:13
+  --> $DIR/auto-with-drop_tracking_mir.rs:25:13
    |
 LL |     is_send(foo());
    |     ------- ^^^^^ `impl Future<Output = ()>` cannot be sent between threads safely
@@ -8,7 +8,7 @@ LL |     is_send(foo());
    |
    = help: the trait `Send` is not implemented for `impl Future<Output = ()>`
 note: required by a bound in `is_send`
-  --> $DIR/auto-with-drop_tracking_mir.rs:23:24
+  --> $DIR/auto-with-drop_tracking_mir.rs:24:24
    |
 LL |     fn is_send(_: impl Send) {}
    |                        ^^^^ required by this bound in `is_send`
diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
index a5db7c4636b..f115e143318 100644
--- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
+++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
@@ -14,6 +14,7 @@ async fn foo() {
     #[cfg(fail)]
     let x = &NotSync;
     bar().await;
+    #[allow(drop_ref)]
     drop(x);
 }
 
diff --git a/tests/ui/traits/new-solver/temporary-ambiguity.rs b/tests/ui/traits/new-solver/temporary-ambiguity.rs
index 18ee0545700..c6c11a1a1de 100644
--- a/tests/ui/traits/new-solver/temporary-ambiguity.rs
+++ b/tests/ui/traits/new-solver/temporary-ambiguity.rs
@@ -18,5 +18,5 @@ fn main() {
     let w = Wrapper(x);
     needs_foo(w);
     x = 1;
-    drop(x);
+    let _ = x;
 }
diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs
index 3416503b851..6ed7667115a 100644
--- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs
+++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.rs
@@ -1,6 +1,8 @@
 // check-pass
 // Check tautalogically false `Copy` bounds
+
 #![feature(trivial_bounds)]
+#![allow(drop_ref, drop_copy)]
 
 fn copy_string(t: String) -> String where String: Copy { //~ WARNING trivial_bounds
     is_copy(&t);
diff --git a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr
index 1e26623899b..deeb352a2a8 100644
--- a/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr
+++ b/tests/ui/trivial-bounds/trivial-bounds-inconsistent-copy.stderr
@@ -1,5 +1,5 @@
 warning: trait bound String: Copy does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent-copy.rs:5:51
+  --> $DIR/trivial-bounds-inconsistent-copy.rs:7:51
    |
 LL | fn copy_string(t: String) -> String where String: Copy {
    |                                                   ^^^^
@@ -7,19 +7,19 @@ LL | fn copy_string(t: String) -> String where String: Copy {
    = note: `#[warn(trivial_bounds)]` on by default
 
 warning: trait bound String: Copy does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent-copy.rs:12:56
+  --> $DIR/trivial-bounds-inconsistent-copy.rs:14:56
    |
 LL | fn copy_out_string(t: &String) -> String where String: Copy {
    |                                                        ^^^^
 
 warning: trait bound String: Copy does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent-copy.rs:16:55
+  --> $DIR/trivial-bounds-inconsistent-copy.rs:18:55
    |
 LL | fn copy_string_with_param<T>(x: String) where String: Copy {
    |                                                       ^^^^
 
 warning: trait bound for<'b> &'b mut i32: Copy does not depend on any type or lifetime parameters
-  --> $DIR/trivial-bounds-inconsistent-copy.rs:22:76
+  --> $DIR/trivial-bounds-inconsistent-copy.rs:24:76
    |
 LL | fn copy_mut<'a>(t: &&'a mut i32) -> &'a mut i32 where for<'b> &'b mut i32: Copy {
    |                                                                            ^^^^