diff --git a/src/tools/clippy/.github/workflows/remark.yml b/src/tools/clippy/.github/workflows/remark.yml
index 348d52020fd23..a1b011dc32d84 100644
--- a/src/tools/clippy/.github/workflows/remark.yml
+++ b/src/tools/clippy/.github/workflows/remark.yml
@@ -19,7 +19,7 @@ jobs:
       uses: actions/checkout@v4
 
     - name: Setup Node.js
-      uses: actions/setup-node@v3
+      uses: actions/setup-node@v4
       with:
         node-version: '18.x'
 
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 41a86e8ce5102..5d253d52531e6 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -5871,6 +5871,7 @@ Released 2018-09-13
 [`ref_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_as_ptr
 [`ref_binding_to_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_binding_to_reference
 [`ref_in_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_in_deref
+[`ref_option`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_option
 [`ref_option_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_option_ref
 [`ref_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_patterns
 [`regex_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#regex_macro
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index 91159bc79c511..07a56fb33df11 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -353,6 +353,7 @@ Suppress lints whenever the suggested change would cause breakage for other crat
 * [`rc_buffer`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_buffer)
 * [`rc_mutex`](https://rust-lang.github.io/rust-clippy/master/index.html#rc_mutex)
 * [`redundant_allocation`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation)
+* [`ref_option`](https://rust-lang.github.io/rust-clippy/master/index.html#ref_option)
 * [`single_call_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#single_call_fn)
 * [`trivially_copy_pass_by_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref)
 * [`unnecessary_box_returns`](https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_box_returns)
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index 757620341ccc1..e4e2c97fdc1d9 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -378,6 +378,7 @@ define_Conf! {
         rc_buffer,
         rc_mutex,
         redundant_allocation,
+        ref_option,
         single_call_fn,
         trivially_copy_pass_by_ref,
         unnecessary_box_returns,
diff --git a/src/tools/clippy/clippy_config/src/msrvs.rs b/src/tools/clippy/clippy_config/src/msrvs.rs
index e30df3d32341a..68a3b11d3848f 100644
--- a/src/tools/clippy/clippy_config/src/msrvs.rs
+++ b/src/tools/clippy/clippy_config/src/msrvs.rs
@@ -19,6 +19,7 @@ macro_rules! msrv_aliases {
 msrv_aliases! {
     1,83,0 { CONST_EXTERN_FN }
     1,83,0 { CONST_FLOAT_BITS_CONV }
+    1,82,0 { IS_NONE_OR }
     1,81,0 { LINT_REASONS_STABILIZATION }
     1,80,0 { BOX_INTO_ITER}
     1,77,0 { C_STR_LITERALS }
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index 3c2af72624f60..26888f7e3a0ed 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -1,3 +1,5 @@
+use clippy_config::Conf;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
 use clippy_utils::eq_expr_value;
 use clippy_utils::source::SpanRangeExt;
@@ -7,7 +9,7 @@ use rustc_errors::Applicability;
 use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
 use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, UnOp};
 use rustc_lint::{LateContext, LateLintPass, Level};
-use rustc_session::declare_lint_pass;
+use rustc_session::{RustcVersion, impl_lint_pass};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::{Span, sym};
 
@@ -69,9 +71,25 @@ declare_clippy_lint! {
 }
 
 // For each pairs, both orders are considered.
-const METHODS_WITH_NEGATION: [(&str, &str); 2] = [("is_some", "is_none"), ("is_err", "is_ok")];
+const METHODS_WITH_NEGATION: [(Option<RustcVersion>, &str, &str); 3] = [
+    (None, "is_some", "is_none"),
+    (None, "is_err", "is_ok"),
+    (Some(msrvs::IS_NONE_OR), "is_some_and", "is_none_or"),
+];
+
+pub struct NonminimalBool {
+    msrv: Msrv,
+}
+
+impl NonminimalBool {
+    pub fn new(conf: &'static Conf) -> Self {
+        Self {
+            msrv: conf.msrv.clone(),
+        }
+    }
+}
 
-declare_lint_pass!(NonminimalBool => [NONMINIMAL_BOOL, OVERLY_COMPLEX_BOOL_EXPR]);
+impl_lint_pass!(NonminimalBool => [NONMINIMAL_BOOL, OVERLY_COMPLEX_BOOL_EXPR]);
 
 impl<'tcx> LateLintPass<'tcx> for NonminimalBool {
     fn check_fn(
@@ -83,7 +101,7 @@ impl<'tcx> LateLintPass<'tcx> for NonminimalBool {
         _: Span,
         _: LocalDefId,
     ) {
-        NonminimalBoolVisitor { cx }.visit_body(body);
+        NonminimalBoolVisitor { cx, msrv: &self.msrv }.visit_body(body);
     }
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
@@ -100,6 +118,8 @@ impl<'tcx> LateLintPass<'tcx> for NonminimalBool {
             _ => {},
         }
     }
+
+    extract_msrv_attr!(LateContext);
 }
 
 fn inverted_bin_op_eq_str(op: BinOpKind) -> Option<&'static str> {
@@ -176,11 +196,11 @@ fn check_inverted_bool_in_condition(
     );
 }
 
-fn check_simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) {
+fn check_simplify_not(cx: &LateContext<'_>, msrv: &Msrv, expr: &Expr<'_>) {
     if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind
         && !expr.span.from_expansion()
         && !inner.span.from_expansion()
-        && let Some(suggestion) = simplify_not(cx, inner)
+        && let Some(suggestion) = simplify_not(cx, msrv, inner)
         && cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).0 != Level::Allow
     {
         span_lint_and_sugg(
@@ -197,6 +217,7 @@ fn check_simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) {
 
 struct NonminimalBoolVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
+    msrv: &'a Msrv,
 }
 
 use quine_mc_cluskey::Bool;
@@ -205,7 +226,7 @@ struct Hir2Qmm<'a, 'tcx, 'v> {
     cx: &'a LateContext<'tcx>,
 }
 
-impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
+impl<'v> Hir2Qmm<'_, '_, 'v> {
     fn extract(&mut self, op: BinOpKind, a: &[&'v Expr<'_>], mut v: Vec<Bool>) -> Result<Vec<Bool>, String> {
         for a in a {
             if let ExprKind::Binary(binop, lhs, rhs) = &a.kind {
@@ -289,10 +310,11 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
 struct SuggestContext<'a, 'tcx, 'v> {
     terminals: &'v [&'v Expr<'v>],
     cx: &'a LateContext<'tcx>,
+    msrv: &'a Msrv,
     output: String,
 }
 
-impl<'a, 'tcx, 'v> SuggestContext<'a, 'tcx, 'v> {
+impl SuggestContext<'_, '_, '_> {
     fn recurse(&mut self, suggestion: &Bool) -> Option<()> {
         use quine_mc_cluskey::Bool::{And, False, Not, Or, Term, True};
         match suggestion {
@@ -311,7 +333,7 @@ impl<'a, 'tcx, 'v> SuggestContext<'a, 'tcx, 'v> {
                 },
                 Term(n) => {
                     let terminal = self.terminals[n as usize];
-                    if let Some(str) = simplify_not(self.cx, terminal) {
+                    if let Some(str) = simplify_not(self.cx, self.msrv, terminal) {
                         self.output.push_str(&str);
                     } else {
                         self.output.push('!');
@@ -358,7 +380,7 @@ impl<'a, 'tcx, 'v> SuggestContext<'a, 'tcx, 'v> {
     }
 }
 
-fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
+fn simplify_not(cx: &LateContext<'_>, curr_msrv: &Msrv, expr: &Expr<'_>) -> Option<String> {
     match &expr.kind {
         ExprKind::Binary(binop, lhs, rhs) => {
             if !implements_ord(cx, lhs) {
@@ -389,7 +411,7 @@ fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
                 Some(format!("{lhs_snippet}{op}{rhs_snippet}"))
             })
         },
-        ExprKind::MethodCall(path, receiver, [], _) => {
+        ExprKind::MethodCall(path, receiver, args, _) => {
             let type_of_receiver = cx.typeck_results().expr_ty(receiver);
             if !is_type_diagnostic_item(cx, type_of_receiver, sym::Option)
                 && !is_type_diagnostic_item(cx, type_of_receiver, sym::Result)
@@ -399,21 +421,41 @@ fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
             METHODS_WITH_NEGATION
                 .iter()
                 .copied()
-                .flat_map(|(a, b)| vec![(a, b), (b, a)])
-                .find(|&(a, _)| {
-                    let path: &str = path.ident.name.as_str();
-                    a == path
+                .flat_map(|(msrv, a, b)| vec![(msrv, a, b), (msrv, b, a)])
+                .find(|&(msrv, a, _)| msrv.is_none_or(|msrv| curr_msrv.meets(msrv)) && a == path.ident.name.as_str())
+                .and_then(|(_, _, neg_method)| {
+                    let negated_args = args
+                        .iter()
+                        .map(|arg| simplify_not(cx, curr_msrv, arg))
+                        .collect::<Option<Vec<_>>>()?
+                        .join(", ");
+                    Some(format!(
+                        "{}.{neg_method}({negated_args})",
+                        receiver.span.get_source_text(cx)?
+                    ))
                 })
-                .and_then(|(_, neg_method)| Some(format!("{}.{neg_method}()", receiver.span.get_source_text(cx)?)))
         },
+        ExprKind::Closure(closure) => {
+            let body = cx.tcx.hir().body(closure.body);
+            let params = body
+                .params
+                .iter()
+                .map(|param| param.span.get_source_text(cx).map(|t| t.to_string()))
+                .collect::<Option<Vec<_>>>()?
+                .join(", ");
+            let negated = simplify_not(cx, curr_msrv, body.value)?;
+            Some(format!("|{params}| {negated}"))
+        },
+        ExprKind::Unary(UnOp::Not, expr) => expr.span.get_source_text(cx).map(|t| t.to_string()),
         _ => None,
     }
 }
 
-fn suggest(cx: &LateContext<'_>, suggestion: &Bool, terminals: &[&Expr<'_>]) -> String {
+fn suggest(cx: &LateContext<'_>, msrv: &Msrv, suggestion: &Bool, terminals: &[&Expr<'_>]) -> String {
     let mut suggest_context = SuggestContext {
         terminals,
         cx,
+        msrv,
         output: String::new(),
     };
     suggest_context.recurse(suggestion);
@@ -475,7 +517,7 @@ fn terminal_stats(b: &Bool) -> Stats {
     stats
 }
 
-impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
+impl<'tcx> NonminimalBoolVisitor<'_, 'tcx> {
     fn bool_expr(&self, e: &'tcx Expr<'_>) {
         let mut h2q = Hir2Qmm {
             terminals: Vec::new(),
@@ -526,7 +568,7 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
                                 diag.span_suggestion(
                                     e.span,
                                     "it would look like the following",
-                                    suggest(self.cx, suggestion, &h2q.terminals),
+                                    suggest(self.cx, self.msrv, suggestion, &h2q.terminals),
                                     // nonminimal_bool can produce minimal but
                                     // not human readable expressions (#3141)
                                     Applicability::Unspecified,
@@ -569,12 +611,12 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
                 }
             };
             if improvements.is_empty() {
-                check_simplify_not(self.cx, e);
+                check_simplify_not(self.cx, self.msrv, e);
             } else {
                 nonminimal_bool_lint(
                     improvements
                         .into_iter()
-                        .map(|suggestion| suggest(self.cx, suggestion, &h2q.terminals))
+                        .map(|suggestion| suggest(self.cx, self.msrv, suggestion, &h2q.terminals))
                         .collect(),
                 );
             }
@@ -582,7 +624,7 @@ impl<'a, 'tcx> NonminimalBoolVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
         if !e.span.from_expansion() {
             match &e.kind {
diff --git a/src/tools/clippy/clippy_lints/src/box_default.rs b/src/tools/clippy/clippy_lints/src/box_default.rs
index 8261c65354fd5..40d154c0bdfe3 100644
--- a/src/tools/clippy/clippy_lints/src/box_default.rs
+++ b/src/tools/clippy/clippy_lints/src/box_default.rs
@@ -91,7 +91,7 @@ fn is_local_vec_expn(cx: &LateContext<'_>, expr: &Expr<'_>, ref_expr: &Expr<'_>)
 #[derive(Default)]
 struct InferVisitor(bool);
 
-impl<'tcx> Visitor<'tcx> for InferVisitor {
+impl Visitor<'_> for InferVisitor {
     fn visit_ty(&mut self, t: &Ty<'_>) {
         self.0 |= matches!(t.kind, TyKind::Infer | TyKind::OpaqueDef(..) | TyKind::TraitObject(..));
         if !self.0 {
diff --git a/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs b/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs
index fed0aa8b2758b..6714c053913c9 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs
@@ -10,27 +10,27 @@ pub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata, ignore_publish: b
         // only run the lint if publish is `None` (`publish = true` or skipped entirely)
         // or if the vector isn't empty (`publish = ["something"]`)
         if package.publish.as_ref().filter(|publish| publish.is_empty()).is_none() || ignore_publish {
-            if is_empty_str(&package.description) {
+            if is_empty_str(package.description.as_ref()) {
                 missing_warning(cx, package, "package.description");
             }
 
-            if is_empty_str(&package.license) && is_empty_str(&package.license_file) {
+            if is_empty_str(package.license.as_ref()) && is_empty_str(package.license_file.as_ref()) {
                 missing_warning(cx, package, "either package.license or package.license_file");
             }
 
-            if is_empty_str(&package.repository) {
+            if is_empty_str(package.repository.as_ref()) {
                 missing_warning(cx, package, "package.repository");
             }
 
-            if is_empty_str(&package.readme) {
+            if is_empty_str(package.readme.as_ref()) {
                 missing_warning(cx, package, "package.readme");
             }
 
-            if is_empty_vec(&package.keywords) {
+            if is_empty_vec(package.keywords.as_ref()) {
                 missing_warning(cx, package, "package.keywords");
             }
 
-            if is_empty_vec(&package.categories) {
+            if is_empty_vec(package.categories.as_ref()) {
                 missing_warning(cx, package, "package.categories");
             }
         }
@@ -42,8 +42,8 @@ fn missing_warning(cx: &LateContext<'_>, package: &cargo_metadata::Package, fiel
     span_lint(cx, CARGO_COMMON_METADATA, DUMMY_SP, message);
 }
 
-fn is_empty_str<T: AsRef<std::ffi::OsStr>>(value: &Option<T>) -> bool {
-    value.as_ref().map_or(true, |s| s.as_ref().is_empty())
+fn is_empty_str<T: AsRef<std::ffi::OsStr>>(value: Option<&T>) -> bool {
+    value.map_or(true, |s| s.as_ref().is_empty())
 }
 
 fn is_empty_vec(value: &[String]) -> bool {
diff --git a/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
index b7256dd2eae9d..4dd51dcbc9a20 100644
--- a/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/borrow_as_ptr.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::is_no_std_crate;
 use clippy_utils::source::snippet_with_context;
+use clippy_utils::std_or_core;
 use rustc_errors::Applicability;
 use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Ty, TyKind};
 use rustc_lint::LateContext;
@@ -16,8 +16,8 @@ pub(super) fn check<'tcx>(
 ) {
     if matches!(cast_to.kind, TyKind::Ptr(_))
         && let ExprKind::AddrOf(BorrowKind::Ref, mutability, e) = cast_expr.kind
+        && let Some(std_or_core) = std_or_core(cx)
     {
-        let core_or_std = if is_no_std_crate(cx) { "core" } else { "std" };
         let macro_name = match mutability {
             Mutability::Not => "addr_of",
             Mutability::Mut => "addr_of_mut",
@@ -40,7 +40,7 @@ pub(super) fn check<'tcx>(
             expr.span,
             "borrow as raw pointer",
             "try",
-            format!("{core_or_std}::ptr::{macro_name}!({snip})"),
+            format!("{std_or_core}::ptr::{macro_name}!({snip})"),
             Applicability::MachineApplicable,
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs
index dfa240ccec623..f699bba20ed01 100644
--- a/src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::Sugg;
-use clippy_utils::{ExprUseNode, expr_use_ctxt, is_no_std_crate};
+use clippy_utils::{ExprUseNode, expr_use_ctxt, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, Mutability, Ty, TyKind};
 use rustc_lint::LateContext;
@@ -25,8 +25,8 @@ pub(super) fn check<'tcx>(
         && let use_cx = expr_use_ctxt(cx, expr)
         // TODO: only block the lint if `cast_expr` is a temporary
         && !matches!(use_cx.use_node(cx), ExprUseNode::LetStmt(_) | ExprUseNode::ConstStatic(_))
+        && let Some(std_or_core) = std_or_core(cx)
     {
-        let core_or_std = if is_no_std_crate(cx) { "core" } else { "std" };
         let fn_name = match to_mutbl {
             Mutability::Not => "from_ref",
             Mutability::Mut => "from_mut",
@@ -56,7 +56,7 @@ pub(super) fn check<'tcx>(
             expr.span,
             "reference as raw pointer",
             "try",
-            format!("{core_or_std}::ptr::{fn_name}{turbofish}({cast_expr_sugg})"),
+            format!("{std_or_core}::ptr::{fn_name}{turbofish}({cast_expr_sugg})"),
             app,
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/checked_conversions.rs b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
index d3aa2fd1ea12c..2e7f91a842e1e 100644
--- a/src/tools/clippy/clippy_lints/src/checked_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/checked_conversions.rs
@@ -48,7 +48,7 @@ impl CheckedConversions {
 
 impl_lint_pass!(CheckedConversions => [CHECKED_CONVERSIONS]);
 
-impl<'tcx> LateLintPass<'tcx> for CheckedConversions {
+impl LateLintPass<'_> for CheckedConversions {
     fn check_expr(&mut self, cx: &LateContext<'_>, item: &Expr<'_>) {
         if let ExprKind::Binary(op, lhs, rhs) = item.kind
             && let (lt1, gt1, op2) = match op.node {
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 2b229d2fe6ac5..9cec672beb004 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -202,6 +202,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::functions::MUST_USE_CANDIDATE_INFO,
     crate::functions::MUST_USE_UNIT_INFO,
     crate::functions::NOT_UNSAFE_PTR_ARG_DEREF_INFO,
+    crate::functions::REF_OPTION_INFO,
     crate::functions::RENAMED_FUNCTION_PARAMS_INFO,
     crate::functions::RESULT_LARGE_ERR_INFO,
     crate::functions::RESULT_UNIT_ERR_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
index a065dc2cf7e52..4808c372754c4 100644
--- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
+++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
@@ -119,7 +119,7 @@ impl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for NumericFallbackVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
         match &expr.kind {
             ExprKind::Block(
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index 35a97adfb452a..82a66cc92029b 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -385,7 +385,7 @@ fn check_unsafe_derive_deserialize<'tcx>(
         && cx
             .tcx
             .inherent_impls(def.did())
-            .into_iter()
+            .iter()
             .map(|imp_did| cx.tcx.hir().expect_item(imp_did.expect_local()))
             .any(|imp| has_unsafe(cx, imp))
     {
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index 0ae1fad569213..e090644ae4410 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -970,7 +970,7 @@ impl<'a, 'tcx> FindPanicUnwrap<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for FindPanicUnwrap<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for FindPanicUnwrap<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
diff --git a/src/tools/clippy/clippy_lints/src/empty_enum.rs b/src/tools/clippy/clippy_lints/src/empty_enum.rs
index f4c55738cb83a..70eb81fa09c1a 100644
--- a/src/tools/clippy/clippy_lints/src/empty_enum.rs
+++ b/src/tools/clippy/clippy_lints/src/empty_enum.rs
@@ -60,7 +60,7 @@ declare_clippy_lint! {
 
 declare_lint_pass!(EmptyEnum => [EMPTY_ENUM]);
 
-impl<'tcx> LateLintPass<'tcx> for EmptyEnum {
+impl LateLintPass<'_> for EmptyEnum {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
         if let ItemKind::Enum(..) = item.kind
             // Only suggest the `never_type` if the feature is enabled
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index 5588124e791ea..a89f0d9c43274 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -141,7 +141,7 @@ fn is_argument(tcx: TyCtxt<'_>, id: HirId) -> bool {
     matches!(tcx.parent_hir_node(id), Node::Param(_))
 }
 
-impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
+impl<'tcx> Delegate<'tcx> for EscapeDelegate<'_, 'tcx> {
     fn consume(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId) {
         if cmt.place.projections.is_empty() {
             if let PlaceBase::Local(lid) = cmt.place.base {
@@ -188,7 +188,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
     fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
 }
 
-impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
+impl<'tcx> EscapeDelegate<'_, 'tcx> {
     fn is_large_box(&self, ty: Ty<'tcx>) -> bool {
         // Large types need to be boxed to avoid stack overflows.
         if let Some(boxed_ty) = ty.boxed_ty() {
diff --git a/src/tools/clippy/clippy_lints/src/excessive_nesting.rs b/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
index ce0e0faa01489..ffc76366983aa 100644
--- a/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
+++ b/src/tools/clippy/clippy_lints/src/excessive_nesting.rs
@@ -135,7 +135,7 @@ impl NestingVisitor<'_, '_> {
     }
 }
 
-impl<'conf, 'cx> Visitor<'_> for NestingVisitor<'conf, 'cx> {
+impl Visitor<'_> for NestingVisitor<'_, '_> {
     fn visit_block(&mut self, block: &Block) {
         if block.span.from_expansion() {
             return;
diff --git a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
index bf9388b4a70fd..3b93d3ff93ed4 100644
--- a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
+++ b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
@@ -193,7 +193,7 @@ fn bound_to_trait_def_id(bound: &GenericBound<'_>) -> Option<LocalDefId> {
     bound.trait_ref()?.trait_def_id()?.as_local()
 }
 
-impl<'cx, 'tcx> Visitor<'tcx> for TypeWalker<'cx, 'tcx> {
+impl<'tcx> Visitor<'tcx> for TypeWalker<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_ty(&mut self, t: &'tcx Ty<'tcx>) {
diff --git a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
index 747ea9a434464..f822432cce63a 100644
--- a/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
+++ b/src/tools/clippy/clippy_lints/src/fallible_impl_from.rs
@@ -73,7 +73,7 @@ fn lint_impl_body(cx: &LateContext<'_>, impl_span: Span, impl_items: &[hir::Impl
         result: Vec<Span>,
     }
 
-    impl<'a, 'tcx> Visitor<'tcx> for FindPanicUnwrap<'a, 'tcx> {
+    impl<'tcx> Visitor<'tcx> for FindPanicUnwrap<'_, 'tcx> {
         fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
             if let Some(macro_call) = root_macro_call_first_node(self.lcx, expr) {
                 if is_panic(self.lcx, macro_call.def_id) {
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index 83ab9f6557bdd..4c043f8dc14b7 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -219,7 +219,7 @@ struct FormatArgsExpr<'a, 'tcx> {
     ignore_mixed: bool,
 }
 
-impl<'a, 'tcx> FormatArgsExpr<'a, 'tcx> {
+impl FormatArgsExpr<'_, '_> {
     fn check_templates(&self) {
         for piece in &self.format_args.template {
             if let FormatArgsPiece::Placeholder(placeholder) = piece
diff --git a/src/tools/clippy/clippy_lints/src/format_impl.rs b/src/tools/clippy/clippy_lints/src/format_impl.rs
index c196f404ce677..7c0515b8c5608 100644
--- a/src/tools/clippy/clippy_lints/src/format_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/format_impl.rs
@@ -148,7 +148,7 @@ struct FormatImplExpr<'a, 'tcx> {
     format_trait_impl: FormatTraitNames,
 }
 
-impl<'a, 'tcx> FormatImplExpr<'a, 'tcx> {
+impl FormatImplExpr<'_, '_> {
     fn check_to_string_in_display(&self) {
         if self.format_trait_impl.name == sym::Display
             && let ExprKind::MethodCall(path, self_arg, ..) = self.expr.kind
diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs
index 8832cd42dd98f..d5a2e06863dc5 100644
--- a/src/tools/clippy/clippy_lints/src/from_over_into.rs
+++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs
@@ -126,7 +126,7 @@ struct SelfFinder<'a, 'tcx> {
     invalid: bool,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for SelfFinder<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for SelfFinder<'_, 'tcx> {
     type NestedFilter = OnlyBodies;
 
     fn nested_visit_map(&mut self) -> Self::Map {
diff --git a/src/tools/clippy/clippy_lints/src/functions/mod.rs b/src/tools/clippy/clippy_lints/src/functions/mod.rs
index ba8a459c917e6..91d73c2a9c962 100644
--- a/src/tools/clippy/clippy_lints/src/functions/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/mod.rs
@@ -2,6 +2,7 @@ mod impl_trait_in_params;
 mod misnamed_getters;
 mod must_use;
 mod not_unsafe_ptr_arg_deref;
+mod ref_option;
 mod renamed_function_params;
 mod result;
 mod too_many_arguments;
@@ -399,6 +400,53 @@ declare_clippy_lint! {
     "renamed function parameters in trait implementation"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Warns when a function signature uses `&Option<T>` instead of `Option<&T>`.
+    ///
+    /// ### Why is this bad?
+    /// More flexibility, better memory optimization, and more idiomatic Rust code.
+    ///
+    /// `&Option<T>` in a function signature breaks encapsulation because the caller must own T
+    /// and move it into an Option to call with it. When returned, the owner must internally store
+    /// it as `Option<T>` in order to return it.
+    /// At a lower level, `&Option<T>` points to memory with the `presence` bit flag plus the `T` value,
+    /// whereas `Option<&T>` is usually [optimized](https://doc.rust-lang.org/1.81.0/std/option/index.html#representation)
+    /// to a single pointer, so it may be more optimal.
+    ///
+    /// See this [YouTube video](https://www.youtube.com/watch?v=6c7pZYP_iIE) by
+    /// Logan Smith for an in-depth explanation of why this is important.
+    ///
+    /// ### Known problems
+    /// This lint recommends changing the function signatures, but it cannot
+    /// automatically change the function calls or the function implementations.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// // caller uses  foo(&opt)
+    /// fn foo(a: &Option<String>) {}
+    /// # struct Unit {}
+    /// # impl Unit {
+    /// fn bar(&self) -> &Option<String> { &None }
+    /// # }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// // caller should use  `foo1(opt.as_ref())`
+    /// fn foo1(a: Option<&String>) {}
+    /// // better yet, use string slice  `foo2(opt.as_deref())`
+    /// fn foo2(a: Option<&str>) {}
+    /// # struct Unit {}
+    /// # impl Unit {
+    /// fn bar(&self) -> Option<&String> { None }
+    /// # }
+    /// ```
+    #[clippy::version = "1.82.0"]
+    pub REF_OPTION,
+    pedantic,
+    "function signature uses `&Option<T>` instead of `Option<&T>`"
+}
+
 pub struct Functions {
     too_many_arguments_threshold: u64,
     too_many_lines_threshold: u64,
@@ -437,6 +485,7 @@ impl_lint_pass!(Functions => [
     MISNAMED_GETTERS,
     IMPL_TRAIT_IN_PARAMS,
     RENAMED_FUNCTION_PARAMS,
+    REF_OPTION,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Functions {
@@ -455,6 +504,16 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
         not_unsafe_ptr_arg_deref::check_fn(cx, kind, decl, body, def_id);
         misnamed_getters::check_fn(cx, kind, decl, body, span);
         impl_trait_in_params::check_fn(cx, &kind, body, hir_id);
+        ref_option::check_fn(
+            cx,
+            kind,
+            decl,
+            span,
+            hir_id,
+            def_id,
+            body,
+            self.avoid_breaking_exported_api,
+        );
     }
 
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
@@ -475,5 +534,6 @@ impl<'tcx> LateLintPass<'tcx> for Functions {
         must_use::check_trait_item(cx, item);
         result::check_trait_item(cx, item, self.large_error_threshold);
         impl_trait_in_params::check_trait_item(cx, item, self.avoid_breaking_exported_api);
+        ref_option::check_trait_item(cx, item, self.avoid_breaking_exported_api);
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/functions/ref_option.rs b/src/tools/clippy/clippy_lints/src/functions/ref_option.rs
new file mode 100644
index 0000000000000..373ecd74cb379
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/functions/ref_option.rs
@@ -0,0 +1,122 @@
+use crate::functions::REF_OPTION;
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::is_trait_impl_item;
+use clippy_utils::source::snippet;
+use clippy_utils::ty::is_type_diagnostic_item;
+use rustc_errors::Applicability;
+use rustc_hir as hir;
+use rustc_hir::intravisit::FnKind;
+use rustc_hir::{FnDecl, HirId};
+use rustc_lint::LateContext;
+use rustc_middle::ty::{self, GenericArgKind, Mutability, Ty};
+use rustc_span::def_id::LocalDefId;
+use rustc_span::{Span, sym};
+
+fn check_ty<'a>(cx: &LateContext<'a>, param: &rustc_hir::Ty<'a>, param_ty: Ty<'a>, fixes: &mut Vec<(Span, String)>) {
+    if let ty::Ref(_, opt_ty, Mutability::Not) = param_ty.kind()
+        && is_type_diagnostic_item(cx, *opt_ty, sym::Option)
+        && let ty::Adt(_, opt_gen) = opt_ty.kind()
+        && let [gen] = opt_gen.as_slice()
+        && let GenericArgKind::Type(gen_ty) = gen.unpack()
+        && !gen_ty.is_ref()
+        // Need to gen the original spans, so first parsing mid, and hir parsing afterward
+        && let hir::TyKind::Ref(lifetime, hir::MutTy { ty, .. }) = param.kind
+        && let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
+        && let (Some(first), Some(last)) = (path.segments.first(), path.segments.last())
+        && let Some(hir::GenericArgs {
+            args: [hir::GenericArg::Type(opt_ty)],
+            ..
+        }) = last.args
+    {
+        let lifetime = snippet(cx, lifetime.ident.span, "..");
+        fixes.push((
+            param.span,
+            format!(
+                "{}<&{lifetime}{}{}>",
+                snippet(cx, first.ident.span.to(last.ident.span), ".."),
+                if lifetime.is_empty() { "" } else { " " },
+                snippet(cx, opt_ty.span, "..")
+            ),
+        ));
+    }
+}
+
+fn check_fn_sig<'a>(cx: &LateContext<'a>, decl: &FnDecl<'a>, span: Span, sig: ty::FnSig<'a>) {
+    let mut fixes = Vec::new();
+    // Check function arguments' types
+    for (param, param_ty) in decl.inputs.iter().zip(sig.inputs()) {
+        check_ty(cx, param, *param_ty, &mut fixes);
+    }
+    // Check return type
+    if let hir::FnRetTy::Return(ty) = &decl.output {
+        check_ty(cx, ty, sig.output(), &mut fixes);
+    }
+    if !fixes.is_empty() {
+        span_lint_and_then(
+            cx,
+            REF_OPTION,
+            span,
+            "it is more idiomatic to use `Option<&T>` instead of `&Option<T>`",
+            |diag| {
+                diag.multipart_suggestion("change this to", fixes, Applicability::Unspecified);
+            },
+        );
+    }
+}
+
+#[allow(clippy::too_many_arguments)]
+pub(crate) fn check_fn<'a>(
+    cx: &LateContext<'a>,
+    kind: FnKind<'_>,
+    decl: &FnDecl<'a>,
+    span: Span,
+    hir_id: HirId,
+    def_id: LocalDefId,
+    body: &hir::Body<'_>,
+    avoid_breaking_exported_api: bool,
+) {
+    if avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {
+        return;
+    }
+
+    if let FnKind::Closure = kind {
+        // Compute the span of the closure parameters + return type if set
+        let span = if let hir::FnRetTy::Return(out_ty) = &decl.output {
+            if decl.inputs.is_empty() {
+                out_ty.span
+            } else {
+                span.with_hi(out_ty.span.hi())
+            }
+        } else if let (Some(first), Some(last)) = (decl.inputs.first(), decl.inputs.last()) {
+            first.span.to(last.span)
+        } else {
+            // No parameters - no point in checking
+            return;
+        };
+
+        // Figure out the signature of the closure
+        let ty::Closure(_, args) = cx.typeck_results().expr_ty(body.value).kind() else {
+            return;
+        };
+        let sig = args.as_closure().sig().skip_binder();
+
+        check_fn_sig(cx, decl, span, sig);
+    } else if !is_trait_impl_item(cx, hir_id) {
+        let sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
+        check_fn_sig(cx, decl, span, sig);
+    }
+}
+
+pub(super) fn check_trait_item<'a>(
+    cx: &LateContext<'a>,
+    trait_item: &hir::TraitItem<'a>,
+    avoid_breaking_exported_api: bool,
+) {
+    if let hir::TraitItemKind::Fn(ref sig, _) = trait_item.kind
+        && !(avoid_breaking_exported_api && cx.effective_visibilities.is_exported(trait_item.owner_id.def_id))
+    {
+        let def_id = trait_item.owner_id.def_id;
+        let ty_sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
+        check_fn_sig(cx, sig.decl, sig.span, ty_sig);
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
index f683925145a28..4c5375730b8e3 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
@@ -281,7 +281,7 @@ impl<'a, 'tcx> ImplicitHasherTypeVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for ImplicitHasherTypeVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for ImplicitHasherTypeVisitor<'_, 'tcx> {
     fn visit_ty(&mut self, t: &'tcx hir::Ty<'_>) {
         if let Some(target) = ImplicitHasherType::new(self.cx, t) {
             self.found.push(target);
@@ -318,7 +318,7 @@ impl<'a, 'b, 'tcx> ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> {
     }
 }
 
-impl<'a, 'b, 'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'a, 'b, 'tcx> {
+impl<'tcx> Visitor<'tcx> for ImplicitHasherConstructorVisitor<'_, '_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_body(&mut self, body: &Body<'tcx>) {
diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
index 39afb6810b8e2..73ebe6aec15a0 100644
--- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
+++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
@@ -226,7 +226,7 @@ struct SliceIndexLintingVisitor<'a, 'tcx> {
     max_suggested_slice: u64,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn nested_visit_map(&mut self) -> Self::Map {
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 8bc2a56af9938..c88eb70384333 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -460,7 +460,7 @@ fn check_for_is_empty(
     let is_empty = cx
         .tcx
         .inherent_impls(impl_ty)
-        .into_iter()
+        .iter()
         .flat_map(|&id| cx.tcx.associated_items(id).filter_by_name_unhygienic(is_empty))
         .find(|item| item.kind == AssocKind::Fn);
 
@@ -628,7 +628,7 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     /// Checks the inherent impl's items for an `is_empty(self)` method.
     fn has_is_empty_impl(cx: &LateContext<'_>, id: DefId) -> bool {
         let is_empty = sym!(is_empty);
-        cx.tcx.inherent_impls(id).into_iter().any(|imp| {
+        cx.tcx.inherent_impls(id).iter().any(|imp| {
             cx.tcx
                 .associated_items(*imp)
                 .filter_by_name_unhygienic(is_empty)
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 1d41f568f3785..2eb6d99b761f7 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -609,7 +609,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(move |tcx| Box::new(await_holding_invalid::AwaitHolding::new(tcx, conf)));
     store.register_late_pass(|_| Box::new(serde_api::SerdeApi));
     store.register_late_pass(move |_| Box::new(types::Types::new(conf)));
-    store.register_late_pass(|_| Box::new(booleans::NonminimalBool));
+    store.register_late_pass(move |_| Box::new(booleans::NonminimalBool::new(conf)));
     store.register_late_pass(|_| Box::new(enum_clike::UnportableVariant));
     store.register_late_pass(|_| Box::new(float_literal::FloatLiteral));
     store.register_late_pass(|_| Box::new(ptr::Ptr));
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index 755afe959b37a..034cab7202523 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -6,12 +6,12 @@ use rustc_errors::Applicability;
 use rustc_hir::FnRetTy::Return;
 use rustc_hir::intravisit::nested_filter::{self as hir_nested_filter, NestedFilter};
 use rustc_hir::intravisit::{
-    Visitor, walk_fn_decl, walk_generic_param, walk_generics, walk_impl_item_ref, walk_item, walk_param_bound,
-    walk_poly_trait_ref, walk_trait_ref, walk_ty,
+    Visitor, walk_fn_decl, walk_generic_args, walk_generics, walk_impl_item_ref, walk_item, walk_param_bound,
+    walk_poly_trait_ref, walk_trait_ref, walk_ty, walk_where_predicate,
 };
 use rustc_hir::{
-    BareFnTy, BodyId, FnDecl, FnSig, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, Impl,
-    ImplItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, Node, PolyTraitRef,
+    BareFnTy, BodyId, FnDecl, FnSig, GenericArg, GenericArgs, GenericBound, GenericParam, GenericParamKind, Generics,
+    Impl, ImplItem, ImplItemKind, Item, ItemKind, Lifetime, LifetimeName, LifetimeParamKind, Node, PolyTraitRef,
     PredicateOrigin, TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate, lang_items,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -21,7 +21,7 @@ use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
 use rustc_span::Span;
 use rustc_span::def_id::LocalDefId;
-use rustc_span::symbol::{Ident, Symbol, kw};
+use rustc_span::symbol::{Ident, kw};
 use std::ops::ControlFlow;
 
 declare_clippy_lint! {
@@ -191,45 +191,10 @@ fn check_fn_inner<'tcx>(
         if usages.iter().any(|usage| !usage.ident.span.eq_ctxt(span)) {
             return;
         }
-
-        let lts = elidable_lts
-            .iter()
-            // In principle, the result of the call to `Node::ident` could be `unwrap`ped, as `DefId` should refer to a
-            // `Node::GenericParam`.
-            .filter_map(|&def_id| cx.tcx.hir_node_by_def_id(def_id).ident())
-            .map(|ident| ident.to_string())
-            .collect::<Vec<_>>()
-            .join(", ");
-
-        span_lint_and_then(
-            cx,
-            NEEDLESS_LIFETIMES,
-            elidable_lts
-                .iter()
-                .map(|&lt| cx.tcx.def_span(lt))
-                .chain(usages.iter().filter_map(|usage| {
-                    if let LifetimeName::Param(def_id) = usage.res
-                        && elidable_lts.contains(&def_id)
-                    {
-                        return Some(usage.ident.span);
-                    }
-
-                    None
-                }))
-                .collect_vec(),
-            format!("the following explicit lifetimes could be elided: {lts}"),
-            |diag| {
-                if sig.header.is_async() {
-                    // async functions have usages whose spans point at the lifetime declaration which messes up
-                    // suggestions
-                    return;
-                };
-
-                if let Some(suggestions) = elision_suggestions(cx, generics, &elidable_lts, &usages) {
-                    diag.multipart_suggestion("elide the lifetimes", suggestions, Applicability::MachineApplicable);
-                }
-            },
-        );
+        // async functions have usages whose spans point at the lifetime declaration which messes up
+        // suggestions
+        let include_suggestions = !sig.header.is_async();
+        report_elidable_lifetimes(cx, generics, &elidable_lts, &usages, include_suggestions);
     }
 
     if report_extra_lifetimes {
@@ -237,97 +202,6 @@ fn check_fn_inner<'tcx>(
     }
 }
 
-fn elision_suggestions(
-    cx: &LateContext<'_>,
-    generics: &Generics<'_>,
-    elidable_lts: &[LocalDefId],
-    usages: &[Lifetime],
-) -> Option<Vec<(Span, String)>> {
-    let explicit_params = generics
-        .params
-        .iter()
-        .filter(|param| !param.is_elided_lifetime() && !param.is_impl_trait())
-        .collect::<Vec<_>>();
-
-    let mut suggestions = if elidable_lts.len() == explicit_params.len() {
-        // if all the params are elided remove the whole generic block
-        //
-        // fn x<'a>() {}
-        //     ^^^^
-        vec![(generics.span, String::new())]
-    } else {
-        elidable_lts
-            .iter()
-            .map(|&id| {
-                let pos = explicit_params.iter().position(|param| param.def_id == id)?;
-                let param = explicit_params.get(pos)?;
-
-                let span = if let Some(next) = explicit_params.get(pos + 1) {
-                    // fn x<'prev, 'a, 'next>() {}
-                    //             ^^^^
-                    param.span.until(next.span)
-                } else {
-                    // `pos` should be at least 1 here, because the param in position 0 would either have a `next`
-                    // param or would have taken the `elidable_lts.len() == explicit_params.len()` branch.
-                    let prev = explicit_params.get(pos - 1)?;
-
-                    // fn x<'prev, 'a>() {}
-                    //           ^^^^
-                    param.span.with_lo(prev.span.hi())
-                };
-
-                Some((span, String::new()))
-            })
-            .collect::<Option<Vec<_>>>()?
-    };
-
-    suggestions.extend(
-        usages
-            .iter()
-            .filter(|usage| named_lifetime(usage).map_or(false, |id| elidable_lts.contains(&id)))
-            .map(|usage| {
-                match cx.tcx.parent_hir_node(usage.hir_id) {
-                    Node::Ty(Ty {
-                        kind: TyKind::Ref(..), ..
-                    }) => {
-                        // expand `&'a T` to `&'a T`
-                        //          ^^         ^^^
-                        let span = cx.sess().source_map().span_extend_while_whitespace(usage.ident.span);
-
-                        (span, String::new())
-                    },
-                    // `T<'a>` and `impl Foo + 'a` should be replaced by `'_`
-                    _ => (usage.ident.span, String::from("'_")),
-                }
-            }),
-    );
-
-    Some(suggestions)
-}
-
-// elision doesn't work for explicit self types, see rust-lang/rust#69064
-fn explicit_self_type<'tcx>(cx: &LateContext<'tcx>, func: &FnDecl<'tcx>, ident: Option<Ident>) -> bool {
-    if let Some(ident) = ident
-        && ident.name == kw::SelfLower
-        && !func.implicit_self.has_implicit_self()
-        && let Some(self_ty) = func.inputs.first()
-    {
-        let mut visitor = RefVisitor::new(cx);
-        visitor.visit_ty(self_ty);
-
-        !visitor.all_lts().is_empty()
-    } else {
-        false
-    }
-}
-
-fn named_lifetime(lt: &Lifetime) -> Option<LocalDefId> {
-    match lt.res {
-        LifetimeName::Param(id) if !lt.is_anonymous() => Some(id),
-        _ => None,
-    }
-}
-
 fn could_use_elision<'tcx>(
     cx: &LateContext<'tcx>,
     func: &'tcx FnDecl<'_>,
@@ -450,6 +324,22 @@ fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxHashSet<LocalDefId
         .collect()
 }
 
+// elision doesn't work for explicit self types, see rust-lang/rust#69064
+fn explicit_self_type<'tcx>(cx: &LateContext<'tcx>, func: &FnDecl<'tcx>, ident: Option<Ident>) -> bool {
+    if let Some(ident) = ident
+        && ident.name == kw::SelfLower
+        && !func.implicit_self.has_implicit_self()
+        && let Some(self_ty) = func.inputs.first()
+    {
+        let mut visitor = RefVisitor::new(cx);
+        visitor.visit_ty(self_ty);
+
+        !visitor.all_lts().is_empty()
+    } else {
+        false
+    }
+}
+
 /// Number of times each named lifetime occurs in the given slice. Returns a vector to preserve
 /// relative order.
 #[must_use]
@@ -470,6 +360,13 @@ fn named_lifetime_occurrences(lts: &[Lifetime]) -> Vec<(LocalDefId, usize)> {
     occurrences
 }
 
+fn named_lifetime(lt: &Lifetime) -> Option<LocalDefId> {
+    match lt.res {
+        LifetimeName::Param(id) if !lt.is_anonymous() => Some(id),
+        _ => None,
+    }
+}
+
 struct RefVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
     lts: Vec<Lifetime>,
@@ -500,7 +397,7 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for RefVisitor<'_, 'tcx> {
     // for lifetimes as parameters of generics
     fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
         self.lts.push(*lifetime);
@@ -594,23 +491,43 @@ fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_
     false
 }
 
+struct Usage {
+    lifetime: Lifetime,
+    in_where_predicate: bool,
+    in_generics_arg: bool,
+}
+
 struct LifetimeChecker<'cx, 'tcx, F> {
     cx: &'cx LateContext<'tcx>,
-    map: FxHashMap<Symbol, Span>,
+    map: FxHashMap<LocalDefId, Vec<Usage>>,
+    where_predicate_depth: usize,
+    generic_args_depth: usize,
     phantom: std::marker::PhantomData<F>,
 }
 
 impl<'cx, 'tcx, F> LifetimeChecker<'cx, 'tcx, F> {
-    fn new(cx: &'cx LateContext<'tcx>, map: FxHashMap<Symbol, Span>) -> LifetimeChecker<'cx, 'tcx, F> {
+    fn new(cx: &'cx LateContext<'tcx>, generics: &'tcx Generics<'_>) -> LifetimeChecker<'cx, 'tcx, F> {
+        let map = generics
+            .params
+            .iter()
+            .filter_map(|par| match par.kind {
+                GenericParamKind::Lifetime {
+                    kind: LifetimeParamKind::Explicit,
+                } => Some((par.def_id, Vec::new())),
+                _ => None,
+            })
+            .collect();
         Self {
             cx,
             map,
+            where_predicate_depth: 0,
+            generic_args_depth: 0,
             phantom: std::marker::PhantomData,
         }
     }
 }
 
-impl<'cx, 'tcx, F> Visitor<'tcx> for LifetimeChecker<'cx, 'tcx, F>
+impl<'tcx, F> Visitor<'tcx> for LifetimeChecker<'_, 'tcx, F>
 where
     F: NestedFilter<'tcx>,
 {
@@ -619,18 +536,27 @@ where
 
     // for lifetimes as parameters of generics
     fn visit_lifetime(&mut self, lifetime: &'tcx Lifetime) {
-        self.map.remove(&lifetime.ident.name);
+        if let LifetimeName::Param(def_id) = lifetime.res
+            && let Some(usages) = self.map.get_mut(&def_id)
+        {
+            usages.push(Usage {
+                lifetime: *lifetime,
+                in_where_predicate: self.where_predicate_depth != 0,
+                in_generics_arg: self.generic_args_depth != 0,
+            });
+        }
     }
 
-    fn visit_generic_param(&mut self, param: &'tcx GenericParam<'_>) {
-        // don't actually visit `<'a>` or `<'a: 'b>`
-        // we've already visited the `'a` declarations and
-        // don't want to spuriously remove them
-        // `'b` in `'a: 'b` is useless unless used elsewhere in
-        // a non-lifetime bound
-        if let GenericParamKind::Type { .. } = param.kind {
-            walk_generic_param(self, param);
-        }
+    fn visit_where_predicate(&mut self, predicate: &'tcx WherePredicate<'tcx>) {
+        self.where_predicate_depth += 1;
+        walk_where_predicate(self, predicate);
+        self.where_predicate_depth -= 1;
+    }
+
+    fn visit_generic_args(&mut self, generic_args: &'tcx GenericArgs<'tcx>) -> Self::Result {
+        self.generic_args_depth += 1;
+        walk_generic_args(self, generic_args);
+        self.generic_args_depth -= 1;
     }
 
     fn nested_visit_map(&mut self) -> Self::Map {
@@ -639,44 +565,28 @@ where
 }
 
 fn report_extra_lifetimes<'tcx>(cx: &LateContext<'tcx>, func: &'tcx FnDecl<'_>, generics: &'tcx Generics<'_>) {
-    let hs = generics
-        .params
-        .iter()
-        .filter_map(|par| match par.kind {
-            GenericParamKind::Lifetime {
-                kind: LifetimeParamKind::Explicit,
-            } => Some((par.name.ident().name, par.span)),
-            _ => None,
-        })
-        .collect();
-    let mut checker = LifetimeChecker::<hir_nested_filter::None>::new(cx, hs);
+    let mut checker = LifetimeChecker::<hir_nested_filter::None>::new(cx, generics);
 
     walk_generics(&mut checker, generics);
     walk_fn_decl(&mut checker, func);
 
-    for &v in checker.map.values() {
-        span_lint(
-            cx,
-            EXTRA_UNUSED_LIFETIMES,
-            v,
-            "this lifetime isn't used in the function definition",
-        );
+    for (def_id, usages) in checker.map {
+        if usages
+            .iter()
+            .all(|usage| usage.in_where_predicate && !usage.in_generics_arg)
+        {
+            span_lint(
+                cx,
+                EXTRA_UNUSED_LIFETIMES,
+                cx.tcx.def_span(def_id),
+                "this lifetime isn't used in the function definition",
+            );
+        }
     }
 }
 
 fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'_>) {
-    let hs = impl_
-        .generics
-        .params
-        .iter()
-        .filter_map(|par| match par.kind {
-            GenericParamKind::Lifetime {
-                kind: LifetimeParamKind::Explicit,
-            } => Some((par.name.ident().name, par.span)),
-            _ => None,
-        })
-        .collect();
-    let mut checker = LifetimeChecker::<middle_nested_filter::All>::new(cx, hs);
+    let mut checker = LifetimeChecker::<middle_nested_filter::All>::new(cx, impl_.generics);
 
     walk_generics(&mut checker, impl_.generics);
     if let Some(ref trait_ref) = impl_.of_trait {
@@ -687,9 +597,176 @@ fn report_extra_impl_lifetimes<'tcx>(cx: &LateContext<'tcx>, impl_: &'tcx Impl<'
         walk_impl_item_ref(&mut checker, item);
     }
 
-    for &v in checker.map.values() {
-        span_lint(cx, EXTRA_UNUSED_LIFETIMES, v, "this lifetime isn't used in the impl");
+    for (&def_id, usages) in &checker.map {
+        if usages
+            .iter()
+            .all(|usage| usage.in_where_predicate && !usage.in_generics_arg)
+        {
+            span_lint(
+                cx,
+                EXTRA_UNUSED_LIFETIMES,
+                cx.tcx.def_span(def_id),
+                "this lifetime isn't used in the impl",
+            );
+        }
+    }
+
+    report_elidable_impl_lifetimes(cx, impl_, &checker.map);
+}
+
+// An `impl` lifetime is elidable if it satisfies the following conditions:
+// - It is used exactly once.
+// - That single use is not in `GenericArgs` in a `WherePredicate`. (Note that `GenericArgs` are
+//   different from `GenericParam`s.)
+fn report_elidable_impl_lifetimes<'tcx>(
+    cx: &LateContext<'tcx>,
+    impl_: &'tcx Impl<'_>,
+    map: &FxHashMap<LocalDefId, Vec<Usage>>,
+) {
+    let single_usages = map
+        .iter()
+        .filter_map(|(def_id, usages)| {
+            if let [
+                Usage {
+                    lifetime,
+                    in_where_predicate: false,
+                    ..
+                }
+                | Usage {
+                    lifetime,
+                    in_generics_arg: false,
+                    ..
+                },
+            ] = usages.as_slice()
+            {
+                Some((def_id, lifetime))
+            } else {
+                None
+            }
+        })
+        .collect::<Vec<_>>();
+
+    if single_usages.is_empty() {
+        return;
     }
+
+    let (elidable_lts, usages): (Vec<_>, Vec<_>) = single_usages.into_iter().unzip();
+
+    report_elidable_lifetimes(cx, impl_.generics, &elidable_lts, &usages, true);
+}
+
+/// Generate diagnostic messages for elidable lifetimes.
+fn report_elidable_lifetimes(
+    cx: &LateContext<'_>,
+    generics: &Generics<'_>,
+    elidable_lts: &[LocalDefId],
+    usages: &[Lifetime],
+    include_suggestions: bool,
+) {
+    let lts = elidable_lts
+        .iter()
+        // In principle, the result of the call to `Node::ident` could be `unwrap`ped, as `DefId` should refer to a
+        // `Node::GenericParam`.
+        .filter_map(|&def_id| cx.tcx.hir_node_by_def_id(def_id).ident())
+        .map(|ident| ident.to_string())
+        .collect::<Vec<_>>()
+        .join(", ");
+
+    span_lint_and_then(
+        cx,
+        NEEDLESS_LIFETIMES,
+        elidable_lts
+            .iter()
+            .map(|&lt| cx.tcx.def_span(lt))
+            .chain(usages.iter().filter_map(|usage| {
+                if let LifetimeName::Param(def_id) = usage.res
+                    && elidable_lts.contains(&def_id)
+                {
+                    return Some(usage.ident.span);
+                }
+
+                None
+            }))
+            .collect_vec(),
+        format!("the following explicit lifetimes could be elided: {lts}"),
+        |diag| {
+            if !include_suggestions {
+                return;
+            };
+
+            if let Some(suggestions) = elision_suggestions(cx, generics, elidable_lts, usages) {
+                diag.multipart_suggestion("elide the lifetimes", suggestions, Applicability::MachineApplicable);
+            }
+        },
+    );
+}
+
+fn elision_suggestions(
+    cx: &LateContext<'_>,
+    generics: &Generics<'_>,
+    elidable_lts: &[LocalDefId],
+    usages: &[Lifetime],
+) -> Option<Vec<(Span, String)>> {
+    let explicit_params = generics
+        .params
+        .iter()
+        .filter(|param| !param.is_elided_lifetime() && !param.is_impl_trait())
+        .collect::<Vec<_>>();
+
+    let mut suggestions = if elidable_lts.len() == explicit_params.len() {
+        // if all the params are elided remove the whole generic block
+        //
+        // fn x<'a>() {}
+        //     ^^^^
+        vec![(generics.span, String::new())]
+    } else {
+        elidable_lts
+            .iter()
+            .map(|&id| {
+                let pos = explicit_params.iter().position(|param| param.def_id == id)?;
+                let param = explicit_params.get(pos)?;
+
+                let span = if let Some(next) = explicit_params.get(pos + 1) {
+                    // fn x<'prev, 'a, 'next>() {}
+                    //             ^^^^
+                    param.span.until(next.span)
+                } else {
+                    // `pos` should be at least 1 here, because the param in position 0 would either have a `next`
+                    // param or would have taken the `elidable_lts.len() == explicit_params.len()` branch.
+                    let prev = explicit_params.get(pos - 1)?;
+
+                    // fn x<'prev, 'a>() {}
+                    //           ^^^^
+                    param.span.with_lo(prev.span.hi())
+                };
+
+                Some((span, String::new()))
+            })
+            .collect::<Option<Vec<_>>>()?
+    };
+
+    suggestions.extend(
+        usages
+            .iter()
+            .filter(|usage| named_lifetime(usage).map_or(false, |id| elidable_lts.contains(&id)))
+            .map(|usage| {
+                match cx.tcx.parent_hir_node(usage.hir_id) {
+                    Node::Ty(Ty {
+                        kind: TyKind::Ref(..), ..
+                    }) => {
+                        // expand `&'a T` to `&'a T`
+                        //          ^^         ^^^
+                        let span = cx.sess().source_map().span_extend_while_whitespace(usage.ident.span);
+
+                        (span, String::new())
+                    },
+                    // `T<'a>` and `impl Foo + 'a` should be replaced by `'_`
+                    _ => (usage.ident.span, String::from("'_")),
+                }
+            }),
+    );
+
+    Some(suggestions)
 }
 
 struct BodyLifetimeChecker;
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
index a7c1d1bd6cd36..68d063ad5e54e 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_memcpy.rs
@@ -209,7 +209,7 @@ fn build_manual_memcpy_suggestion<'tcx>(
 #[derive(Clone)]
 struct MinifyingSugg<'a>(Sugg<'a>);
 
-impl<'a> Display for MinifyingSugg<'a> {
+impl Display for MinifyingSugg<'_> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         self.0.fmt(f)
     }
diff --git a/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs b/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs
index e405829b2f4ba..a9944d64ce2dd 100644
--- a/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs
@@ -1,6 +1,6 @@
 use super::MISSING_SPIN_LOOP;
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::is_no_std_crate;
+use clippy_utils::std_or_core;
 use rustc_errors::Applicability;
 use rustc_hir::{Block, Expr, ExprKind};
 use rustc_lint::LateContext;
@@ -41,6 +41,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, body: &'
         && [sym::load, sym::compare_exchange, sym::compare_exchange_weak].contains(&method.ident.name)
         && let ty::Adt(def, _args) = cx.typeck_results().expr_ty(callee).kind()
         && cx.tcx.is_diagnostic_item(sym::AtomicBool, def.did())
+        && let Some(std_or_core) = std_or_core(cx)
     {
         span_lint_and_sugg(
             cx,
@@ -48,12 +49,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, body: &'
             body.span,
             "busy-waiting loop should at least have a spin loop hint",
             "try",
-            (if is_no_std_crate(cx) {
-                "{ core::hint::spin_loop() }"
-            } else {
-                "{ std::hint::spin_loop() }"
-            })
-            .into(),
+            format!("{{ {std_or_core}::hint::spin_loop() }}"),
             Applicability::MachineApplicable,
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
index 20dd5a311dca0..745f070a577d5 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
@@ -241,7 +241,7 @@ struct VarVisitor<'a, 'tcx> {
     prefer_mutable: bool,
 }
 
-impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
+impl<'tcx> VarVisitor<'_, 'tcx> {
     fn check(&mut self, idx: &'tcx Expr<'_>, seqexpr: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) -> bool {
         if let ExprKind::Path(ref seqpath) = seqexpr.kind
             // the indexed container is referenced by a name
@@ -292,7 +292,7 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for VarVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
         if let ExprKind::MethodCall(meth, args_0, [args_1, ..], _) = &expr.kind
             // a range index op
diff --git a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
index 5662d3013e15b..f8659897ffe97 100644
--- a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
@@ -123,7 +123,7 @@ impl<'a, 'tcx> SameItemPushVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for SameItemPushVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for SameItemPushVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
         match &expr.kind {
             // Non-determinism may occur ... don't give a lint
diff --git a/src/tools/clippy/clippy_lints/src/loops/utils.rs b/src/tools/clippy/clippy_lints/src/loops/utils.rs
index 9a89a41d2b395..c4c504e1ae4ff 100644
--- a/src/tools/clippy/clippy_lints/src/loops/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/utils.rs
@@ -44,7 +44,7 @@ impl<'a, 'tcx> IncrementVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for IncrementVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for IncrementVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
         // If node is a variable
         if let Some(def_id) = path_to_local(expr) {
@@ -138,7 +138,7 @@ impl<'a, 'tcx> InitializeVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for InitializeVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_local(&mut self, l: &'tcx LetStmt<'_>) {
diff --git a/src/tools/clippy/clippy_lints/src/loops/while_immutable_condition.rs b/src/tools/clippy/clippy_lints/src/loops/while_immutable_condition.rs
index eab096e9a227d..1a1cde3c5bd63 100644
--- a/src/tools/clippy/clippy_lints/src/loops/while_immutable_condition.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/while_immutable_condition.rs
@@ -84,7 +84,7 @@ struct VarCollectorVisitor<'a, 'tcx> {
     skip: bool,
 }
 
-impl<'a, 'tcx> VarCollectorVisitor<'a, 'tcx> {
+impl<'tcx> VarCollectorVisitor<'_, 'tcx> {
     fn insert_def_id(&mut self, ex: &'tcx Expr<'_>) {
         if let ExprKind::Path(ref qpath) = ex.kind
             && let QPath::Resolved(None, _) = *qpath
@@ -103,7 +103,7 @@ impl<'a, 'tcx> VarCollectorVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for VarCollectorVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for VarCollectorVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, ex: &'tcx Expr<'_>) {
         match ex.kind {
             ExprKind::Path(_) => self.insert_def_id(ex),
diff --git a/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs b/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs
index 7d9fbaf3ceabf..74467522619e9 100644
--- a/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/while_let_on_iterator.rs
@@ -283,7 +283,7 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &
         found_local: bool,
         used_after: bool,
     }
-    impl<'a, 'b, 'tcx> Visitor<'tcx> for NestedLoopVisitor<'a, 'b, 'tcx> {
+    impl<'tcx> Visitor<'tcx> for NestedLoopVisitor<'_, '_, 'tcx> {
         type NestedFilter = OnlyBodies;
         fn nested_visit_map(&mut self) -> Self::Map {
             self.cx.tcx.hir()
diff --git a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs
index ccc554042d685..312bcb55a9533 100644
--- a/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs
+++ b/src/tools/clippy/clippy_lints/src/macro_metavars_in_unsafe.rs
@@ -149,7 +149,7 @@ fn is_public_macro(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {
         && !cx.tcx.is_doc_hidden(def_id)
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for BodyVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for BodyVisitor<'_, 'tcx> {
     fn visit_stmt(&mut self, s: &'tcx Stmt<'tcx>) {
         let from_expn = s.span.from_expansion();
         if from_expn {
diff --git a/src/tools/clippy/clippy_lints/src/macro_use.rs b/src/tools/clippy/clippy_lints/src/macro_use.rs
index bd6b3f1a47b16..50680331fbc4e 100644
--- a/src/tools/clippy/clippy_lints/src/macro_use.rs
+++ b/src/tools/clippy/clippy_lints/src/macro_use.rs
@@ -81,7 +81,7 @@ impl MacroUseImports {
     }
 }
 
-impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
+impl LateLintPass<'_> for MacroUseImports {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
         if cx.sess().opts.edition >= Edition::Edition2018
             && let hir::ItemKind::Use(path, _kind) = &item.kind
diff --git a/src/tools/clippy/clippy_lints/src/manual_clamp.rs b/src/tools/clippy/clippy_lints/src/manual_clamp.rs
index 788649fd4f90e..fd66cacdfe933 100644
--- a/src/tools/clippy/clippy_lints/src/manual_clamp.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_clamp.rs
@@ -741,7 +741,7 @@ enum MaybeBorrowedStmtKind<'a> {
     Owned(StmtKind<'a>),
 }
 
-impl<'a> Clone for MaybeBorrowedStmtKind<'a> {
+impl Clone for MaybeBorrowedStmtKind<'_> {
     fn clone(&self) -> Self {
         match self {
             Self::Borrowed(t) => Self::Borrowed(t),
diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs
index 9aceca66bf774..828c5a3f6ffd2 100644
--- a/src/tools/clippy/clippy_lints/src/manual_strip.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs
@@ -203,7 +203,7 @@ fn find_stripping<'tcx>(
         results: Vec<Span>,
     }
 
-    impl<'a, 'tcx> Visitor<'tcx> for StrippingFinder<'a, 'tcx> {
+    impl<'tcx> Visitor<'tcx> for StrippingFinder<'_, 'tcx> {
         fn visit_expr(&mut self, ex: &'tcx Expr<'_>) {
             if is_ref_str(self.cx, ex)
                 && let unref = peel_ref(ex)
diff --git a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
index a97dbbbc33fd0..3221a04d2d03f 100644
--- a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
@@ -251,7 +251,7 @@ fn lint_map_unit_fn(
     }
 }
 
-impl<'tcx> LateLintPass<'tcx> for MapUnit {
+impl LateLintPass<'_> for MapUnit {
     fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &hir::Stmt<'_>) {
         if let hir::StmtKind::Semi(expr) = stmt.kind
             && !stmt.span.from_expansion()
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs b/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
index 40518ce2ca775..463aa602bc8b9 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
@@ -40,7 +40,7 @@ struct MatchExprVisitor<'a, 'tcx> {
     case_method: Option<CaseMethod>,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for MatchExprVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for MatchExprVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, ex: &'tcx Expr<'_>) {
         match ex.kind {
             ExprKind::MethodCall(segment, receiver, [], _) if self.case_altered(segment.ident.as_str(), receiver) => {},
@@ -49,7 +49,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchExprVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> MatchExprVisitor<'a, 'tcx> {
+impl MatchExprVisitor<'_, '_> {
     fn case_altered(&mut self, segment_ident: &str, receiver: &Expr<'_>) -> bool {
         if let Some(case_method) = get_case_method(segment_ident) {
             let ty = self.cx.typeck_results().expr_ty(receiver).peel_refs();
diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs
index 686fc4a0fa0a5..28adcc2f22746 100644
--- a/src/tools/clippy/clippy_lints/src/matches/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs
@@ -1045,7 +1045,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
             if !from_expansion {
                 // These don't depend on a relationship between multiple arms
                 match_wild_err_arm::check(cx, ex, arms);
-                wild_in_or_pats::check(cx, arms);
+                wild_in_or_pats::check(cx, ex, arms);
             }
 
             if let MatchSource::TryDesugar(_) = source {
diff --git a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
index 6a4c553cee0ee..856311899f268 100644
--- a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
@@ -96,13 +96,13 @@ where
     #[derive(Copy, Clone, Debug, Eq, PartialEq)]
     struct RangeBound<'a, T>(T, BoundKind, &'a SpannedRange<T>);
 
-    impl<'a, T: Copy + Ord> PartialOrd for RangeBound<'a, T> {
+    impl<T: Copy + Ord> PartialOrd for RangeBound<'_, T> {
         fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
             Some(self.cmp(other))
         }
     }
 
-    impl<'a, T: Copy + Ord> Ord for RangeBound<'a, T> {
+    impl<T: Copy + Ord> Ord for RangeBound<'_, T> {
         fn cmp(&self, RangeBound(other_value, other_kind, _): &Self) -> Ordering {
             let RangeBound(self_value, self_kind, _) = *self;
             (self_value, self_kind).cmp(&(*other_value, *other_kind))
diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
index 537f7272f7f34..7372f52e1e5bd 100644
--- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
@@ -424,7 +424,7 @@ fn ty_has_erased_regions(ty: Ty<'_>) -> bool {
     ty.visit_with(&mut V).is_break()
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for SigDropHelper<'_, 'tcx> {
     fn visit_expr(&mut self, ex: &'tcx Expr<'_>) {
         // We've emitted a lint on some neighborhood expression. That lint will suggest to move out the
         // _parent_ expression (not the expression itself). Since we decide to move out the parent
@@ -495,7 +495,7 @@ fn has_significant_drop_in_arms<'tcx>(cx: &LateContext<'tcx>, arms: &[&'tcx Expr
     helper.found_sig_drop_spans
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for ArmSigDropHelper<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for ArmSigDropHelper<'_, 'tcx> {
     fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
         if self.sig_drop_checker.is_sig_drop_expr(ex) {
             self.found_sig_drop_spans.insert(ex.span);
diff --git a/src/tools/clippy/clippy_lints/src/matches/wild_in_or_pats.rs b/src/tools/clippy/clippy_lints/src/matches/wild_in_or_pats.rs
index 459513e65bfad..390ba889fd2e6 100644
--- a/src/tools/clippy/clippy_lints/src/matches/wild_in_or_pats.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/wild_in_or_pats.rs
@@ -1,11 +1,19 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::is_wild;
-use rustc_hir::{Arm, PatKind};
+use clippy_utils::{has_non_exhaustive_attr, is_wild};
+use rustc_hir::{Arm, Expr, PatKind};
 use rustc_lint::LateContext;
+use rustc_middle::ty;
 
 use super::WILDCARD_IN_OR_PATTERNS;
 
-pub(crate) fn check(cx: &LateContext<'_>, arms: &[Arm<'_>]) {
+pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arms: &[Arm<'_>]) {
+    // first check if we are matching on an enum that has the non_exhaustive attribute
+    let ty = cx.typeck_results().expr_ty(expr).peel_refs();
+    if let ty::Adt(adt_def, _) = ty.kind()
+        && has_non_exhaustive_attr(cx.tcx, *adt_def)
+    {
+        return;
+    };
     for arm in arms {
         if let PatKind::Or(fields) = arm.pat.kind {
             // look for multiple fields in this arm that contains at least one Wild pattern
diff --git a/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs b/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs
index 83e8370f939bc..320523aceb675 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs
@@ -1,17 +1,17 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::expr_custom_deref_adjustment;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::{is_type_diagnostic_item, peel_mid_ty_refs_is_mutable};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, Mutability};
 use rustc_lint::LateContext;
-use rustc_middle::ty;
 use rustc_span::{Span, sym};
 
 use super::MUT_MUTEX_LOCK;
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'tcx>, recv: &'tcx Expr<'tcx>, name_span: Span) {
     if matches!(expr_custom_deref_adjustment(cx, recv), None | Some(Mutability::Mut))
-        && let ty::Ref(_, _, Mutability::Mut) = cx.typeck_results().expr_ty(recv).kind()
+        && let (_, ref_depth, Mutability::Mut) = peel_mid_ty_refs_is_mutable(cx.typeck_results().expr_ty(recv))
+        && ref_depth >= 1
         && let Some(method_id) = cx.typeck_results().type_dependent_def_id(ex.hir_id)
         && let Some(impl_id) = cx.tcx.impl_of_method(method_id)
         && is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::Mutex)
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
index 421c7a5e070d9..c58e27e37ad31 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
@@ -441,7 +441,7 @@ struct UsedCountVisitor<'a, 'tcx> {
     count: usize,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for UsedCountVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for UsedCountVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
index b160ab6de8e95..528e2204cf8f7 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
@@ -130,7 +130,7 @@ struct UnwrapVisitor<'a, 'tcx> {
     identifiers: FxHashSet<HirId>,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for UnwrapVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for UnwrapVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::All;
 
     fn visit_path(&mut self, path: &Path<'tcx>, _: HirId) {
@@ -154,7 +154,7 @@ struct ReferenceVisitor<'a, 'tcx> {
     unwrap_or_span: Span,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for ReferenceVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for ReferenceVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::All;
     type Result = ControlFlow<()>;
     fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'_>) -> ControlFlow<()> {
diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
index c60a839432c97..b971f60d41699 100644
--- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
@@ -77,7 +77,7 @@ pub(super) fn check<'tcx>(
         let Some(suggested_method_def_id) = receiver_ty.ty_adt_def().and_then(|adt_def| {
             cx.tcx
                 .inherent_impls(adt_def.did())
-                .into_iter()
+                .iter()
                 .flat_map(|impl_id| cx.tcx.associated_items(impl_id).filter_by_name_unhygienic(sugg))
                 .find_map(|assoc| {
                     if assoc.fn_has_self_parameter
diff --git a/src/tools/clippy/clippy_lints/src/methods/utils.rs b/src/tools/clippy/clippy_lints/src/methods/utils.rs
index 4e33dc1df54d8..cf0ee569f1310 100644
--- a/src/tools/clippy/clippy_lints/src/methods/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/utils.rs
@@ -86,7 +86,7 @@ struct CloneOrCopyVisitor<'cx, 'tcx> {
     references_to_binding: Vec<(Span, String)>,
 }
 
-impl<'cx, 'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'cx, 'tcx> {
+impl<'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn nested_visit_map(&mut self) -> Self::Map {
@@ -123,7 +123,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'cx, 'tcx> {
     }
 }
 
-impl<'cx, 'tcx> CloneOrCopyVisitor<'cx, 'tcx> {
+impl<'tcx> CloneOrCopyVisitor<'_, 'tcx> {
     fn is_binding(&self, expr: &Expr<'tcx>) -> bool {
         self.binding_hir_ids
             .iter()
diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
index d333b71edb1ae..a7452c8a3c84e 100644
--- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
+++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -116,7 +116,7 @@ struct DivergenceVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
 }
 
-impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> {
+impl<'tcx> DivergenceVisitor<'_, 'tcx> {
     fn maybe_walk_expr(&mut self, e: &'tcx Expr<'_>) {
         match e.kind {
             ExprKind::Closure(..) | ExprKind::If(..) | ExprKind::Loop(..) => {},
@@ -148,7 +148,7 @@ fn stmt_might_diverge(stmt: &Stmt<'_>) -> bool {
     !matches!(stmt.kind, StmtKind::Item(..))
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for DivergenceVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
         match e.kind {
             // fix #10776
@@ -321,7 +321,7 @@ struct ReadVisitor<'a, 'tcx> {
     last_expr: &'tcx Expr<'tcx>,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for ReadVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
         if expr.hir_id == self.last_expr.hir_id {
             return;
diff --git a/src/tools/clippy/clippy_lints/src/mut_mut.rs b/src/tools/clippy/clippy_lints/src/mut_mut.rs
index 60372121a7a4c..6cddd7ea813b2 100644
--- a/src/tools/clippy/clippy_lints/src/mut_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_mut.rs
@@ -55,7 +55,7 @@ pub struct MutVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
 }
 
-impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> {
+impl<'tcx> intravisit::Visitor<'tcx> for MutVisitor<'_, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx hir::Expr<'_>) {
         if in_external_macro(self.cx.sess(), expr.span) {
             return;
diff --git a/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs b/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs
index 785bf70a3ec9f..152635a5c35c7 100644
--- a/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs
+++ b/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs
@@ -87,7 +87,7 @@ impl<'a, 'tcx> MutArgVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for MutArgVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for MutArgVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
diff --git a/src/tools/clippy/clippy_lints/src/needless_for_each.rs b/src/tools/clippy/clippy_lints/src/needless_for_each.rs
index b54eb164e81d5..93e20f37ef8ac 100644
--- a/src/tools/clippy/clippy_lints/src/needless_for_each.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_for_each.rs
@@ -133,7 +133,7 @@ struct RetCollector {
     loop_depth: u16,
 }
 
-impl<'tcx> Visitor<'tcx> for RetCollector {
+impl Visitor<'_> for RetCollector {
     fn visit_expr(&mut self, expr: &Expr<'_>) {
         match expr.kind {
             ExprKind::Ret(..) => {
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
index 19cbf59590840..c2facb2fcf68c 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
@@ -311,7 +311,7 @@ struct MutablyUsedVariablesCtxt<'tcx> {
     tcx: TyCtxt<'tcx>,
 }
 
-impl<'tcx> MutablyUsedVariablesCtxt<'tcx> {
+impl MutablyUsedVariablesCtxt<'_> {
     fn add_mutably_used_var(&mut self, used_id: HirId) {
         self.mutably_used_vars.insert(used_id);
     }
diff --git a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
index d85032e9eee84..2fee1c72a91b5 100644
--- a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
+++ b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
@@ -104,7 +104,7 @@ struct SimilarNamesLocalVisitor<'a, 'tcx> {
     single_char_names: Vec<Vec<Ident>>,
 }
 
-impl<'a, 'tcx> SimilarNamesLocalVisitor<'a, 'tcx> {
+impl SimilarNamesLocalVisitor<'_, '_> {
     fn check_single_char_names(&self) {
         if self.single_char_names.last().map(Vec::len) == Some(0) {
             return;
@@ -152,7 +152,7 @@ fn chars_are_similar(a: char, b: char) -> bool {
 
 struct SimilarNamesNameVisitor<'a, 'tcx, 'b>(&'b mut SimilarNamesLocalVisitor<'a, 'tcx>);
 
-impl<'a, 'tcx, 'b> Visitor<'tcx> for SimilarNamesNameVisitor<'a, 'tcx, 'b> {
+impl<'tcx> Visitor<'tcx> for SimilarNamesNameVisitor<'_, 'tcx, '_> {
     fn visit_pat(&mut self, pat: &'tcx Pat) {
         match pat.kind {
             PatKind::Ident(_, ident, _) => {
@@ -189,7 +189,7 @@ fn allowed_to_be_similar(interned_name: &str, list: &[&str]) -> bool {
         .any(|&name| interned_name.starts_with(name) || interned_name.ends_with(name))
 }
 
-impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> {
+impl SimilarNamesNameVisitor<'_, '_, '_> {
     fn check_short_ident(&mut self, ident: Ident) {
         // Ignore shadowing
         if self
@@ -329,7 +329,7 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> {
     }
 }
 
-impl<'a, 'b> SimilarNamesLocalVisitor<'a, 'b> {
+impl SimilarNamesLocalVisitor<'_, '_> {
     /// ensure scoping rules work
     fn apply<F: for<'c> Fn(&'c mut Self)>(&mut self, f: F) {
         let n = self.names.len();
@@ -340,7 +340,7 @@ impl<'a, 'b> SimilarNamesLocalVisitor<'a, 'b> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for SimilarNamesLocalVisitor<'_, 'tcx> {
     fn visit_local(&mut self, local: &'tcx Local) {
         if let Some((init, els)) = &local.kind.init_else_opt() {
             self.apply(|this| walk_expr(this, init));
diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
index a60988ac5dbc2..793eb5d945603 100644
--- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
+++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
@@ -159,7 +159,7 @@ struct NonSendField<'tcx> {
     generic_params: Vec<Ty<'tcx>>,
 }
 
-impl<'tcx> NonSendField<'tcx> {
+impl NonSendField<'_> {
     fn generic_params_string(&self) -> String {
         self.generic_params
             .iter()
diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
index 75d8c09f2b08d..1bddfab39c694 100644
--- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
+++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
@@ -110,7 +110,7 @@ pub struct PassByRefOrValue {
     avoid_breaking_exported_api: bool,
 }
 
-impl<'tcx> PassByRefOrValue {
+impl PassByRefOrValue {
     pub fn new(tcx: TyCtxt<'_>, conf: &'static Conf) -> Self {
         let ref_min_size = conf.trivial_copy_size_limit.unwrap_or_else(|| {
             let bit_width = u64::from(tcx.sess.target.pointer_width);
@@ -130,7 +130,7 @@ impl<'tcx> PassByRefOrValue {
         }
     }
 
-    fn check_poly_fn(&mut self, cx: &LateContext<'tcx>, def_id: LocalDefId, decl: &FnDecl<'_>, span: Option<Span>) {
+    fn check_poly_fn(&mut self, cx: &LateContext<'_>, def_id: LocalDefId, decl: &FnDecl<'_>, span: Option<Span>) {
         if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id) {
             return;
         }
diff --git a/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs b/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs
index 1b9a5a4438297..9f84686a0b12e 100644
--- a/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs
+++ b/src/tools/clippy/clippy_lints/src/pathbuf_init_then_push.rs
@@ -60,7 +60,7 @@ struct PathbufPushSearcher<'tcx> {
     err_span: Span,
 }
 
-impl<'tcx> PathbufPushSearcher<'tcx> {
+impl PathbufPushSearcher<'_> {
     /// Try to generate a suggestion with `PathBuf::from`.
     /// Returns `None` if the suggestion would be invalid.
     fn gen_pathbuf_from(&self, cx: &LateContext<'_>) -> Option<String> {
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 807636bb642b2..bb8a9b6fca85b 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -271,14 +271,18 @@ fn check_invalid_ptr_usage<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()
         && let Some(name) = cx.tcx.get_diagnostic_name(fun_def_id)
     {
+        // TODO: `ptr_slice_from_raw_parts` and its mutable variant should probably still be linted
+        // conditionally based on how the return value is used, but not universally like the other
+        // functions since there are valid uses for null slice pointers.
+        //
+        // See: https://github.com/rust-lang/rust-clippy/pull/13452/files#r1773772034
+
         // `arg` positions where null would cause U.B.
         let arg_indices: &[_] = match name {
             sym::ptr_read
             | sym::ptr_read_unaligned
             | sym::ptr_read_volatile
             | sym::ptr_replace
-            | sym::ptr_slice_from_raw_parts
-            | sym::ptr_slice_from_raw_parts_mut
             | sym::ptr_write
             | sym::ptr_write_bytes
             | sym::ptr_write_unaligned
diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
index 6930a01d48be4..41a44de536b15 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
@@ -228,7 +228,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
                 path: &'tcx hir::Path<'tcx>,
                 count: usize,
             }
-            impl<'a, 'tcx> Visitor<'tcx> for ClosureUsageCount<'a, 'tcx> {
+            impl<'tcx> Visitor<'tcx> for ClosureUsageCount<'_, 'tcx> {
                 type NestedFilter = nested_filter::OnlyBodies;
 
                 fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs
index 3754fdddedfd1..1f223048ce5ce 100644
--- a/src/tools/clippy/clippy_lints/src/returns.rs
+++ b/src/tools/clippy/clippy_lints/src/returns.rs
@@ -140,7 +140,7 @@ enum RetReplacement<'tcx> {
     Expr(Cow<'tcx, str>, Applicability),
 }
 
-impl<'tcx> RetReplacement<'tcx> {
+impl RetReplacement<'_> {
     fn sugg_help(&self) -> &'static str {
         match self {
             Self::Empty | Self::Expr(..) => "remove `return`",
@@ -158,7 +158,7 @@ impl<'tcx> RetReplacement<'tcx> {
     }
 }
 
-impl<'tcx> Display for RetReplacement<'tcx> {
+impl Display for RetReplacement<'_> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         match self {
             Self::Empty => write!(f, ""),
@@ -421,7 +421,7 @@ fn check_final_expr<'tcx>(
                     if matches!(Level::from_attr(attr), Some(Level::Expect(_)))
                         && let metas = attr.meta_item_list()
                         && let Some(lst) = metas
-                        && let [NestedMetaItem::MetaItem(meta_item)] = lst.as_slice()
+                        && let [NestedMetaItem::MetaItem(meta_item), ..] = lst.as_slice()
                         && let [tool, lint_name] = meta_item.path.segments.as_slice()
                         && tool.ident.name == sym::clippy
                         && matches!(
diff --git a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs
index d1114cb29f7a3..0eece9221438a 100644
--- a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs
+++ b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs
@@ -249,7 +249,7 @@ impl<'ap, 'lc, 'others, 'stmt, 'tcx> StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx
     }
 }
 
-impl<'ap, 'lc, 'others, 'stmt, 'tcx> Visitor<'tcx> for StmtsChecker<'ap, 'lc, 'others, 'stmt, 'tcx> {
+impl<'tcx> Visitor<'tcx> for StmtsChecker<'_, '_, '_, '_, 'tcx> {
     fn visit_block(&mut self, block: &'tcx hir::Block<'tcx>) {
         self.ap.curr_block_hir_id = block.hir_id;
         self.ap.curr_block_span = block.span;
diff --git a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
index c986c3e8aa6e8..9fdee8543a854 100644
--- a/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/single_component_path_imports.rs
@@ -102,7 +102,7 @@ struct ImportUsageVisitor {
     imports_referenced_with_self: Vec<Symbol>,
 }
 
-impl<'tcx> Visitor<'tcx> for ImportUsageVisitor {
+impl Visitor<'_> for ImportUsageVisitor {
     fn visit_expr(&mut self, expr: &Expr) {
         if let ExprKind::Path(_, path) = &expr.kind
             && path.segments.len() > 1
diff --git a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
index 5129bbf26655e..fc799cad67e8b 100644
--- a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
+++ b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
@@ -229,7 +229,7 @@ struct VectorInitializationVisitor<'a, 'tcx> {
     initialization_found: bool,
 }
 
-impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
+impl<'tcx> VectorInitializationVisitor<'_, 'tcx> {
     /// Checks if the given expression is extending a vector with `repeat(0).take(..)`
     fn search_slow_extend_filling(&mut self, expr: &'tcx Expr<'_>) {
         if self.initialization_found
@@ -299,7 +299,7 @@ impl<'a, 'tcx> VectorInitializationVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for VectorInitializationVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for VectorInitializationVisitor<'_, 'tcx> {
     fn visit_stmt(&mut self, stmt: &'tcx Stmt<'_>) {
         if self.initialization_found {
             match stmt.kind {
diff --git a/src/tools/clippy/clippy_lints/src/swap.rs b/src/tools/clippy/clippy_lints/src/swap.rs
index e05fa4095b8e3..a3145c4647cab 100644
--- a/src/tools/clippy/clippy_lints/src/swap.rs
+++ b/src/tools/clippy/clippy_lints/src/swap.rs
@@ -332,7 +332,7 @@ struct IndexBinding<'a, 'tcx> {
     applicability: &'a mut Applicability,
 }
 
-impl<'a, 'tcx> IndexBinding<'a, 'tcx> {
+impl<'tcx> IndexBinding<'_, 'tcx> {
     fn snippet_index_bindings(&mut self, exprs: &[&'tcx Expr<'tcx>]) -> String {
         let mut bindings = FxHashSet::default();
         for expr in exprs {
diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
index 104be63bb1579..c7c837de505e4 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -275,12 +275,15 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: us
             |k, ps1, idx| matches!(
                 k,
                 TupleStruct(qself2, path2, ps2)
-                    if eq_maybe_qself(qself1, qself2) && eq_path(path1, path2) && eq_pre_post(ps1, ps2, idx)
+                    if eq_maybe_qself(qself1.as_ref(), qself2.as_ref())
+                       && eq_path(path1, path2) && eq_pre_post(ps1, ps2, idx)
             ),
             |k| always_pat!(k, TupleStruct(_, _, ps) => ps),
         ),
         // Transform a record pattern `S { fp_0, ..., fp_n }`.
-        Struct(qself1, path1, fps1, rest1) => extend_with_struct_pat(qself1, path1, fps1, *rest1, start, alternatives),
+        Struct(qself1, path1, fps1, rest1) => {
+            extend_with_struct_pat(qself1.as_ref(), path1, fps1, *rest1, start, alternatives)
+        },
     };
 
     alternatives[focus_idx].kind = focus_kind;
@@ -292,7 +295,7 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: us
 /// So when we fixate on some `ident_k: pat_k`, we try to find `ident_k` in the other pattern
 /// and check that all `fp_i` where `i ∈ ((0...n) \ k)` between two patterns are equal.
 fn extend_with_struct_pat(
-    qself1: &Option<P<ast::QSelf>>,
+    qself1: Option<&P<ast::QSelf>>,
     path1: &ast::Path,
     fps1: &mut [ast::PatField],
     rest1: ast::PatFieldsRest,
@@ -307,7 +310,7 @@ fn extend_with_struct_pat(
             |k| {
                 matches!(k, Struct(qself2, path2, fps2, rest2)
                 if rest1 == *rest2 // If one struct pattern has `..` so must the other.
-                && eq_maybe_qself(qself1, qself2)
+                && eq_maybe_qself(qself1, qself2.as_ref())
                 && eq_path(path1, path2)
                 && fps1.len() == fps2.len()
                 && fps1.iter().enumerate().all(|(idx_1, fp1)| {
diff --git a/src/tools/clippy/clippy_lints/src/unused_async.rs b/src/tools/clippy/clippy_lints/src/unused_async.rs
index a1f08cf6623bc..c899b1868a6cf 100644
--- a/src/tools/clippy/clippy_lints/src/unused_async.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_async.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::is_def_id_trait_method;
 use rustc_hir::def::DefKind;
 use rustc_hir::intravisit::{FnKind, Visitor, walk_expr, walk_fn};
-use rustc_hir::{Body, Expr, ExprKind, FnDecl, Node, YieldSource};
+use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, Node, YieldSource};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
 use rustc_session::impl_lint_pass;
@@ -67,7 +67,7 @@ struct AsyncFnVisitor<'a, 'tcx> {
     async_depth: usize,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for AsyncFnVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for AsyncFnVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) {
@@ -137,17 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
         }
     }
 
-    fn check_path(&mut self, cx: &LateContext<'tcx>, path: &rustc_hir::Path<'tcx>, hir_id: rustc_hir::HirId) {
-        fn is_node_func_call(node: Node<'_>, expected_receiver: Span) -> bool {
-            matches!(
-                node,
-                Node::Expr(Expr {
-                    kind: ExprKind::Call(Expr { span, .. }, _) | ExprKind::MethodCall(_, Expr { span, .. }, ..),
-                    ..
-                }) if *span == expected_receiver
-            )
-        }
-
+    fn check_path(&mut self, cx: &LateContext<'tcx>, path: &rustc_hir::Path<'tcx>, hir_id: HirId) {
         // Find paths to local async functions that aren't immediately called.
         // E.g. `async fn f() {}; let x = f;`
         // Depending on how `x` is used, f's asyncness might be required despite not having any `await`
@@ -156,7 +146,14 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
             && let Some(local_def_id) = def_id.as_local()
             && cx.tcx.def_kind(def_id) == DefKind::Fn
             && cx.tcx.asyncness(def_id).is_async()
-            && !is_node_func_call(cx.tcx.parent_hir_node(hir_id), path.span)
+            && let parent = cx.tcx.parent_hir_node(hir_id)
+            && !matches!(
+                parent,
+                Node::Expr(Expr {
+                    kind: ExprKind::Call(Expr { span, .. }, _),
+                    ..
+                }) if *span == path.span
+            )
         {
             self.async_fns_as_value.insert(local_def_id);
         }
diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs
index 596f0fd9c8b02..6fe660b6a479f 100644
--- a/src/tools/clippy/clippy_lints/src/unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/unwrap.rs
@@ -235,7 +235,7 @@ impl<'tcx> Delegate<'tcx> for MutationVisitor<'tcx> {
     fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
 }
 
-impl<'a, 'tcx> UnwrappableVariablesVisitor<'a, 'tcx> {
+impl<'tcx> UnwrappableVariablesVisitor<'_, 'tcx> {
     fn visit_branch(
         &mut self,
         if_expr: &'tcx Expr<'_>,
@@ -288,7 +288,7 @@ fn consume_option_as_ref<'tcx>(expr: &'tcx Expr<'tcx>) -> (&'tcx Expr<'tcx>, Opt
     }
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs
index e340b419bd07b..08449de79b364 100644
--- a/src/tools/clippy/clippy_lints/src/use_self.rs
+++ b/src/tools/clippy/clippy_lints/src/use_self.rs
@@ -280,7 +280,7 @@ struct SkipTyCollector {
     types_to_skip: Vec<HirId>,
 }
 
-impl<'tcx> Visitor<'tcx> for SkipTyCollector {
+impl Visitor<'_> for SkipTyCollector {
     fn visit_infer(&mut self, inf: &hir::InferArg) {
         self.types_to_skip.push(inf.hir_id);
 
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
index 7c2e23995c1d3..9e400d2391f02 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
@@ -80,7 +80,7 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
                         && let ty = cx.tcx.type_of(item_def_id).instantiate_identity()
                         && match_type(cx, ty, &paths::SYMBOL)
                         && let Ok(ConstValue::Scalar(value)) = cx.tcx.const_eval_poly(item_def_id)
-                        && let Ok(value) = value.to_u32()
+                        && let Some(value) = value.to_u32().discard_err()
                     {
                         self.symbol_map.insert(value, item_def_id);
                     }
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
index d444ad45087cf..96397375d5edb 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
@@ -72,8 +72,7 @@ pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
         SimplifiedType::Bool,
     ]
     .iter()
-    .flat_map(|&ty| cx.tcx.incoherent_impls(ty).into_iter())
-    .flatten()
+    .flat_map(|&ty| cx.tcx.incoherent_impls(ty).iter())
     .copied();
     for item_def_id in lang_items.iter().map(|(_, def_id)| def_id).chain(incoherent_impls) {
         let lang_item_path = cx.get_def_path(item_def_id);
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
index 7c45a5b2f0971..dd45602221267 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
@@ -270,7 +270,7 @@ struct LintCollector<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for LintCollector<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for LintCollector<'_, 'tcx> {
     type NestedFilter = nested_filter::All;
 
     fn visit_path(&mut self, path: &Path<'_>, _: HirId) {
diff --git a/src/tools/clippy/clippy_lints/src/zombie_processes.rs b/src/tools/clippy/clippy_lints/src/zombie_processes.rs
index ba2a80ee66b05..8d9241cc7d9a2 100644
--- a/src/tools/clippy/clippy_lints/src/zombie_processes.rs
+++ b/src/tools/clippy/clippy_lints/src/zombie_processes.rs
@@ -6,6 +6,7 @@ use rustc_errors::Applicability;
 use rustc_hir::intravisit::{Visitor, walk_block, walk_expr, walk_local};
 use rustc_hir::{Expr, ExprKind, HirId, LetStmt, Node, PatKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::hir::nested_filter;
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
 use std::ops::ControlFlow;
@@ -118,7 +119,8 @@ enum WaitFinder<'a, 'tcx> {
     Found(&'a LateContext<'tcx>, HirId),
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for WaitFinder<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for WaitFinder<'_, 'tcx> {
+    type NestedFilter = nested_filter::OnlyBodies;
     type Result = ControlFlow<BreakReason>;
 
     fn visit_local(&mut self, l: &'tcx LetStmt<'tcx>) -> Self::Result {
@@ -204,6 +206,11 @@ impl<'a, 'tcx> Visitor<'tcx> for WaitFinder<'a, 'tcx> {
 
         walk_expr(self, ex)
     }
+
+    fn nested_visit_map(&mut self) -> Self::Map {
+        let (Self::Found(cx, _) | Self::WalkUpTo(cx, _)) = self;
+        cx.tcx.hir()
+    }
 }
 
 /// This function has shared logic between the different kinds of nodes that can trigger the lint.
@@ -300,7 +307,7 @@ struct ExitPointFinder<'a, 'tcx> {
 
 struct ExitCallFound;
 
-impl<'a, 'tcx> Visitor<'tcx> for ExitPointFinder<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for ExitPointFinder<'_, 'tcx> {
     type Result = ControlFlow<ExitCallFound>;
 
     fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> Self::Result {
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 49323492e124d..68f74e52ed7b7 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -37,20 +37,27 @@ pub fn eq_pat(l: &Pat, r: &Pat) -> bool {
         (_, Paren(r)) => eq_pat(l, r),
         (Wild, Wild) | (Rest, Rest) => true,
         (Lit(l), Lit(r)) => eq_expr(l, r),
-        (Ident(b1, i1, s1), Ident(b2, i2, s2)) => b1 == b2 && eq_id(*i1, *i2) && both(s1, s2, |l, r| eq_pat(l, r)),
+        (Ident(b1, i1, s1), Ident(b2, i2, s2)) => {
+            b1 == b2 && eq_id(*i1, *i2) && both(s1.as_deref(), s2.as_deref(), eq_pat)
+        },
         (Range(lf, lt, le), Range(rf, rt, re)) => {
-            eq_expr_opt(lf, rf) && eq_expr_opt(lt, rt) && eq_range_end(&le.node, &re.node)
+            eq_expr_opt(lf.as_ref(), rf.as_ref())
+                && eq_expr_opt(lt.as_ref(), rt.as_ref())
+                && eq_range_end(&le.node, &re.node)
         },
         (Box(l), Box(r))
         | (Ref(l, Mutability::Not), Ref(r, Mutability::Not))
         | (Ref(l, Mutability::Mut), Ref(r, Mutability::Mut)) => eq_pat(l, r),
         (Tuple(l), Tuple(r)) | (Slice(l), Slice(r)) => over(l, r, |l, r| eq_pat(l, r)),
-        (Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp),
+        (Path(lq, lp), Path(rq, rp)) => both(lq.as_ref(), rq.as_ref(), eq_qself) && eq_path(lp, rp),
         (TupleStruct(lqself, lp, lfs), TupleStruct(rqself, rp, rfs)) => {
-            eq_maybe_qself(lqself, rqself) && eq_path(lp, rp) && over(lfs, rfs, |l, r| eq_pat(l, r))
+            eq_maybe_qself(lqself.as_ref(), rqself.as_ref()) && eq_path(lp, rp) && over(lfs, rfs, |l, r| eq_pat(l, r))
         },
         (Struct(lqself, lp, lfs, lr), Struct(rqself, rp, rfs, rr)) => {
-            lr == rr && eq_maybe_qself(lqself, rqself) && eq_path(lp, rp) && unordered_over(lfs, rfs, eq_field_pat)
+            lr == rr
+                && eq_maybe_qself(lqself.as_ref(), rqself.as_ref())
+                && eq_path(lp, rp)
+                && unordered_over(lfs, rfs, eq_field_pat)
         },
         (Or(ls), Or(rs)) => unordered_over(ls, rs, |l, r| eq_pat(l, r)),
         (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
@@ -79,7 +86,7 @@ pub fn eq_qself(l: &P<QSelf>, r: &P<QSelf>) -> bool {
     l.position == r.position && eq_ty(&l.ty, &r.ty)
 }
 
-pub fn eq_maybe_qself(l: &Option<P<QSelf>>, r: &Option<P<QSelf>>) -> bool {
+pub fn eq_maybe_qself(l: Option<&P<QSelf>>, r: Option<&P<QSelf>>) -> bool {
     match (l, r) {
         (Some(l), Some(r)) => eq_qself(l, r),
         (None, None) => true,
@@ -92,7 +99,7 @@ pub fn eq_path(l: &Path, r: &Path) -> bool {
 }
 
 pub fn eq_path_seg(l: &PathSegment, r: &PathSegment) -> bool {
-    eq_id(l.ident, r.ident) && both(&l.args, &r.args, |l, r| eq_generic_args(l, r))
+    eq_id(l.ident, r.ident) && both(l.args.as_ref(), r.args.as_ref(), |l, r| eq_generic_args(l, r))
 }
 
 pub fn eq_generic_args(l: &GenericArgs, r: &GenericArgs) -> bool {
@@ -122,7 +129,7 @@ pub fn eq_generic_arg(l: &GenericArg, r: &GenericArg) -> bool {
     }
 }
 
-pub fn eq_expr_opt(l: &Option<P<Expr>>, r: &Option<P<Expr>>) -> bool {
+pub fn eq_expr_opt(l: Option<&P<Expr>>, r: Option<&P<Expr>>) -> bool {
     both(l, r, |l, r| eq_expr(l, r))
 }
 
@@ -169,8 +176,12 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
         (Lit(l), Lit(r)) => l == r,
         (Cast(l, lt), Cast(r, rt)) | (Type(l, lt), Type(r, rt)) => eq_expr(l, r) && eq_ty(lt, rt),
         (Let(lp, le, _, _), Let(rp, re, _, _)) => eq_pat(lp, rp) && eq_expr(le, re),
-        (If(lc, lt, le), If(rc, rt, re)) => eq_expr(lc, rc) && eq_block(lt, rt) && eq_expr_opt(le, re),
-        (While(lc, lt, ll), While(rc, rt, rl)) => eq_label(ll, rl) && eq_expr(lc, rc) && eq_block(lt, rt),
+        (If(lc, lt, le), If(rc, rt, re)) => {
+            eq_expr(lc, rc) && eq_block(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref())
+        },
+        (While(lc, lt, ll), While(rc, rt, rl)) => {
+            eq_label(ll.as_ref(), rl.as_ref()) && eq_expr(lc, rc) && eq_block(lt, rt)
+        },
         (
             ForLoop {
                 pat: lp,
@@ -186,13 +197,13 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
                 label: rl,
                 kind: rk,
             },
-        ) => eq_label(ll, rl) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) && lk == rk,
-        (Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll, rl) && eq_block(lt, rt),
-        (Block(lb, ll), Block(rb, rl)) => eq_label(ll, rl) && eq_block(lb, rb),
+        ) => eq_label(ll.as_ref(), rl.as_ref()) && eq_pat(lp, rp) && eq_expr(li, ri) && eq_block(lt, rt) && lk == rk,
+        (Loop(lt, ll, _), Loop(rt, rl, _)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lt, rt),
+        (Block(lb, ll), Block(rb, rl)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_block(lb, rb),
         (TryBlock(l), TryBlock(r)) => eq_block(l, r),
-        (Yield(l), Yield(r)) | (Ret(l), Ret(r)) => eq_expr_opt(l, r),
-        (Break(ll, le), Break(rl, re)) => eq_label(ll, rl) && eq_expr_opt(le, re),
-        (Continue(ll), Continue(rl)) => eq_label(ll, rl),
+        (Yield(l), Yield(r)) | (Ret(l), Ret(r)) => eq_expr_opt(l.as_ref(), r.as_ref()),
+        (Break(ll, le), Break(rl, re)) => eq_label(ll.as_ref(), rl.as_ref()) && eq_expr_opt(le.as_ref(), re.as_ref()),
+        (Continue(ll), Continue(rl)) => eq_label(ll.as_ref(), rl.as_ref()),
         (Assign(l1, l2, _), Assign(r1, r2, _)) | (Index(l1, l2, _), Index(r1, r2, _)) => {
             eq_expr(l1, r1) && eq_expr(l2, r2)
         },
@@ -227,12 +238,14 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
                 && eq_expr(le, re)
         },
         (Gen(lc, lb, lk, _), Gen(rc, rb, rk, _)) => lc == rc && eq_block(lb, rb) && lk == rk,
-        (Range(lf, lt, ll), Range(rf, rt, rl)) => ll == rl && eq_expr_opt(lf, rf) && eq_expr_opt(lt, rt),
+        (Range(lf, lt, ll), Range(rf, rt, rl)) => {
+            ll == rl && eq_expr_opt(lf.as_ref(), rf.as_ref()) && eq_expr_opt(lt.as_ref(), rt.as_ref())
+        },
         (AddrOf(lbk, lm, le), AddrOf(rbk, rm, re)) => lbk == rbk && lm == rm && eq_expr(le, re),
-        (Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp),
+        (Path(lq, lp), Path(rq, rp)) => both(lq.as_ref(), rq.as_ref(), eq_qself) && eq_path(lp, rp),
         (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
         (Struct(lse), Struct(rse)) => {
-            eq_maybe_qself(&lse.qself, &rse.qself)
+            eq_maybe_qself(lse.qself.as_ref(), rse.qself.as_ref())
                 && eq_path(&lse.path, &rse.path)
                 && eq_struct_rest(&lse.rest, &rse.rest)
                 && unordered_over(&lse.fields, &rse.fields, eq_field)
@@ -264,12 +277,12 @@ pub fn eq_field(l: &ExprField, r: &ExprField) -> bool {
 pub fn eq_arm(l: &Arm, r: &Arm) -> bool {
     l.is_placeholder == r.is_placeholder
         && eq_pat(&l.pat, &r.pat)
-        && eq_expr_opt(&l.body, &r.body)
-        && eq_expr_opt(&l.guard, &r.guard)
+        && eq_expr_opt(l.body.as_ref(), r.body.as_ref())
+        && eq_expr_opt(l.guard.as_ref(), r.guard.as_ref())
         && over(&l.attrs, &r.attrs, eq_attr)
 }
 
-pub fn eq_label(l: &Option<Label>, r: &Option<Label>) -> bool {
+pub fn eq_label(l: Option<&Label>, r: Option<&Label>) -> bool {
     both(l, r, |l, r| eq_id(l.ident, r.ident))
 }
 
@@ -282,7 +295,7 @@ pub fn eq_stmt(l: &Stmt, r: &Stmt) -> bool {
     match (&l.kind, &r.kind) {
         (Let(l), Let(r)) => {
             eq_pat(&l.pat, &r.pat)
-                && both(&l.ty, &r.ty, |l, r| eq_ty(l, r))
+                && both(l.ty.as_ref(), r.ty.as_ref(), |l, r| eq_ty(l, r))
                 && eq_local_kind(&l.kind, &r.kind)
                 && over(&l.attrs, &r.attrs, eq_attr)
         },
@@ -329,7 +342,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 expr: re,
                 safety: rs,
             }),
-        ) => lm == rm && ls == rs && eq_ty(lt, rt) && eq_expr_opt(le, re),
+        ) => lm == rm && ls == rs && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()),
         (
             Const(box ConstItem {
                 defaultness: ld,
@@ -343,7 +356,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 ty: rt,
                 expr: re,
             }),
-        ) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le, re),
+        ) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()),
         (
             Fn(box ast::Fn {
                 defaultness: ld,
@@ -358,7 +371,10 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 body: rb,
             }),
         ) => {
-            eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
+            eq_defaultness(*ld, *rd)
+                && eq_fn_sig(lf, rf)
+                && eq_generics(lg, rg)
+                && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
         },
         (Mod(lu, lmk), Mod(ru, rmk)) => {
             lu == ru
@@ -371,7 +387,8 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 }
         },
         (ForeignMod(l), ForeignMod(r)) => {
-            both(&l.abi, &r.abi, eq_str_lit) && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_foreign_item_kind))
+            both(l.abi.as_ref(), r.abi.as_ref(), eq_str_lit)
+                && over(&l.items, &r.items, |l, r| eq_item(l, r, eq_foreign_item_kind))
         },
         (
             TyAlias(box ast::TyAlias {
@@ -392,7 +409,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
             eq_defaultness(*ld, *rd)
                 && eq_generics(lg, rg)
                 && over(lb, rb, eq_generic_bound)
-                && both(lt, rt, |l, r| eq_ty(l, r))
+                && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))
         },
         (Enum(le, lg), Enum(re, rg)) => over(&le.variants, &re.variants, eq_variant) && eq_generics(lg, rg),
         (Struct(lv, lg), Struct(rv, rg)) | (Union(lv, lg), Union(rv, rg)) => {
@@ -448,7 +465,7 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
                 && eq_defaultness(*ld, *rd)
                 && matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No)
                 && eq_generics(lg, rg)
-                && both(lot, rot, |l, r| eq_path(&l.path, &r.path))
+                && both(lot.as_ref(), rot.as_ref(), |l, r| eq_path(&l.path, &r.path))
                 && eq_ty(lst, rst)
                 && over(li, ri, |l, r| eq_item(l, r, eq_assoc_item_kind))
         },
@@ -474,7 +491,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
                 expr: re,
                 safety: rs,
             }),
-        ) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re) && ls == rs,
+        ) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()) && ls == rs,
         (
             Fn(box ast::Fn {
                 defaultness: ld,
@@ -489,7 +506,10 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
                 body: rb,
             }),
         ) => {
-            eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
+            eq_defaultness(*ld, *rd)
+                && eq_fn_sig(lf, rf)
+                && eq_generics(lg, rg)
+                && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
         },
         (
             TyAlias(box ast::TyAlias {
@@ -510,7 +530,7 @@ pub fn eq_foreign_item_kind(l: &ForeignItemKind, r: &ForeignItemKind) -> bool {
             eq_defaultness(*ld, *rd)
                 && eq_generics(lg, rg)
                 && over(lb, rb, eq_generic_bound)
-                && both(lt, rt, |l, r| eq_ty(l, r))
+                && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))
         },
         (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
         _ => false,
@@ -533,7 +553,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
                 ty: rt,
                 expr: re,
             }),
-        ) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le, re),
+        ) => eq_defaultness(*ld, *rd) && eq_generics(lg, rg) && eq_ty(lt, rt) && eq_expr_opt(le.as_ref(), re.as_ref()),
         (
             Fn(box ast::Fn {
                 defaultness: ld,
@@ -548,7 +568,10 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
                 body: rb,
             }),
         ) => {
-            eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
+            eq_defaultness(*ld, *rd)
+                && eq_fn_sig(lf, rf)
+                && eq_generics(lg, rg)
+                && both(lb.as_ref(), rb.as_ref(), |l, r| eq_block(l, r))
         },
         (
             Type(box TyAlias {
@@ -569,7 +592,7 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
             eq_defaultness(*ld, *rd)
                 && eq_generics(lg, rg)
                 && over(lb, rb, eq_generic_bound)
-                && both(lt, rt, |l, r| eq_ty(l, r))
+                && both(lt.as_ref(), rt.as_ref(), |l, r| eq_ty(l, r))
         },
         (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
         _ => false,
@@ -582,7 +605,9 @@ pub fn eq_variant(l: &Variant, r: &Variant) -> bool {
         && eq_vis(&l.vis, &r.vis)
         && eq_id(l.ident, r.ident)
         && eq_variant_data(&l.data, &r.data)
-        && both(&l.disr_expr, &r.disr_expr, |l, r| eq_expr(&l.value, &r.value))
+        && both(l.disr_expr.as_ref(), r.disr_expr.as_ref(), |l, r| {
+            eq_expr(&l.value, &r.value)
+        })
 }
 
 pub fn eq_variant_data(l: &VariantData, r: &VariantData) -> bool {
@@ -600,7 +625,7 @@ pub fn eq_struct_field(l: &FieldDef, r: &FieldDef) -> bool {
     l.is_placeholder == r.is_placeholder
         && over(&l.attrs, &r.attrs, eq_attr)
         && eq_vis(&l.vis, &r.vis)
-        && both(&l.ident, &r.ident, |l, r| eq_id(*l, *r))
+        && both(l.ident.as_ref(), r.ident.as_ref(), |l, r| eq_id(*l, *r))
         && eq_ty(&l.ty, &r.ty)
 }
 
@@ -664,7 +689,7 @@ pub fn eq_use_tree_kind(l: &UseTreeKind, r: &UseTreeKind) -> bool {
     use UseTreeKind::*;
     match (l, r) {
         (Glob, Glob) => true,
-        (Simple(l), Simple(r)) => both(l, r, |l, r| eq_id(*l, *r)),
+        (Simple(l), Simple(r)) => both(l.as_ref(), r.as_ref(), |l, r| eq_id(*l, *r)),
         (Nested { items: l, .. }, Nested { items: r, .. }) => over(l, r, |(l, _), (r, _)| eq_use_tree(l, r)),
         _ => false,
     }
@@ -726,7 +751,7 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool {
         (Array(le, ls), Array(re, rs)) => eq_ty(le, re) && eq_expr(&ls.value, &rs.value),
         (Ptr(l), Ptr(r)) => l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty),
         (Ref(ll, l), Ref(rl, r)) => {
-            both(ll, rl, |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty)
+            both(ll.as_ref(), rl.as_ref(), |l, r| eq_id(l.ident, r.ident)) && l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty)
         },
         (BareFn(l), BareFn(r)) => {
             l.safety == r.safety
@@ -735,7 +760,7 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool {
                 && eq_fn_decl(&l.decl, &r.decl)
         },
         (Tup(l), Tup(r)) => over(l, r, |l, r| eq_ty(l, r)),
-        (Path(lq, lp), Path(rq, rp)) => both(lq, rq, eq_qself) && eq_path(lp, rp),
+        (Path(lq, lp), Path(rq, rp)) => both(lq.as_ref(), rq.as_ref(), eq_qself) && eq_path(lp, rp),
         (TraitObject(lg, ls), TraitObject(rg, rs)) => ls == rs && over(lg, rg, eq_generic_bound),
         (ImplTrait(_, lg), ImplTrait(_, rg)) => over(lg, rg, eq_generic_bound),
         (Typeof(l), Typeof(r)) => eq_expr(&l.value, &r.value),
@@ -771,7 +796,7 @@ pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool {
         && over(&l.bounds, &r.bounds, eq_generic_bound)
         && match (&l.kind, &r.kind) {
             (Lifetime, Lifetime) => true,
-            (Type { default: l }, Type { default: r }) => both(l, r, |l, r| eq_ty(l, r)),
+            (Type { default: l }, Type { default: r }) => both(l.as_ref(), r.as_ref(), |l, r| eq_ty(l, r)),
             (
                 Const {
                     ty: lt,
@@ -783,7 +808,7 @@ pub fn eq_generic_param(l: &GenericParam, r: &GenericParam) -> bool {
                     kw_span: _,
                     default: rd,
                 },
-            ) => eq_ty(lt, rt) && both(ld, rd, eq_anon_const),
+            ) => eq_ty(lt, rt) && both(ld.as_ref(), rd.as_ref(), eq_anon_const),
             _ => false,
         }
         && over(&l.attrs, &r.attrs, eq_attr)
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 53a1170d6a618..510034876e051 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -118,7 +118,7 @@ impl IntTypeBounds for IntTy {
     }
 }
 
-impl<'tcx> PartialEq for Constant<'tcx> {
+impl PartialEq for Constant<'_> {
     fn eq(&self, other: &Self) -> bool {
         match (self, other) {
             (Self::Str(ls), Self::Str(rs)) => ls == rs,
@@ -147,7 +147,7 @@ impl<'tcx> PartialEq for Constant<'tcx> {
     }
 }
 
-impl<'tcx> Hash for Constant<'tcx> {
+impl Hash for Constant<'_> {
     fn hash<H>(&self, state: &mut H)
     where
         H: Hasher,
@@ -203,7 +203,7 @@ impl<'tcx> Hash for Constant<'tcx> {
     }
 }
 
-impl<'tcx> Constant<'tcx> {
+impl Constant<'_> {
     pub fn partial_cmp(tcx: TyCtxt<'_>, cmp_type: Ty<'_>, left: &Self, right: &Self) -> Option<Ordering> {
         match (left, right) {
             (Self::Str(ls), Self::Str(rs)) => Some(ls.cmp(rs)),
diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
index 9420d84b9591d..a2e97919d042f 100644
--- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
+++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs
@@ -118,7 +118,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
         eagerness: EagernessSuggestion,
     }
 
-    impl<'cx, 'tcx> Visitor<'tcx> for V<'cx, 'tcx> {
+    impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> {
         fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
             use EagernessSuggestion::{ForceNoChange, Lazy, NoChange};
             if self.eagerness == ForceNoChange {
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 76900379ac787..06a5cb1a84f0c 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -121,9 +121,9 @@ impl HirEqInterExpr<'_, '_, '_> {
 
                 // eq_pat adds the HirIds to the locals map. We therefore call it last to make sure that
                 // these only get added if the init and type is equal.
-                both(&l.init, &r.init, |l, r| self.eq_expr(l, r))
-                    && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r))
-                    && both(&l.els, &r.els, |l, r| self.eq_block(l, r))
+                both(l.init.as_ref(), r.init.as_ref(), |l, r| self.eq_expr(l, r))
+                    && both(l.ty.as_ref(), r.ty.as_ref(), |l, r| self.eq_ty(l, r))
+                    && both(l.els.as_ref(), r.els.as_ref(), |l, r| self.eq_block(l, r))
                     && self.eq_pat(l.pat, r.pat)
             },
             (&StmtKind::Expr(l), &StmtKind::Expr(r)) | (&StmtKind::Semi(l), &StmtKind::Semi(r)) => self.eq_expr(l, r),
@@ -142,7 +142,9 @@ impl HirEqInterExpr<'_, '_, '_> {
         if lspan.ctxt != SyntaxContext::root() && rspan.ctxt != SyntaxContext::root() {
             // Don't try to check in between statements inside macros.
             return over(left.stmts, right.stmts, |left, right| self.eq_stmt(left, right))
-                && both(&left.expr, &right.expr, |left, right| self.eq_expr(left, right));
+                && both(left.expr.as_ref(), right.expr.as_ref(), |left, right| {
+                    self.eq_expr(left, right)
+                });
         }
         if lspan.ctxt != rspan.ctxt {
             return false;
@@ -285,8 +287,8 @@ impl HirEqInterExpr<'_, '_, '_> {
                     })
             },
             (&ExprKind::Break(li, ref le), &ExprKind::Break(ri, ref re)) => {
-                both(&li.label, &ri.label, |l, r| l.ident.name == r.ident.name)
-                    && both(le, re, |l, r| self.eq_expr(l, r))
+                both(li.label.as_ref(), ri.label.as_ref(), |l, r| l.ident.name == r.ident.name)
+                    && both(le.as_ref(), re.as_ref(), |l, r| self.eq_expr(l, r))
             },
             (&ExprKind::Call(l_fun, l_args), &ExprKind::Call(r_fun, r_args)) => {
                 self.inner.allow_side_effects && self.eq_expr(l_fun, r_fun) && self.eq_exprs(l_args, r_args)
@@ -297,7 +299,7 @@ impl HirEqInterExpr<'_, '_, '_> {
             (&ExprKind::Closure(_l), &ExprKind::Closure(_r)) => false,
             (&ExprKind::ConstBlock(lb), &ExprKind::ConstBlock(rb)) => self.eq_body(lb.body, rb.body),
             (&ExprKind::Continue(li), &ExprKind::Continue(ri)) => {
-                both(&li.label, &ri.label, |l, r| l.ident.name == r.ident.name)
+                both(li.label.as_ref(), ri.label.as_ref(), |l, r| l.ident.name == r.ident.name)
             },
             (&ExprKind::DropTemps(le), &ExprKind::DropTemps(re)) => self.eq_expr(le, re),
             (&ExprKind::Field(l_f_exp, ref l_f_ident), &ExprKind::Field(r_f_exp, ref r_f_ident)) => {
@@ -305,21 +307,25 @@ impl HirEqInterExpr<'_, '_, '_> {
             },
             (&ExprKind::Index(la, li, _), &ExprKind::Index(ra, ri, _)) => self.eq_expr(la, ra) && self.eq_expr(li, ri),
             (&ExprKind::If(lc, lt, ref le), &ExprKind::If(rc, rt, ref re)) => {
-                self.eq_expr(lc, rc) && self.eq_expr(lt, rt) && both(le, re, |l, r| self.eq_expr(l, r))
+                self.eq_expr(lc, rc) && self.eq_expr(lt, rt)
+                    && both(le.as_ref(), re.as_ref(), |l, r| self.eq_expr(l, r))
             },
             (&ExprKind::Let(l), &ExprKind::Let(r)) => {
-                self.eq_pat(l.pat, r.pat) && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r)) && self.eq_expr(l.init, r.init)
+                self.eq_pat(l.pat, r.pat)
+                    && both(l.ty.as_ref(), r.ty.as_ref(), |l, r| self.eq_ty(l, r))
+                    && self.eq_expr(l.init, r.init)
             },
             (ExprKind::Lit(l), ExprKind::Lit(r)) => l.node == r.node,
             (&ExprKind::Loop(lb, ref ll, ref lls, _), &ExprKind::Loop(rb, ref rl, ref rls, _)) => {
-                lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.name == r.ident.name)
+                lls == rls && self.eq_block(lb, rb)
+                    && both(ll.as_ref(), rl.as_ref(), |l, r| l.ident.name == r.ident.name)
             },
             (&ExprKind::Match(le, la, ref ls), &ExprKind::Match(re, ra, ref rs)) => {
                 (ls == rs || (matches!((ls, rs), (TryDesugar(_), TryDesugar(_)))))
                     && self.eq_expr(le, re)
                     && over(la, ra, |l, r| {
                         self.eq_pat(l.pat, r.pat)
-                            && both(&l.guard, &r.guard, |l, r| self.eq_expr(l, r))
+                            && both(l.guard.as_ref(), r.guard.as_ref(), |l, r| self.eq_expr(l, r))
                             && self.eq_expr(l.body, r.body)
                     })
             },
@@ -339,10 +345,10 @@ impl HirEqInterExpr<'_, '_, '_> {
             (&ExprKind::Repeat(le, ll), &ExprKind::Repeat(re, rl)) => {
                 self.eq_expr(le, re) && self.eq_array_length(ll, rl)
             },
-            (ExprKind::Ret(l), ExprKind::Ret(r)) => both(l, r, |l, r| self.eq_expr(l, r)),
+            (ExprKind::Ret(l), ExprKind::Ret(r)) => both(l.as_ref(), r.as_ref(), |l, r| self.eq_expr(l, r)),
             (&ExprKind::Struct(l_path, lf, ref lo), &ExprKind::Struct(r_path, rf, ref ro)) => {
                 self.eq_qpath(l_path, r_path)
-                    && both(lo, ro, |l, r| self.eq_expr(l, r))
+                    && both(lo.as_ref(), ro.as_ref(), |l, r| self.eq_expr(l, r))
                     && over(lf, rf, |l, r| self.eq_expr_field(l, r))
             },
             (&ExprKind::Tup(l_tup), &ExprKind::Tup(r_tup)) => self.eq_exprs(l_tup, r_tup),
@@ -450,7 +456,7 @@ impl HirEqInterExpr<'_, '_, '_> {
                 self.eq_qpath(lp, rp) && over(la, ra, |l, r| self.eq_pat(l, r)) && ls == rs
             },
             (&PatKind::Binding(lb, li, _, ref lp), &PatKind::Binding(rb, ri, _, ref rp)) => {
-                let eq = lb == rb && both(lp, rp, |l, r| self.eq_pat(l, r));
+                let eq = lb == rb && both(lp.as_ref(), rp.as_ref(), |l, r| self.eq_pat(l, r));
                 if eq {
                     self.locals.insert(li, ri);
                 }
@@ -460,13 +466,15 @@ impl HirEqInterExpr<'_, '_, '_> {
             (&PatKind::Lit(l), &PatKind::Lit(r)) => self.eq_expr(l, r),
             (&PatKind::Tuple(l, ls), &PatKind::Tuple(r, rs)) => ls == rs && over(l, r, |l, r| self.eq_pat(l, r)),
             (&PatKind::Range(ref ls, ref le, li), &PatKind::Range(ref rs, ref re, ri)) => {
-                both(ls, rs, |a, b| self.eq_expr(a, b)) && both(le, re, |a, b| self.eq_expr(a, b)) && (li == ri)
+                both(ls.as_ref(), rs.as_ref(), |a, b| self.eq_expr(a, b))
+                    && both(le.as_ref(), re.as_ref(), |a, b| self.eq_expr(a, b))
+                    && (li == ri)
             },
             (&PatKind::Ref(le, ref lm), &PatKind::Ref(re, ref rm)) => lm == rm && self.eq_pat(le, re),
             (&PatKind::Slice(ls, ref li, le), &PatKind::Slice(rs, ref ri, re)) => {
                 over(ls, rs, |l, r| self.eq_pat(l, r))
                     && over(le, re, |l, r| self.eq_pat(l, r))
-                    && both(li, ri, |l, r| self.eq_pat(l, r))
+                    && both(li.as_ref(), ri.as_ref(), |l, r| self.eq_pat(l, r))
             },
             (&PatKind::Wild, &PatKind::Wild) => true,
             _ => false,
@@ -476,7 +484,7 @@ impl HirEqInterExpr<'_, '_, '_> {
     fn eq_qpath(&mut self, left: &QPath<'_>, right: &QPath<'_>) -> bool {
         match (left, right) {
             (&QPath::Resolved(ref lty, lpath), &QPath::Resolved(ref rty, rpath)) => {
-                both(lty, rty, |l, r| self.eq_ty(l, r)) && self.eq_path(lpath, rpath)
+                both(lty.as_ref(), rty.as_ref(), |l, r| self.eq_ty(l, r)) && self.eq_path(lpath, rpath)
             },
             (&QPath::TypeRelative(lty, lseg), &QPath::TypeRelative(rty, rseg)) => {
                 self.eq_ty(lty, rty) && self.eq_path_segment(lseg, rseg)
@@ -510,7 +518,10 @@ impl HirEqInterExpr<'_, '_, '_> {
     pub fn eq_path_segment(&mut self, left: &PathSegment<'_>, right: &PathSegment<'_>) -> bool {
         // The == of idents doesn't work with different contexts,
         // we have to be explicit about hygiene
-        left.ident.name == right.ident.name && both(&left.args, &right.args, |l, r| self.eq_path_parameters(l, r))
+        left.ident.name == right.ident.name
+            && both(left.args.as_ref(), right.args.as_ref(), |l, r| {
+                self.eq_path_parameters(l, r)
+            })
     }
 
     pub fn eq_ty(&mut self, left: &Ty<'_>, right: &Ty<'_>) -> bool {
@@ -649,7 +660,7 @@ fn swap_binop<'a>(
 
 /// Checks if the two `Option`s are both `None` or some equal values as per
 /// `eq_fn`.
-pub fn both<X>(l: &Option<X>, r: &Option<X>, mut eq_fn: impl FnMut(&X, &X) -> bool) -> bool {
+pub fn both<X>(l: Option<&X>, r: Option<&X>, mut eq_fn: impl FnMut(&X, &X) -> bool) -> bool {
     l.as_ref()
         .map_or_else(|| r.is_none(), |x| r.as_ref().map_or(false, |y| eq_fn(x, y)))
 }
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 6dbc3334157e3..514ec70a40bf7 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -597,7 +597,7 @@ fn find_primitive_impls<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator<It
         },
     };
 
-    tcx.incoherent_impls(ty).into_iter().copied()
+    tcx.incoherent_impls(ty).iter().copied()
 }
 
 fn non_local_item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec<Res> {
@@ -731,7 +731,7 @@ pub fn def_path_res_with_base(tcx: TyCtxt<'_>, mut base: Vec<Res>, mut path: &[&
                 // `impl S { ... }`
                 let inherent_impl_children = tcx
                     .inherent_impls(def_id)
-                    .into_iter()
+                    .iter()
                     .flat_map(|&impl_def_id| item_children_by_name(tcx, impl_def_id, segment));
 
                 let direct_children = item_children_by_name(tcx, def_id, segment);
@@ -1341,7 +1341,7 @@ pub struct ContainsName<'a, 'tcx> {
     pub result: bool,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for ContainsName<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for ContainsName<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_name(&mut self, name: Symbol) {
@@ -3111,7 +3111,7 @@ pub fn is_never_expr<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option<
         is_never: bool,
     }
 
-    impl<'tcx> V<'_, 'tcx> {
+    impl V<'_, '_> {
         fn push_break_target(&mut self, id: HirId) {
             self.break_targets.push(BreakTarget { id, unused: true });
             self.break_targets_for_result_ty += u32::from(self.in_final_expr);
diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs
index 59bb5e35cda66..3924e384c371d 100644
--- a/src/tools/clippy/clippy_utils/src/mir/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs
@@ -58,7 +58,7 @@ struct V<'a> {
     results: Vec<LocalUsage>,
 }
 
-impl<'a, 'tcx> Visitor<'tcx> for V<'a> {
+impl<'tcx> Visitor<'tcx> for V<'_> {
     fn visit_place(&mut self, place: &Place<'tcx>, ctx: PlaceContext, loc: Location) {
         if loc.block == self.location.block && loc.statement_index <= self.location.statement_index {
             return;
diff --git a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
index 07e6705cd3d95..6bb434a466fdf 100644
--- a/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/possible_borrower.rs
@@ -65,7 +65,7 @@ impl<'a, 'b, 'tcx> PossibleBorrowerVisitor<'a, 'b, 'tcx> {
     }
 }
 
-impl<'a, 'b, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'b, 'tcx> {
+impl<'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'_, '_, 'tcx> {
     fn visit_assign(&mut self, place: &mir::Place<'tcx>, rvalue: &mir::Rvalue<'_>, _location: mir::Location) {
         let lhs = place.local;
         match rvalue {
@@ -177,8 +177,8 @@ pub struct PossibleBorrowerMap<'b, 'tcx> {
     pub bitset: (BitSet<mir::Local>, BitSet<mir::Local>),
 }
 
-impl<'a, 'b, 'tcx> PossibleBorrowerMap<'b, 'tcx> {
-    pub fn new(cx: &'a LateContext<'tcx>, mir: &'b mir::Body<'tcx>) -> Self {
+impl<'b, 'tcx> PossibleBorrowerMap<'b, 'tcx> {
+    pub fn new(cx: &LateContext<'tcx>, mir: &'b mir::Body<'tcx>) -> Self {
         let possible_origin = {
             let mut vis = PossibleOriginVisitor::new(mir);
             vis.visit_body(mir);
diff --git a/src/tools/clippy/clippy_utils/src/mir/possible_origin.rs b/src/tools/clippy/clippy_utils/src/mir/possible_origin.rs
index da04266863f94..4157b3f493066 100644
--- a/src/tools/clippy/clippy_utils/src/mir/possible_origin.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/possible_origin.rs
@@ -39,7 +39,7 @@ impl<'a, 'tcx> PossibleOriginVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleOriginVisitor<'a, 'tcx> {
+impl<'tcx> mir::visit::Visitor<'tcx> for PossibleOriginVisitor<'_, 'tcx> {
     fn visit_assign(&mut self, place: &mir::Place<'tcx>, rvalue: &mir::Rvalue<'_>, _location: mir::Location) {
         let lhs = place.local;
         match rvalue {
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 7a6107cfe539e..5f12b6bf99ec2 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -131,7 +131,8 @@ fn check_rvalue<'tcx>(
             CastKind::PointerCoercion(
                 PointerCoercion::UnsafeFnPointer
                 | PointerCoercion::ClosureFnPointer(_)
-                | PointerCoercion::ReifyFnPointer, _
+                | PointerCoercion::ReifyFnPointer,
+                _,
             ),
             _,
             _,
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 4e3a61a1aa5f5..21c2b19f4bdd6 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -1319,7 +1319,7 @@ pub fn deref_chain<'cx, 'tcx>(cx: &'cx LateContext<'tcx>, ty: Ty<'tcx>) -> impl
 /// If you need this, you should wrap this call in `clippy_utils::ty::deref_chain().any(...)`.
 pub fn get_adt_inherent_method<'a>(cx: &'a LateContext<'_>, ty: Ty<'_>, method_name: Symbol) -> Option<&'a AssocItem> {
     if let Some(ty_did) = ty.ty_adt_def().map(AdtDef::did) {
-        cx.tcx.inherent_impls(ty_did).into_iter().find_map(|&did| {
+        cx.tcx.inherent_impls(ty_did).iter().find_map(|&did| {
             cx.tcx
                 .associated_items(did)
                 .filter_by_name_unhygienic(method_name)
diff --git a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
index e612e9c6cb606..91ec120adbf6f 100644
--- a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
@@ -108,7 +108,7 @@ impl<'cx, 'tcx> CertaintyVisitor<'cx, 'tcx> {
     }
 }
 
-impl<'cx, 'tcx> Visitor<'cx> for CertaintyVisitor<'cx, 'tcx> {
+impl<'cx> Visitor<'cx> for CertaintyVisitor<'cx, '_> {
     fn visit_qpath(&mut self, qpath: &'cx QPath<'_>, hir_id: HirId, _: Span) {
         self.certainty = self.certainty.meet(qpath_certainty(self.cx, qpath, true));
         if self.certainty != Certainty::Uncertain {
diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs
index 1230b60c3a6b7..8af3bdccaa1ca 100644
--- a/src/tools/clippy/clippy_utils/src/usage.rs
+++ b/src/tools/clippy/clippy_utils/src/usage.rs
@@ -46,8 +46,8 @@ struct MutVarsDelegate {
     skip: bool,
 }
 
-impl<'tcx> MutVarsDelegate {
-    fn update(&mut self, cat: &PlaceWithHirId<'tcx>) {
+impl MutVarsDelegate {
+    fn update(&mut self, cat: &PlaceWithHirId<'_>) {
         match cat.place.base {
             PlaceBase::Local(id) => {
                 self.used_mutably.insert(id);
@@ -122,7 +122,7 @@ impl<'a, 'tcx> BindingUsageFinder<'a, 'tcx> {
         finder.usage_found
     }
 }
-impl<'a, 'tcx> Visitor<'tcx> for BindingUsageFinder<'a, 'tcx> {
+impl<'tcx> Visitor<'tcx> for BindingUsageFinder<'_, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
     fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index 6d9a85a1181c4..02931306f162d 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -552,7 +552,7 @@ pub fn for_each_local_use_after_expr<'tcx, B>(
         res: ControlFlow<B>,
         f: F,
     }
-    impl<'cx, 'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'cx, 'tcx, F, B> {
+    impl<'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'_, 'tcx, F, B> {
         type NestedFilter = nested_filter::OnlyBodies;
         fn nested_visit_map(&mut self) -> Self::Map {
             self.cx.tcx.hir()
@@ -734,7 +734,7 @@ pub fn for_each_local_assignment<'tcx, B>(
         res: ControlFlow<B>,
         f: F,
     }
-    impl<'cx, 'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'cx, 'tcx, F, B> {
+    impl<'tcx, F: FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>, B> Visitor<'tcx> for V<'_, 'tcx, F, B> {
         type NestedFilter = nested_filter::OnlyBodies;
         fn nested_visit_map(&mut self) -> Self::Map {
             self.cx.tcx.hir()
diff --git a/src/tools/clippy/lintcheck/src/main.rs b/src/tools/clippy/lintcheck/src/main.rs
index acb6eaa5278aa..8c62dd3ed3859 100644
--- a/src/tools/clippy/lintcheck/src/main.rs
+++ b/src/tools/clippy/lintcheck/src/main.rs
@@ -68,7 +68,7 @@ impl Crate {
         total_crates_to_lint: usize,
         config: &LintcheckConfig,
         lint_levels_args: &[String],
-        server: &Option<LintcheckServer>,
+        server: Option<&LintcheckServer>,
     ) -> Vec<ClippyCheckOutput> {
         // advance the atomic index by one
         let index = target_dir_index.fetch_add(1, Ordering::SeqCst);
@@ -359,7 +359,7 @@ fn lintcheck(config: LintcheckConfig) {
                 crates.len(),
                 &config,
                 &lint_level_args,
-                &server,
+                server.as_ref(),
             )
         })
         .collect();
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index b431599c224ef..f0c8651efce4e 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,4 +1,4 @@
 [toolchain]
-channel = "nightly-2024-09-22"
+channel = "nightly-2024-10-03"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
 profile = "minimal"
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index 324f754e61556..c66837dc998f4 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -22,7 +22,6 @@ use rustc_span::symbol::Symbol;
 
 use std::env;
 use std::fs::read_to_string;
-use std::ops::Deref;
 use std::path::Path;
 use std::process::exit;
 
@@ -30,12 +29,8 @@ use anstream::println;
 
 /// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
 /// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`.
-fn arg_value<'a, T: Deref<Target = str>>(
-    args: &'a [T],
-    find_arg: &str,
-    pred: impl Fn(&str) -> bool,
-) -> Option<&'a str> {
-    let mut args = args.iter().map(Deref::deref);
+fn arg_value<'a>(args: &'a [String], find_arg: &str, pred: impl Fn(&str) -> bool) -> Option<&'a str> {
+    let mut args = args.iter().map(String::as_str);
     while let Some(arg) = args.next() {
         let mut arg = arg.splitn(2, '=');
         if arg.next() != Some(find_arg) {
@@ -50,11 +45,15 @@ fn arg_value<'a, T: Deref<Target = str>>(
     None
 }
 
+fn has_arg(args: &[String], find_arg: &str) -> bool {
+    args.iter().any(|arg| find_arg == arg.split('=').next().unwrap())
+}
+
 #[test]
 fn test_arg_value() {
-    let args = &["--bar=bar", "--foobar", "123", "--foo"];
+    let args = &["--bar=bar", "--foobar", "123", "--foo"].map(String::from);
 
-    assert_eq!(arg_value(&[] as &[&str], "--foobar", |_| true), None);
+    assert_eq!(arg_value(&[], "--foobar", |_| true), None);
     assert_eq!(arg_value(args, "--bar", |_| false), None);
     assert_eq!(arg_value(args, "--bar", |_| true), Some("bar"));
     assert_eq!(arg_value(args, "--bar", |p| p == "bar"), Some("bar"));
@@ -65,11 +64,21 @@ fn test_arg_value() {
     assert_eq!(arg_value(args, "--foo", |_| true), None);
 }
 
-fn track_clippy_args(psess: &mut ParseSess, args_env_var: &Option<String>) {
-    psess.env_depinfo.get_mut().insert((
-        Symbol::intern("CLIPPY_ARGS"),
-        args_env_var.as_deref().map(Symbol::intern),
-    ));
+#[test]
+fn test_has_arg() {
+    let args = &["--foo=bar", "-vV", "--baz"].map(String::from);
+    assert!(has_arg(args, "--foo"));
+    assert!(has_arg(args, "--baz"));
+    assert!(has_arg(args, "-vV"));
+
+    assert!(!has_arg(args, "--bar"));
+}
+
+fn track_clippy_args(psess: &mut ParseSess, args_env_var: Option<&str>) {
+    psess
+        .env_depinfo
+        .get_mut()
+        .insert((Symbol::intern("CLIPPY_ARGS"), args_env_var.map(Symbol::intern)));
 }
 
 /// Track files that may be accessed at runtime in `file_depinfo` so that cargo will re-run clippy
@@ -113,7 +122,7 @@ impl rustc_driver::Callbacks for RustcCallbacks {
     fn config(&mut self, config: &mut interface::Config) {
         let clippy_args_var = self.clippy_args_var.take();
         config.psess_created = Some(Box::new(move |psess| {
-            track_clippy_args(psess, &clippy_args_var);
+            track_clippy_args(psess, clippy_args_var.as_deref());
         }));
     }
 }
@@ -130,7 +139,7 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
         let previous = config.register_lints.take();
         let clippy_args_var = self.clippy_args_var.take();
         config.psess_created = Some(Box::new(move |psess| {
-            track_clippy_args(psess, &clippy_args_var);
+            track_clippy_args(psess, clippy_args_var.as_deref());
             track_files(psess);
 
             // Trigger a rebuild if CLIPPY_CONF_DIR changes. The value must be a valid string so
@@ -189,7 +198,7 @@ pub fn main() {
         let mut orig_args = rustc_driver::args::raw_args(&early_dcx)?;
 
         let has_sysroot_arg = |args: &mut [String]| -> bool {
-            if arg_value(args, "--sysroot", |_| true).is_some() {
+            if has_arg(args, "--sysroot") {
                 return true;
             }
             // https://doc.rust-lang.org/rustc/command-line-arguments.html#path-load-command-line-flags-from-a-path
@@ -199,7 +208,7 @@ pub fn main() {
                 if let Some(arg_file_path) = arg.strip_prefix('@') {
                     if let Ok(arg_file) = read_to_string(arg_file_path) {
                         let split_arg_file: Vec<String> = arg_file.lines().map(ToString::to_string).collect();
-                        if arg_value(&split_arg_file, "--sysroot", |_| true).is_some() {
+                        if has_arg(&split_arg_file, "--sysroot") {
                             return true;
                         }
                     }
@@ -271,16 +280,18 @@ pub fn main() {
             .chain(vec!["--cfg".into(), "clippy".into()])
             .collect::<Vec<String>>();
 
-        // We enable Clippy if one of the following conditions is met
-        // - IF Clippy is run on its test suite OR
-        // - IF Clippy is run on the main crate, not on deps (`!cap_lints_allow`) THEN
-        //    - IF `--no-deps` is not set (`!no_deps`) OR
-        //    - IF `--no-deps` is set and Clippy is run on the specified primary package
+        // If no Clippy lints will be run we do not need to run Clippy
         let cap_lints_allow = arg_value(&orig_args, "--cap-lints", |val| val == "allow").is_some()
             && arg_value(&orig_args, "--force-warn", |val| val.contains("clippy::")).is_none();
-        let in_primary_package = env::var("CARGO_PRIMARY_PACKAGE").is_ok();
 
-        let clippy_enabled = !cap_lints_allow && (!no_deps || in_primary_package);
+        // If `--no-deps` is enabled only lint the primary pacakge
+        let relevant_package = !no_deps || env::var("CARGO_PRIMARY_PACKAGE").is_ok();
+
+        // Do not run Clippy for Cargo's info queries so that invalid CLIPPY_ARGS are not cached
+        // https://github.com/rust-lang/cargo/issues/14385
+        let info_query = has_arg(&orig_args, "-vV") || has_arg(&orig_args, "--print");
+
+        let clippy_enabled = !cap_lints_allow && relevant_package && !info_query;
         if clippy_enabled {
             args.extend(clippy_args);
             rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var })
diff --git a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs
index 232bccf6a1543..4613a74b85d83 100644
--- a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs
+++ b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.rs
@@ -7,7 +7,8 @@
     clippy::no_effect,
     clippy::unnecessary_operation,
     clippy::useless_vec,
-    clippy::out_of_bounds_indexing
+    clippy::out_of_bounds_indexing,
+    clippy::needless_lifetimes
 )]
 
 const ARR: [i32; 2] = [1, 2];
diff --git a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr
index 5ce2ed2ffaeec..120f5c35cb036 100644
--- a/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/suppress_lint_in_const/test.stderr
@@ -1,5 +1,5 @@
 error: indexing may panic
-  --> tests/ui-toml/suppress_lint_in_const/test.rs:26:5
+  --> tests/ui-toml/suppress_lint_in_const/test.rs:27:5
    |
 LL |     x[index];
    |     ^^^^^^^^
@@ -9,7 +9,7 @@ LL |     x[index];
    = help: to override `-D warnings` add `#[allow(clippy::indexing_slicing)]`
 
 error: indexing may panic
-  --> tests/ui-toml/suppress_lint_in_const/test.rs:41:5
+  --> tests/ui-toml/suppress_lint_in_const/test.rs:42:5
    |
 LL |     v[0];
    |     ^^^^
@@ -17,7 +17,7 @@ LL |     v[0];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui-toml/suppress_lint_in_const/test.rs:42:5
+  --> tests/ui-toml/suppress_lint_in_const/test.rs:43:5
    |
 LL |     v[10];
    |     ^^^^^
@@ -25,7 +25,7 @@ LL |     v[10];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui-toml/suppress_lint_in_const/test.rs:43:5
+  --> tests/ui-toml/suppress_lint_in_const/test.rs:44:5
    |
 LL |     v[1 << 3];
    |     ^^^^^^^^^
@@ -33,7 +33,7 @@ LL |     v[1 << 3];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui-toml/suppress_lint_in_const/test.rs:49:5
+  --> tests/ui-toml/suppress_lint_in_const/test.rs:50:5
    |
 LL |     v[N];
    |     ^^^^
@@ -41,7 +41,7 @@ LL |     v[N];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> tests/ui-toml/suppress_lint_in_const/test.rs:50:5
+  --> tests/ui-toml/suppress_lint_in_const/test.rs:51:5
    |
 LL |     v[M];
    |     ^^^^
diff --git a/src/tools/clippy/tests/ui/as_ptr_cast_mut.rs b/src/tools/clippy/tests/ui/as_ptr_cast_mut.rs
index 297a53b1bbfb4..9e862320f4efe 100644
--- a/src/tools/clippy/tests/ui/as_ptr_cast_mut.rs
+++ b/src/tools/clippy/tests/ui/as_ptr_cast_mut.rs
@@ -1,7 +1,7 @@
 #![allow(unused)]
 #![warn(clippy::as_ptr_cast_mut)]
 #![allow(clippy::wrong_self_convention, clippy::unnecessary_cast)]
-//@no-rustfix
+//@no-rustfix: incorrect suggestion
 
 struct MutPtrWrapper(Vec<u8>);
 impl MutPtrWrapper {
diff --git a/src/tools/clippy/tests/ui/borrow_box.fixed b/src/tools/clippy/tests/ui/borrow_box.fixed
new file mode 100644
index 0000000000000..08ea60583ea40
--- /dev/null
+++ b/src/tools/clippy/tests/ui/borrow_box.fixed
@@ -0,0 +1,133 @@
+#![deny(clippy::borrowed_box)]
+#![allow(dead_code, unused_variables)]
+#![allow(
+    clippy::uninlined_format_args,
+    clippy::disallowed_names,
+    clippy::needless_pass_by_ref_mut,
+    clippy::needless_lifetimes
+)]
+
+use std::fmt::Display;
+
+pub fn test1(foo: &mut Box<bool>) {
+    // Although this function could be changed to "&mut bool",
+    // avoiding the Box, mutable references to boxes are not
+    // flagged by this lint.
+    //
+    // This omission is intentional: By passing a mutable Box,
+    // the memory location of the pointed-to object could be
+    // modified. By passing a mutable reference, the contents
+    // could change, but not the location.
+    println!("{:?}", foo)
+}
+
+pub fn test2() {
+    let foo: &bool;
+    //~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+}
+
+struct Test3<'a> {
+    foo: &'a bool,
+    //~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+}
+
+trait Test4 {
+    fn test4(a: &bool);
+    //~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+}
+
+use std::any::Any;
+
+pub fn test5(foo: &mut Box<dyn Any>) {
+    println!("{:?}", foo)
+}
+
+pub fn test6() {
+    let foo: &Box<dyn Any>;
+}
+
+struct Test7<'a> {
+    foo: &'a Box<dyn Any>,
+}
+
+trait Test8 {
+    fn test8(a: &Box<dyn Any>);
+}
+
+impl<'a> Test8 for Test7<'a> {
+    fn test8(a: &Box<dyn Any>) {
+        unimplemented!();
+    }
+}
+
+pub fn test9(foo: &mut Box<dyn Any + Send + Sync>) {
+    let _ = foo;
+}
+
+pub fn test10() {
+    let foo: &Box<dyn Any + Send + 'static>;
+}
+
+struct Test11<'a> {
+    foo: &'a Box<dyn Any + Send>,
+}
+
+trait Test12 {
+    fn test4(a: &Box<dyn Any + 'static>);
+}
+
+impl<'a> Test12 for Test11<'a> {
+    fn test4(a: &Box<dyn Any + 'static>) {
+        unimplemented!();
+    }
+}
+
+pub fn test13(boxed_slice: &mut Box<[i32]>) {
+    // Unconditionally replaces the box pointer.
+    //
+    // This cannot be accomplished if "&mut [i32]" is passed,
+    // and provides a test case where passing a reference to
+    // a Box is valid.
+    let mut data = vec![12];
+    *boxed_slice = data.into_boxed_slice();
+}
+
+// The suggestion should include proper parentheses to avoid a syntax error.
+pub fn test14(_display: &dyn Display) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+pub fn test15(_display: &(dyn Display + Send)) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+pub fn test16<'a>(_display: &'a (dyn Display + 'a)) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+
+pub fn test17(_display: &impl Display) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+pub fn test18(_display: &(impl Display + Send)) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+pub fn test19<'a>(_display: &'a (impl Display + 'a)) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+
+// This exists only to check what happens when parentheses are already present.
+// Even though the current implementation doesn't put extra parentheses,
+// it's fine that unnecessary parentheses appear in the future for some reason.
+pub fn test20(_display: &(dyn Display + Send)) {}
+//~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
+
+#[allow(clippy::borrowed_box)]
+trait Trait {
+    fn f(b: &Box<bool>);
+}
+
+// Trait impls are not linted
+impl Trait for () {
+    fn f(_: &Box<bool>) {}
+}
+
+fn main() {
+    test1(&mut Box::new(false));
+    test2();
+    test5(&mut (Box::new(false) as Box<dyn Any>));
+    test6();
+    test9(&mut (Box::new(false) as Box<dyn Any + Send + Sync>));
+    test10();
+}
diff --git a/src/tools/clippy/tests/ui/borrow_box.rs b/src/tools/clippy/tests/ui/borrow_box.rs
index e9994aac8454a..b55de1701daa8 100644
--- a/src/tools/clippy/tests/ui/borrow_box.rs
+++ b/src/tools/clippy/tests/ui/borrow_box.rs
@@ -3,9 +3,9 @@
 #![allow(
     clippy::uninlined_format_args,
     clippy::disallowed_names,
-    clippy::needless_pass_by_ref_mut
+    clippy::needless_pass_by_ref_mut,
+    clippy::needless_lifetimes
 )]
-//@no-rustfix
 
 use std::fmt::Display;
 
@@ -36,12 +36,6 @@ trait Test4 {
     //~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
 }
 
-impl<'a> Test4 for Test3<'a> {
-    fn test4(a: &Box<bool>) {
-        unimplemented!();
-    }
-}
-
 use std::any::Any;
 
 pub fn test5(foo: &mut Box<dyn Any>) {
@@ -119,6 +113,16 @@ pub fn test19<'a>(_display: &'a Box<impl Display + 'a>) {}
 pub fn test20(_display: &Box<(dyn Display + Send)>) {}
 //~^ ERROR: you seem to be trying to use `&Box<T>`. Consider using just `&T`
 
+#[allow(clippy::borrowed_box)]
+trait Trait {
+    fn f(b: &Box<bool>);
+}
+
+// Trait impls are not linted
+impl Trait for () {
+    fn f(_: &Box<bool>) {}
+}
+
 fn main() {
     test1(&mut Box::new(false));
     test2();
diff --git a/src/tools/clippy/tests/ui/borrow_box.stderr b/src/tools/clippy/tests/ui/borrow_box.stderr
index 34e8f11dfd743..6f80f86c3b3d4 100644
--- a/src/tools/clippy/tests/ui/borrow_box.stderr
+++ b/src/tools/clippy/tests/ui/borrow_box.stderr
@@ -23,43 +23,43 @@ LL |     fn test4(a: &Box<bool>);
    |                 ^^^^^^^^^^ help: try: `&bool`
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> tests/ui/borrow_box.rs:102:25
+  --> tests/ui/borrow_box.rs:96:25
    |
 LL | pub fn test14(_display: &Box<dyn Display>) {}
    |                         ^^^^^^^^^^^^^^^^^ help: try: `&dyn Display`
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> tests/ui/borrow_box.rs:104:25
+  --> tests/ui/borrow_box.rs:98:25
    |
 LL | pub fn test15(_display: &Box<dyn Display + Send>) {}
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(dyn Display + Send)`
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> tests/ui/borrow_box.rs:106:29
+  --> tests/ui/borrow_box.rs:100:29
    |
 LL | pub fn test16<'a>(_display: &'a Box<dyn Display + 'a>) {}
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&'a (dyn Display + 'a)`
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> tests/ui/borrow_box.rs:109:25
+  --> tests/ui/borrow_box.rs:103:25
    |
 LL | pub fn test17(_display: &Box<impl Display>) {}
    |                         ^^^^^^^^^^^^^^^^^^ help: try: `&impl Display`
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> tests/ui/borrow_box.rs:111:25
+  --> tests/ui/borrow_box.rs:105:25
    |
 LL | pub fn test18(_display: &Box<impl Display + Send>) {}
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(impl Display + Send)`
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> tests/ui/borrow_box.rs:113:29
+  --> tests/ui/borrow_box.rs:107:29
    |
 LL | pub fn test19<'a>(_display: &'a Box<impl Display + 'a>) {}
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&'a (impl Display + 'a)`
 
 error: you seem to be trying to use `&Box<T>`. Consider using just `&T`
-  --> tests/ui/borrow_box.rs:119:25
+  --> tests/ui/borrow_box.rs:113:25
    |
 LL | pub fn test20(_display: &Box<(dyn Display + Send)>) {}
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&(dyn Display + Send)`
diff --git a/src/tools/clippy/tests/ui/boxed_local.rs b/src/tools/clippy/tests/ui/boxed_local.rs
index fbd9e12fc1891..e2c27e585fce8 100644
--- a/src/tools/clippy/tests/ui/boxed_local.rs
+++ b/src/tools/clippy/tests/ui/boxed_local.rs
@@ -3,7 +3,8 @@
     clippy::needless_pass_by_value,
     clippy::unused_unit,
     clippy::redundant_clone,
-    clippy::match_single_binding
+    clippy::match_single_binding,
+    clippy::needless_lifetimes
 )]
 #![warn(clippy::boxed_local)]
 
diff --git a/src/tools/clippy/tests/ui/boxed_local.stderr b/src/tools/clippy/tests/ui/boxed_local.stderr
index 7710233fa4db8..d3156c820b2c5 100644
--- a/src/tools/clippy/tests/ui/boxed_local.stderr
+++ b/src/tools/clippy/tests/ui/boxed_local.stderr
@@ -1,5 +1,5 @@
 error: local variable doesn't need to be boxed here
-  --> tests/ui/boxed_local.rs:39:13
+  --> tests/ui/boxed_local.rs:40:13
    |
 LL | fn warn_arg(x: Box<A>) {
    |             ^
@@ -8,19 +8,19 @@ LL | fn warn_arg(x: Box<A>) {
    = help: to override `-D warnings` add `#[allow(clippy::boxed_local)]`
 
 error: local variable doesn't need to be boxed here
-  --> tests/ui/boxed_local.rs:122:12
+  --> tests/ui/boxed_local.rs:123:12
    |
 LL | pub fn new(_needs_name: Box<PeekableSeekable<&()>>) -> () {}
    |            ^^^^^^^^^^^
 
 error: local variable doesn't need to be boxed here
-  --> tests/ui/boxed_local.rs:187:44
+  --> tests/ui/boxed_local.rs:188:44
    |
 LL |         fn default_impl_x(self: Box<Self>, x: Box<u32>) -> u32 {
    |                                            ^
 
 error: local variable doesn't need to be boxed here
-  --> tests/ui/boxed_local.rs:195:16
+  --> tests/ui/boxed_local.rs:196:16
    |
 LL |         fn foo(x: Box<u32>) {}
    |                ^
diff --git a/src/tools/clippy/tests/ui/bytecount.rs b/src/tools/clippy/tests/ui/bytecount.rs
index 3794fc5d441c6..f3b02fda8a81e 100644
--- a/src/tools/clippy/tests/ui/bytecount.rs
+++ b/src/tools/clippy/tests/ui/bytecount.rs
@@ -1,4 +1,4 @@
-//@no-rustfix
+//@no-rustfix: suggests external crate
 
 #![allow(clippy::needless_borrow, clippy::useless_vec)]
 
diff --git a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.fixed b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.fixed
index 8bd9eea75bb26..837069cae6d15 100644
--- a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.fixed
+++ b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.fixed
@@ -9,7 +9,7 @@ struct Baz<'a> {
     bar: &'a Bar,
 }
 
-impl<'a> Foo for Baz<'a> {}
+impl Foo for Baz<'_> {}
 
 impl Bar {
     fn baz(&self) -> impl Foo + '_ {
diff --git a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr
index 3a2d1f4410ef1..bed6aab25c4d2 100644
--- a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr
+++ b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.stderr
@@ -1,8 +1,8 @@
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/crashes/needless_lifetimes_impl_trait.rs:15:12
+  --> tests/ui/crashes/needless_lifetimes_impl_trait.rs:12:6
    |
-LL |     fn baz<'a>(&'a self) -> impl Foo + 'a {
-   |            ^^   ^^                     ^^
+LL | impl<'a> Foo for Baz<'a> {}
+   |      ^^              ^^
    |
 note: the lint level is defined here
   --> tests/ui/crashes/needless_lifetimes_impl_trait.rs:1:9
@@ -11,9 +11,21 @@ LL | #![deny(clippy::needless_lifetimes)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 help: elide the lifetimes
    |
+LL - impl<'a> Foo for Baz<'a> {}
+LL + impl Foo for Baz<'_> {}
+   |
+
+error: the following explicit lifetimes could be elided: 'a
+  --> tests/ui/crashes/needless_lifetimes_impl_trait.rs:15:12
+   |
+LL |     fn baz<'a>(&'a self) -> impl Foo + 'a {
+   |            ^^   ^^                     ^^
+   |
+help: elide the lifetimes
+   |
 LL -     fn baz<'a>(&'a self) -> impl Foo + 'a {
 LL +     fn baz(&self) -> impl Foo + '_ {
    |
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui/deref_addrof_double_trigger.rs b/src/tools/clippy/tests/ui/deref_addrof_double_trigger.rs
index 32582a3a8bfa3..6f997875777e4 100644
--- a/src/tools/clippy/tests/ui/deref_addrof_double_trigger.rs
+++ b/src/tools/clippy/tests/ui/deref_addrof_double_trigger.rs
@@ -1,5 +1,5 @@
-// This test can't work with run-rustfix because it needs two passes of test+fix
-//@no-rustfix
+//@no-rustfix: this test can't work with run-rustfix because it needs two passes of test+fix
+
 #[warn(clippy::deref_addrof)]
 #[allow(unused_variables, unused_mut)]
 fn main() {
diff --git a/src/tools/clippy/tests/ui/derive.rs b/src/tools/clippy/tests/ui/derive.rs
index 20ac8a6e6be35..b06dd78608fdc 100644
--- a/src/tools/clippy/tests/ui/derive.rs
+++ b/src/tools/clippy/tests/ui/derive.rs
@@ -1,4 +1,9 @@
-#![allow(clippy::non_canonical_clone_impl, clippy::non_canonical_partial_ord_impl, dead_code)]
+#![allow(
+    clippy::non_canonical_clone_impl,
+    clippy::non_canonical_partial_ord_impl,
+    clippy::needless_lifetimes,
+    dead_code
+)]
 #![warn(clippy::expl_impl_clone_on_copy)]
 
 
diff --git a/src/tools/clippy/tests/ui/derive.stderr b/src/tools/clippy/tests/ui/derive.stderr
index d5f9d7cf2a2c8..0eb4b3c1adaa6 100644
--- a/src/tools/clippy/tests/ui/derive.stderr
+++ b/src/tools/clippy/tests/ui/derive.stderr
@@ -1,5 +1,5 @@
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:8:1
+  --> tests/ui/derive.rs:13:1
    |
 LL | / impl Clone for Qux {
 LL | |
@@ -10,7 +10,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:8:1
+  --> tests/ui/derive.rs:13:1
    |
 LL | / impl Clone for Qux {
 LL | |
@@ -23,7 +23,7 @@ LL | | }
    = help: to override `-D warnings` add `#[allow(clippy::expl_impl_clone_on_copy)]`
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:33:1
+  --> tests/ui/derive.rs:38:1
    |
 LL | / impl<'a> Clone for Lt<'a> {
 LL | |
@@ -34,7 +34,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:33:1
+  --> tests/ui/derive.rs:38:1
    |
 LL | / impl<'a> Clone for Lt<'a> {
 LL | |
@@ -45,7 +45,7 @@ LL | | }
    | |_^
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:45:1
+  --> tests/ui/derive.rs:50:1
    |
 LL | / impl Clone for BigArray {
 LL | |
@@ -56,7 +56,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:45:1
+  --> tests/ui/derive.rs:50:1
    |
 LL | / impl Clone for BigArray {
 LL | |
@@ -67,7 +67,7 @@ LL | | }
    | |_^
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:57:1
+  --> tests/ui/derive.rs:62:1
    |
 LL | / impl Clone for FnPtr {
 LL | |
@@ -78,7 +78,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:57:1
+  --> tests/ui/derive.rs:62:1
    |
 LL | / impl Clone for FnPtr {
 LL | |
@@ -89,7 +89,7 @@ LL | | }
    | |_^
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:78:1
+  --> tests/ui/derive.rs:83:1
    |
 LL | / impl<T: Clone> Clone for Generic2<T> {
 LL | |
@@ -100,7 +100,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:78:1
+  --> tests/ui/derive.rs:83:1
    |
 LL | / impl<T: Clone> Clone for Generic2<T> {
 LL | |
diff --git a/src/tools/clippy/tests/ui/eta.fixed b/src/tools/clippy/tests/ui/eta.fixed
index ca422ee29c104..f1baf28200e96 100644
--- a/src/tools/clippy/tests/ui/eta.fixed
+++ b/src/tools/clippy/tests/ui/eta.fixed
@@ -9,7 +9,8 @@
     clippy::redundant_closure_call,
     clippy::uninlined_format_args,
     clippy::useless_vec,
-    clippy::unnecessary_map_on_constructor
+    clippy::unnecessary_map_on_constructor,
+    clippy::needless_lifetimes
 )]
 
 use std::path::{Path, PathBuf};
diff --git a/src/tools/clippy/tests/ui/eta.rs b/src/tools/clippy/tests/ui/eta.rs
index c0db91c03ef45..c52a51880bfc9 100644
--- a/src/tools/clippy/tests/ui/eta.rs
+++ b/src/tools/clippy/tests/ui/eta.rs
@@ -9,7 +9,8 @@
     clippy::redundant_closure_call,
     clippy::uninlined_format_args,
     clippy::useless_vec,
-    clippy::unnecessary_map_on_constructor
+    clippy::unnecessary_map_on_constructor,
+    clippy::needless_lifetimes
 )]
 
 use std::path::{Path, PathBuf};
diff --git a/src/tools/clippy/tests/ui/eta.stderr b/src/tools/clippy/tests/ui/eta.stderr
index 5540261fc5744..1731a4377f534 100644
--- a/src/tools/clippy/tests/ui/eta.stderr
+++ b/src/tools/clippy/tests/ui/eta.stderr
@@ -1,5 +1,5 @@
 error: redundant closure
-  --> tests/ui/eta.rs:30:27
+  --> tests/ui/eta.rs:31:27
    |
 LL |     let a = Some(1u8).map(|a| foo(a));
    |                           ^^^^^^^^^^ help: replace the closure with the function itself: `foo`
@@ -8,31 +8,31 @@ LL |     let a = Some(1u8).map(|a| foo(a));
    = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]`
 
 error: redundant closure
-  --> tests/ui/eta.rs:34:40
+  --> tests/ui/eta.rs:35:40
    |
 LL |     let _: Option<Vec<u8>> = true.then(|| vec![]); // special case vec!
    |                                        ^^^^^^^^^ help: replace the closure with `Vec::new`: `std::vec::Vec::new`
 
 error: redundant closure
-  --> tests/ui/eta.rs:35:35
+  --> tests/ui/eta.rs:36:35
    |
 LL |     let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted?
    |                                   ^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo2`
 
 error: redundant closure
-  --> tests/ui/eta.rs:36:26
+  --> tests/ui/eta.rs:37:26
    |
 LL |     all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted
    |                          ^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `below`
 
 error: redundant closure
-  --> tests/ui/eta.rs:43:27
+  --> tests/ui/eta.rs:44:27
    |
 LL |     let e = Some(1u8).map(|a| generic(a));
    |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic`
 
 error: redundant closure
-  --> tests/ui/eta.rs:95:51
+  --> tests/ui/eta.rs:96:51
    |
 LL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
    |                                                   ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo`
@@ -41,169 +41,169 @@ LL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
    = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_for_method_calls)]`
 
 error: redundant closure
-  --> tests/ui/eta.rs:96:51
+  --> tests/ui/eta.rs:97:51
    |
 LL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo());
    |                                                   ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo`
 
 error: redundant closure
-  --> tests/ui/eta.rs:98:42
+  --> tests/ui/eta.rs:99:42
    |
 LL |     let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear());
    |                                          ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear`
 
 error: redundant closure
-  --> tests/ui/eta.rs:102:29
+  --> tests/ui/eta.rs:103:29
    |
 LL |     let e = Some("str").map(|s| s.to_string());
    |                             ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string`
 
 error: redundant closure
-  --> tests/ui/eta.rs:103:27
+  --> tests/ui/eta.rs:104:27
    |
 LL |     let e = Some('a').map(|s| s.to_uppercase());
    |                           ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase`
 
 error: redundant closure
-  --> tests/ui/eta.rs:105:65
+  --> tests/ui/eta.rs:106:65
    |
 LL |     let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect();
    |                                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase`
 
 error: redundant closure
-  --> tests/ui/eta.rs:168:22
+  --> tests/ui/eta.rs:169:22
    |
 LL |     requires_fn_once(|| x());
    |                      ^^^^^^ help: replace the closure with the function itself: `x`
 
 error: redundant closure
-  --> tests/ui/eta.rs:175:27
+  --> tests/ui/eta.rs:176:27
    |
 LL |     let a = Some(1u8).map(|a| foo_ptr(a));
    |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr`
 
 error: redundant closure
-  --> tests/ui/eta.rs:180:27
+  --> tests/ui/eta.rs:181:27
    |
 LL |     let a = Some(1u8).map(|a| closure(a));
    |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure`
 
 error: redundant closure
-  --> tests/ui/eta.rs:212:28
+  --> tests/ui/eta.rs:213:28
    |
 LL |     x.into_iter().for_each(|x| add_to_res(x));
    |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
 
 error: redundant closure
-  --> tests/ui/eta.rs:213:28
+  --> tests/ui/eta.rs:214:28
    |
 LL |     y.into_iter().for_each(|x| add_to_res(x));
    |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
 
 error: redundant closure
-  --> tests/ui/eta.rs:214:28
+  --> tests/ui/eta.rs:215:28
    |
 LL |     z.into_iter().for_each(|x| add_to_res(x));
    |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res`
 
 error: redundant closure
-  --> tests/ui/eta.rs:221:21
+  --> tests/ui/eta.rs:222:21
    |
 LL |         Some(1).map(|n| closure(n));
    |                     ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure`
 
 error: redundant closure
-  --> tests/ui/eta.rs:225:21
+  --> tests/ui/eta.rs:226:21
    |
 LL |         Some(1).map(|n| in_loop(n));
    |                     ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop`
 
 error: redundant closure
-  --> tests/ui/eta.rs:318:18
+  --> tests/ui/eta.rs:319:18
    |
 LL |     takes_fn_mut(|| f());
    |                  ^^^^^^ help: replace the closure with the function itself: `&mut f`
 
 error: redundant closure
-  --> tests/ui/eta.rs:321:19
+  --> tests/ui/eta.rs:322:19
    |
 LL |     takes_fn_once(|| f());
    |                   ^^^^^^ help: replace the closure with the function itself: `&mut f`
 
 error: redundant closure
-  --> tests/ui/eta.rs:325:26
+  --> tests/ui/eta.rs:326:26
    |
 LL |     move || takes_fn_mut(|| f_used_once())
    |                          ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once`
 
 error: redundant closure
-  --> tests/ui/eta.rs:337:19
+  --> tests/ui/eta.rs:338:19
    |
 LL |     array_opt.map(|a| a.as_slice());
    |                   ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice`
 
 error: redundant closure
-  --> tests/ui/eta.rs:340:19
+  --> tests/ui/eta.rs:341:19
    |
 LL |     slice_opt.map(|s| s.len());
    |                   ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len`
 
 error: redundant closure
-  --> tests/ui/eta.rs:343:17
+  --> tests/ui/eta.rs:344:17
    |
 LL |     ptr_opt.map(|p| p.is_null());
    |                 ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null`
 
 error: redundant closure
-  --> tests/ui/eta.rs:347:17
+  --> tests/ui/eta.rs:348:17
    |
 LL |     dyn_opt.map(|d| d.method_on_dyn());
    |                 ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<dyn TestTrait>::method_on_dyn`
 
 error: redundant closure
-  --> tests/ui/eta.rs:407:19
+  --> tests/ui/eta.rs:408:19
    |
 LL |     let _ = f(&0, |x, y| f2(x, y));
    |                   ^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `f2`
 
 error: redundant closure
-  --> tests/ui/eta.rs:435:22
+  --> tests/ui/eta.rs:436:22
    |
 LL |             test.map(|t| t.method())
    |                      ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `Test::method`
 
 error: redundant closure
-  --> tests/ui/eta.rs:439:22
+  --> tests/ui/eta.rs:440:22
    |
 LL |             test.map(|t| t.method())
    |                      ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `super::Outer::method`
 
 error: redundant closure
-  --> tests/ui/eta.rs:452:18
+  --> tests/ui/eta.rs:453:18
    |
 LL |         test.map(|t| t.method())
    |                  ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `test_mod::Test::method`
 
 error: redundant closure
-  --> tests/ui/eta.rs:459:30
+  --> tests/ui/eta.rs:460:30
    |
 LL |                     test.map(|t| t.method())
    |                              ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `crate::issue_10854::d::Test::method`
 
 error: redundant closure
-  --> tests/ui/eta.rs:478:38
+  --> tests/ui/eta.rs:479:38
    |
 LL |         let x = Box::new(|| None.map(|x| f(x)));
    |                                      ^^^^^^^^ help: replace the closure with the function itself: `&f`
 
 error: redundant closure
-  --> tests/ui/eta.rs:482:38
+  --> tests/ui/eta.rs:483:38
    |
 LL |         let x = Box::new(|| None.map(|x| f(x)));
    |                                      ^^^^^^^^ help: replace the closure with the function itself: `f`
 
 error: redundant closure
-  --> tests/ui/eta.rs:499:35
+  --> tests/ui/eta.rs:500:35
    |
 LL |         let _field = bind.or_else(|| get_default()).unwrap();
    |                                   ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `get_default`
diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed
index 255b2c5a220d8..9d476259b87e0 100644
--- a/src/tools/clippy/tests/ui/explicit_auto_deref.fixed
+++ b/src/tools/clippy/tests/ui/explicit_auto_deref.fixed
@@ -10,7 +10,8 @@
     clippy::redundant_field_names,
     clippy::too_many_arguments,
     clippy::borrow_deref_ref,
-    clippy::let_unit_value
+    clippy::let_unit_value,
+    clippy::needless_lifetimes
 )]
 
 trait CallableStr {
diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.rs b/src/tools/clippy/tests/ui/explicit_auto_deref.rs
index 99906999f01d9..23307c837f0e8 100644
--- a/src/tools/clippy/tests/ui/explicit_auto_deref.rs
+++ b/src/tools/clippy/tests/ui/explicit_auto_deref.rs
@@ -10,7 +10,8 @@
     clippy::redundant_field_names,
     clippy::too_many_arguments,
     clippy::borrow_deref_ref,
-    clippy::let_unit_value
+    clippy::let_unit_value,
+    clippy::needless_lifetimes
 )]
 
 trait CallableStr {
diff --git a/src/tools/clippy/tests/ui/explicit_auto_deref.stderr b/src/tools/clippy/tests/ui/explicit_auto_deref.stderr
index 53784934f6386..0b05a554eb11f 100644
--- a/src/tools/clippy/tests/ui/explicit_auto_deref.stderr
+++ b/src/tools/clippy/tests/ui/explicit_auto_deref.stderr
@@ -1,5 +1,5 @@
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:68:19
+  --> tests/ui/explicit_auto_deref.rs:69:19
    |
 LL |     let _: &str = &*s;
    |                   ^^^ help: try: `&s`
@@ -8,271 +8,271 @@ LL |     let _: &str = &*s;
    = help: to override `-D warnings` add `#[allow(clippy::explicit_auto_deref)]`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:69:19
+  --> tests/ui/explicit_auto_deref.rs:70:19
    |
 LL |     let _: &str = &*{ String::new() };
    |                   ^^^^^^^^^^^^^^^^^^^ help: try: `&{ String::new() }`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:70:19
+  --> tests/ui/explicit_auto_deref.rs:71:19
    |
 LL |     let _: &str = &mut *{ String::new() };
    |                   ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut { String::new() }`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:74:11
+  --> tests/ui/explicit_auto_deref.rs:75:11
    |
 LL |     f_str(&*s);
    |           ^^^ help: try: `&s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:78:13
+  --> tests/ui/explicit_auto_deref.rs:79:13
    |
 LL |     f_str_t(&*s, &*s); // Don't lint second param.
    |             ^^^ help: try: `&s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:81:24
+  --> tests/ui/explicit_auto_deref.rs:82:24
    |
 LL |     let _: &Box<i32> = &**b;
    |                        ^^^^ help: try: `&b`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:87:7
+  --> tests/ui/explicit_auto_deref.rs:88:7
    |
 LL |     c(&*s);
    |       ^^^ help: try: `&s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:93:9
+  --> tests/ui/explicit_auto_deref.rs:94:9
    |
 LL |         &**x
    |         ^^^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:97:11
+  --> tests/ui/explicit_auto_deref.rs:98:11
    |
 LL |         { &**x }
    |           ^^^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:101:9
+  --> tests/ui/explicit_auto_deref.rs:102:9
    |
 LL |         &**{ x }
    |         ^^^^^^^^ help: try: `{ x }`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:105:9
+  --> tests/ui/explicit_auto_deref.rs:106:9
    |
 LL |         &***x
    |         ^^^^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:122:12
+  --> tests/ui/explicit_auto_deref.rs:123:12
    |
 LL |         f1(&*x);
    |            ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:123:12
+  --> tests/ui/explicit_auto_deref.rs:124:12
    |
 LL |         f2(&*x);
    |            ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:124:12
+  --> tests/ui/explicit_auto_deref.rs:125:12
    |
 LL |         f3(&*x);
    |            ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:125:27
+  --> tests/ui/explicit_auto_deref.rs:126:27
    |
 LL |         f4.callable_str()(&*x);
    |                           ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:126:12
+  --> tests/ui/explicit_auto_deref.rs:127:12
    |
 LL |         f5(&*x);
    |            ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:127:12
+  --> tests/ui/explicit_auto_deref.rs:128:12
    |
 LL |         f6(&*x);
    |            ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:128:27
+  --> tests/ui/explicit_auto_deref.rs:129:27
    |
 LL |         f7.callable_str()(&*x);
    |                           ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:129:25
+  --> tests/ui/explicit_auto_deref.rs:130:25
    |
 LL |         f8.callable_t()(&*x);
    |                         ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:130:12
+  --> tests/ui/explicit_auto_deref.rs:131:12
    |
 LL |         f9(&*x);
    |            ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:131:13
+  --> tests/ui/explicit_auto_deref.rs:132:13
    |
 LL |         f10(&*x);
    |             ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:132:26
+  --> tests/ui/explicit_auto_deref.rs:133:26
    |
 LL |         f11.callable_t()(&*x);
    |                          ^^^ help: try: `&x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:136:16
+  --> tests/ui/explicit_auto_deref.rs:137:16
    |
 LL |     let _ = S1(&*s);
    |                ^^^ help: try: `&s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:141:21
+  --> tests/ui/explicit_auto_deref.rs:142:21
    |
 LL |     let _ = S2 { s: &*s };
    |                     ^^^ help: try: `&s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:157:30
+  --> tests/ui/explicit_auto_deref.rs:158:30
    |
 LL |             let _ = Self::S1(&**s);
    |                              ^^^^ help: try: `s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:158:35
+  --> tests/ui/explicit_auto_deref.rs:159:35
    |
 LL |             let _ = Self::S2 { s: &**s };
    |                                   ^^^^ help: try: `s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:161:20
+  --> tests/ui/explicit_auto_deref.rs:162:20
    |
 LL |     let _ = E1::S1(&*s);
    |                    ^^^ help: try: `&s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:162:25
+  --> tests/ui/explicit_auto_deref.rs:163:25
    |
 LL |     let _ = E1::S2 { s: &*s };
    |                         ^^^ help: try: `&s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:180:13
+  --> tests/ui/explicit_auto_deref.rs:181:13
    |
 LL |     let _ = (*b).foo;
    |             ^^^^ help: try: `b`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:181:13
+  --> tests/ui/explicit_auto_deref.rs:182:13
    |
 LL |     let _ = (**b).foo;
    |             ^^^^^ help: try: `b`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:196:19
+  --> tests/ui/explicit_auto_deref.rs:197:19
    |
 LL |     let _ = f_str(*ref_str);
    |                   ^^^^^^^^ help: try: `ref_str`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:198:19
+  --> tests/ui/explicit_auto_deref.rs:199:19
    |
 LL |     let _ = f_str(**ref_ref_str);
    |                   ^^^^^^^^^^^^^ help: try: `ref_ref_str`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:208:12
+  --> tests/ui/explicit_auto_deref.rs:209:12
    |
 LL |     f_str(&&*ref_str); // `needless_borrow` will suggest removing both references
    |            ^^^^^^^^^ help: try: `ref_str`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:209:12
+  --> tests/ui/explicit_auto_deref.rs:210:12
    |
 LL |     f_str(&&**ref_str); // `needless_borrow` will suggest removing only one reference
    |            ^^^^^^^^^^ help: try: `ref_str`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:218:41
+  --> tests/ui/explicit_auto_deref.rs:219:41
    |
 LL |     let _ = || -> &'static str { return *s };
    |                                         ^^ help: try: `s`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:237:9
+  --> tests/ui/explicit_auto_deref.rs:238:9
    |
 LL |         &**x
    |         ^^^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:260:8
+  --> tests/ui/explicit_auto_deref.rs:261:8
    |
 LL |     c1(*x);
    |        ^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:263:20
+  --> tests/ui/explicit_auto_deref.rs:264:20
    |
 LL |             return *x;
    |                    ^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:265:9
+  --> tests/ui/explicit_auto_deref.rs:266:9
    |
 LL |         *x
    |         ^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:299:20
+  --> tests/ui/explicit_auto_deref.rs:300:20
    |
 LL |         Some(x) => &mut *x,
    |                    ^^^^^^^ help: try: `x`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:332:22
+  --> tests/ui/explicit_auto_deref.rs:333:22
    |
 LL |         let _ = &mut (*{ x.u }).x;
    |                      ^^^^^^^^^^ help: try: `{ x.u }`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:338:22
+  --> tests/ui/explicit_auto_deref.rs:339:22
    |
 LL |         let _ = &mut (**x.u).x;
    |                      ^^^^^^^ help: try: `(*x.u)`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:339:22
+  --> tests/ui/explicit_auto_deref.rs:340:22
    |
 LL |         let _ = &mut (**{ x.u }).x;
    |                      ^^^^^^^^^^^ help: try: `{ x.u }`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:343:22
+  --> tests/ui/explicit_auto_deref.rs:344:22
    |
 LL |         let _ = &mut (*x.u).x;
    |                      ^^^^^^ help: try: `x.u`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:344:22
+  --> tests/ui/explicit_auto_deref.rs:345:22
    |
 LL |         let _ = &mut (*{ x.u }).x;
    |                      ^^^^^^^^^^ help: try: `{ x.u }`
 
 error: deref which would be done by auto-deref
-  --> tests/ui/explicit_auto_deref.rs:367:13
+  --> tests/ui/explicit_auto_deref.rs:368:13
    |
 LL |         foo(&*wrapped_bar);
    |             ^^^^^^^^^^^^^ help: try: `&wrapped_bar`
diff --git a/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs b/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs
index cdfaf8d3afea8..17d2ed9f50cfc 100644
--- a/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs
@@ -114,9 +114,17 @@ mod second_case {
         fn hey();
     }
 
+    // Should lint. The response to the above comment incorrectly called this a false positive. The
+    // lifetime `'a` can be removed, as demonstrated below.
     impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {
         fn hey() {}
     }
+
+    struct OtherBox<T: ?Sized>(Box<T>);
+
+    impl<T: Source + ?Sized> Source for OtherBox<T> {
+        fn hey() {}
+    }
 }
 
 // Should not lint
diff --git a/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr b/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr
index 56292cb5d1a51..85fbb7568ff4c 100644
--- a/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr
+++ b/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr
@@ -37,5 +37,11 @@ error: this lifetime isn't used in the function definition
 LL |         pub fn something<'c>() -> Self {
    |                          ^^
 
-error: aborting due to 6 previous errors
+error: this lifetime isn't used in the impl
+  --> tests/ui/extra_unused_lifetimes.rs:119:10
+   |
+LL |     impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {
+   |          ^^
+
+error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/float_cmp.rs b/src/tools/clippy/tests/ui/float_cmp.rs
index 78dd2c6c01c3d..a1dfd1954fced 100644
--- a/src/tools/clippy/tests/ui/float_cmp.rs
+++ b/src/tools/clippy/tests/ui/float_cmp.rs
@@ -8,7 +8,7 @@
     clippy::unnecessary_operation,
     clippy::cast_lossless
 )]
-//@no-rustfix
+//@no-rustfix: suggestions have an error margin placeholder
 use std::ops::Add;
 
 const ZERO: f32 = 0.0;
diff --git a/src/tools/clippy/tests/ui/float_cmp_const.rs b/src/tools/clippy/tests/ui/float_cmp_const.rs
index 0818055643734..ba760a18f28a1 100644
--- a/src/tools/clippy/tests/ui/float_cmp_const.rs
+++ b/src/tools/clippy/tests/ui/float_cmp_const.rs
@@ -1,5 +1,4 @@
-// does not test any rustfixable lints
-//@no-rustfix
+//@no-rustfix: suggestions have an error margin placeholder
 #![warn(clippy::float_cmp_const)]
 #![allow(clippy::float_cmp)]
 #![allow(unused, clippy::no_effect, clippy::unnecessary_operation)]
diff --git a/src/tools/clippy/tests/ui/float_cmp_const.stderr b/src/tools/clippy/tests/ui/float_cmp_const.stderr
index 4f88746e958e2..e0cd6faf4b3af 100644
--- a/src/tools/clippy/tests/ui/float_cmp_const.stderr
+++ b/src/tools/clippy/tests/ui/float_cmp_const.stderr
@@ -1,5 +1,5 @@
 error: strict comparison of `f32` or `f64` constant
-  --> tests/ui/float_cmp_const.rs:16:5
+  --> tests/ui/float_cmp_const.rs:15:5
    |
 LL |     1f32 == ONE;
    |     ^^^^^^^^^^^ help: consider comparing them within some margin of error: `(1f32 - ONE).abs() < error_margin`
@@ -8,43 +8,43 @@ LL |     1f32 == ONE;
    = help: to override `-D warnings` add `#[allow(clippy::float_cmp_const)]`
 
 error: strict comparison of `f32` or `f64` constant
-  --> tests/ui/float_cmp_const.rs:18:5
+  --> tests/ui/float_cmp_const.rs:17:5
    |
 LL |     TWO == ONE;
    |     ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() < error_margin`
 
 error: strict comparison of `f32` or `f64` constant
-  --> tests/ui/float_cmp_const.rs:20:5
+  --> tests/ui/float_cmp_const.rs:19:5
    |
 LL |     TWO != ONE;
    |     ^^^^^^^^^^ help: consider comparing them within some margin of error: `(TWO - ONE).abs() > error_margin`
 
 error: strict comparison of `f32` or `f64` constant
-  --> tests/ui/float_cmp_const.rs:22:5
+  --> tests/ui/float_cmp_const.rs:21:5
    |
 LL |     ONE + ONE == TWO;
    |     ^^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(ONE + ONE - TWO).abs() < error_margin`
 
 error: strict comparison of `f32` or `f64` constant
-  --> tests/ui/float_cmp_const.rs:25:5
+  --> tests/ui/float_cmp_const.rs:24:5
    |
 LL |     x as f32 == ONE;
    |     ^^^^^^^^^^^^^^^ help: consider comparing them within some margin of error: `(x as f32 - ONE).abs() < error_margin`
 
 error: strict comparison of `f32` or `f64` constant
-  --> tests/ui/float_cmp_const.rs:29:5
+  --> tests/ui/float_cmp_const.rs:28:5
    |
 LL |     v == ONE;
    |     ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() < error_margin`
 
 error: strict comparison of `f32` or `f64` constant
-  --> tests/ui/float_cmp_const.rs:31:5
+  --> tests/ui/float_cmp_const.rs:30:5
    |
 LL |     v != ONE;
    |     ^^^^^^^^ help: consider comparing them within some margin of error: `(v - ONE).abs() > error_margin`
 
 error: strict comparison of `f32` or `f64` constant arrays
-  --> tests/ui/float_cmp_const.rs:64:5
+  --> tests/ui/float_cmp_const.rs:63:5
    |
 LL |     NON_ZERO_ARRAY == NON_ZERO_ARRAY2;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/float_equality_without_abs.rs b/src/tools/clippy/tests/ui/float_equality_without_abs.rs
index 2b67c8bec1039..500b3035390fe 100644
--- a/src/tools/clippy/tests/ui/float_equality_without_abs.rs
+++ b/src/tools/clippy/tests/ui/float_equality_without_abs.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::float_equality_without_abs)]
-//@no-rustfix
+//@no-rustfix: suggestions cause type ambiguity
 
 // FIXME(f16_f128): add tests for these types when abs is available
 
diff --git a/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.rs b/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.rs
index 5bbdabcaad19b..a4cb50bd68220 100644
--- a/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.rs
+++ b/src/tools/clippy/tests/ui/index_refutable_slice/if_let_slice_binding.rs
@@ -1,5 +1,5 @@
 #![deny(clippy::index_refutable_slice)]
-#![allow(clippy::uninlined_format_args)]
+#![allow(clippy::uninlined_format_args, clippy::needless_lifetimes)]
 
 //@no-rustfix: need to change the suggestion to a multipart suggestion
 
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed
index eeddc2349a133..092e875a2554a 100644
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed
+++ b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.fixed
@@ -24,11 +24,8 @@ fn main() {
         let _a: A = std::ptr::read_volatile(core::ptr::NonNull::dangling().as_ptr());
 
         let _a: A = std::ptr::replace(core::ptr::NonNull::dangling().as_ptr(), A);
-
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(core::ptr::NonNull::dangling().as_ptr(), 0);
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(core::ptr::NonNull::dangling().as_ptr(), 0);
-
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts_mut(core::ptr::NonNull::dangling().as_ptr(), 0);
+        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null_mut(), 0); // shouldn't lint
+        let _slice: *const [usize] = std::ptr::slice_from_raw_parts_mut(std::ptr::null_mut(), 0);
 
         std::ptr::swap::<A>(core::ptr::NonNull::dangling().as_ptr(), &mut A);
         std::ptr::swap::<A>(&mut A, core::ptr::NonNull::dangling().as_ptr());
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs
index 8569b77408458..480b6642a3e3a 100644
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs
+++ b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.rs
@@ -24,10 +24,7 @@ fn main() {
         let _a: A = std::ptr::read_volatile(std::ptr::null_mut());
 
         let _a: A = std::ptr::replace(std::ptr::null_mut(), A);
-
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null(), 0);
-        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null_mut(), 0);
-
+        let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null_mut(), 0); // shouldn't lint
         let _slice: *const [usize] = std::ptr::slice_from_raw_parts_mut(std::ptr::null_mut(), 0);
 
         std::ptr::swap::<A>(std::ptr::null_mut(), &mut A);
diff --git a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr
index 54d79ba1aeb4f..a0be2c0ad75c6 100644
--- a/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr
+++ b/src/tools/clippy/tests/ui/invalid_null_ptr_usage.stderr
@@ -85,70 +85,52 @@ LL |         let _a: A = std::ptr::replace(std::ptr::null_mut(), A);
    |                                       ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:28:69
-   |
-LL |         let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null(), 0);
-   |                                                                     ^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:29:69
-   |
-LL |         let _slice: *const [usize] = std::ptr::slice_from_raw_parts(std::ptr::null_mut(), 0);
-   |                                                                     ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:31:73
-   |
-LL |         let _slice: *const [usize] = std::ptr::slice_from_raw_parts_mut(std::ptr::null_mut(), 0);
-   |                                                                         ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
-
-error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:33:29
+  --> tests/ui/invalid_null_ptr_usage.rs:30:29
    |
 LL |         std::ptr::swap::<A>(std::ptr::null_mut(), &mut A);
    |                             ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:34:37
+  --> tests/ui/invalid_null_ptr_usage.rs:31:37
    |
 LL |         std::ptr::swap::<A>(&mut A, std::ptr::null_mut());
    |                                     ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:36:44
+  --> tests/ui/invalid_null_ptr_usage.rs:33:44
    |
 LL |         std::ptr::swap_nonoverlapping::<A>(std::ptr::null_mut(), &mut A, 0);
    |                                            ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:37:52
+  --> tests/ui/invalid_null_ptr_usage.rs:34:52
    |
 LL |         std::ptr::swap_nonoverlapping::<A>(&mut A, std::ptr::null_mut(), 0);
    |                                                    ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:39:25
+  --> tests/ui/invalid_null_ptr_usage.rs:36:25
    |
 LL |         std::ptr::write(std::ptr::null_mut(), A);
    |                         ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:41:35
+  --> tests/ui/invalid_null_ptr_usage.rs:38:35
    |
 LL |         std::ptr::write_unaligned(std::ptr::null_mut(), A);
    |                                   ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:43:34
+  --> tests/ui/invalid_null_ptr_usage.rs:40:34
    |
 LL |         std::ptr::write_volatile(std::ptr::null_mut(), A);
    |                                  ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
 error: pointer must be non-null
-  --> tests/ui/invalid_null_ptr_usage.rs:45:40
+  --> tests/ui/invalid_null_ptr_usage.rs:42:40
    |
 LL |         std::ptr::write_bytes::<usize>(std::ptr::null_mut(), 42, 0);
    |                                        ^^^^^^^^^^^^^^^^^^^^ help: change this to: `core::ptr::NonNull::dangling().as_ptr()`
 
-error: aborting due to 25 previous errors
+error: aborting due to 22 previous errors
 
diff --git a/src/tools/clippy/tests/ui/iter_without_into_iter.rs b/src/tools/clippy/tests/ui/iter_without_into_iter.rs
index 3054d848efb7d..d5b28e45453b4 100644
--- a/src/tools/clippy/tests/ui/iter_without_into_iter.rs
+++ b/src/tools/clippy/tests/ui/iter_without_into_iter.rs
@@ -1,6 +1,7 @@
 //@no-rustfix
 //@aux-build:proc_macros.rs
 #![warn(clippy::iter_without_into_iter)]
+#![allow(clippy::needless_lifetimes)]
 extern crate proc_macros;
 
 pub struct S1;
diff --git a/src/tools/clippy/tests/ui/iter_without_into_iter.stderr b/src/tools/clippy/tests/ui/iter_without_into_iter.stderr
index 382a7606f48c6..7c42fa1dd89ce 100644
--- a/src/tools/clippy/tests/ui/iter_without_into_iter.stderr
+++ b/src/tools/clippy/tests/ui/iter_without_into_iter.stderr
@@ -1,5 +1,5 @@
 error: `iter` method without an `IntoIterator` impl for `&S1`
-  --> tests/ui/iter_without_into_iter.rs:8:5
+  --> tests/ui/iter_without_into_iter.rs:9:5
    |
 LL | /     pub fn iter(&self) -> std::slice::Iter<'_, u8> {
 LL | |
@@ -22,7 +22,7 @@ LL + }
    |
 
 error: `iter_mut` method without an `IntoIterator` impl for `&mut S1`
-  --> tests/ui/iter_without_into_iter.rs:12:5
+  --> tests/ui/iter_without_into_iter.rs:13:5
    |
 LL | /     pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
 LL | |
@@ -43,7 +43,7 @@ LL + }
    |
 
 error: `iter` method without an `IntoIterator` impl for `&S3<'a>`
-  --> tests/ui/iter_without_into_iter.rs:28:5
+  --> tests/ui/iter_without_into_iter.rs:29:5
    |
 LL | /     pub fn iter(&self) -> std::slice::Iter<'_, u8> {
 LL | |
@@ -64,7 +64,7 @@ LL + }
    |
 
 error: `iter_mut` method without an `IntoIterator` impl for `&mut S3<'a>`
-  --> tests/ui/iter_without_into_iter.rs:32:5
+  --> tests/ui/iter_without_into_iter.rs:33:5
    |
 LL | /     pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
 LL | |
@@ -85,7 +85,7 @@ LL + }
    |
 
 error: `iter` method without an `IntoIterator` impl for `&S8<T>`
-  --> tests/ui/iter_without_into_iter.rs:69:5
+  --> tests/ui/iter_without_into_iter.rs:70:5
    |
 LL | /     pub fn iter(&self) -> std::slice::Iter<'static, T> {
 LL | |         todo!()
@@ -105,7 +105,7 @@ LL + }
    |
 
 error: `iter` method without an `IntoIterator` impl for `&S9<T>`
-  --> tests/ui/iter_without_into_iter.rs:77:5
+  --> tests/ui/iter_without_into_iter.rs:78:5
    |
 LL | /     pub fn iter(&self) -> std::slice::Iter<'_, T> {
 LL | |
@@ -126,7 +126,7 @@ LL + }
    |
 
 error: `iter_mut` method without an `IntoIterator` impl for `&mut S9<T>`
-  --> tests/ui/iter_without_into_iter.rs:81:5
+  --> tests/ui/iter_without_into_iter.rs:82:5
    |
 LL | /     pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {
 LL | |
@@ -147,7 +147,7 @@ LL + }
    |
 
 error: `iter` method without an `IntoIterator` impl for `&Issue12037`
-  --> tests/ui/iter_without_into_iter.rs:130:13
+  --> tests/ui/iter_without_into_iter.rs:131:13
    |
 LL | /             fn iter(&self) -> std::slice::Iter<'_, u8> {
 LL | |                 todo!()
diff --git a/src/tools/clippy/tests/ui/mem_replace.fixed b/src/tools/clippy/tests/ui/mem_replace.fixed
index 78d8b3e9bce6b..4210dbbe82d37 100644
--- a/src/tools/clippy/tests/ui/mem_replace.fixed
+++ b/src/tools/clippy/tests/ui/mem_replace.fixed
@@ -1,6 +1,5 @@
-#![allow(unused)]
+#![allow(unused, clippy::needless_lifetimes)]
 #![warn(
-    clippy::all,
     clippy::style,
     clippy::mem_replace_option_with_none,
     clippy::mem_replace_with_default
diff --git a/src/tools/clippy/tests/ui/mem_replace.rs b/src/tools/clippy/tests/ui/mem_replace.rs
index 28915bf6daee8..bd7ad78b2af26 100644
--- a/src/tools/clippy/tests/ui/mem_replace.rs
+++ b/src/tools/clippy/tests/ui/mem_replace.rs
@@ -1,6 +1,5 @@
-#![allow(unused)]
+#![allow(unused, clippy::needless_lifetimes)]
 #![warn(
-    clippy::all,
     clippy::style,
     clippy::mem_replace_option_with_none,
     clippy::mem_replace_with_default
diff --git a/src/tools/clippy/tests/ui/mem_replace.stderr b/src/tools/clippy/tests/ui/mem_replace.stderr
index 44be2c9b63d75..c33f80b01b852 100644
--- a/src/tools/clippy/tests/ui/mem_replace.stderr
+++ b/src/tools/clippy/tests/ui/mem_replace.stderr
@@ -1,5 +1,5 @@
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace.rs:14:13
+  --> tests/ui/mem_replace.rs:13:13
    |
 LL |     let _ = mem::replace(&mut an_option, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
@@ -8,13 +8,13 @@ LL |     let _ = mem::replace(&mut an_option, None);
    = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace.rs:16:13
+  --> tests/ui/mem_replace.rs:15:13
    |
 LL |     let _ = mem::replace(an_option, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:21:13
+  --> tests/ui/mem_replace.rs:20:13
    |
 LL |     let _ = std::mem::replace(&mut s, String::default());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)`
@@ -23,127 +23,127 @@ LL |     let _ = std::mem::replace(&mut s, String::default());
    = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:24:13
+  --> tests/ui/mem_replace.rs:23:13
    |
 LL |     let _ = std::mem::replace(s, String::default());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:25:13
+  --> tests/ui/mem_replace.rs:24:13
    |
 LL |     let _ = std::mem::replace(s, Default::default());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(s)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:28:13
+  --> tests/ui/mem_replace.rs:27:13
    |
 LL |     let _ = std::mem::replace(&mut v, Vec::default());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:29:13
+  --> tests/ui/mem_replace.rs:28:13
    |
 LL |     let _ = std::mem::replace(&mut v, Default::default());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:30:13
+  --> tests/ui/mem_replace.rs:29:13
    |
 LL |     let _ = std::mem::replace(&mut v, Vec::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:31:13
+  --> tests/ui/mem_replace.rs:30:13
    |
 LL |     let _ = std::mem::replace(&mut v, vec![]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut v)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:34:13
+  --> tests/ui/mem_replace.rs:33:13
    |
 LL |     let _ = std::mem::replace(&mut hash_map, HashMap::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut hash_map)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:37:13
+  --> tests/ui/mem_replace.rs:36:13
    |
 LL |     let _ = std::mem::replace(&mut btree_map, BTreeMap::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut btree_map)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:40:13
+  --> tests/ui/mem_replace.rs:39:13
    |
 LL |     let _ = std::mem::replace(&mut vd, VecDeque::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut vd)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:43:13
+  --> tests/ui/mem_replace.rs:42:13
    |
 LL |     let _ = std::mem::replace(&mut hash_set, HashSet::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut hash_set)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:46:13
+  --> tests/ui/mem_replace.rs:45:13
    |
 LL |     let _ = std::mem::replace(&mut btree_set, BTreeSet::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut btree_set)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:49:13
+  --> tests/ui/mem_replace.rs:48:13
    |
 LL |     let _ = std::mem::replace(&mut list, LinkedList::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut list)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:52:13
+  --> tests/ui/mem_replace.rs:51:13
    |
 LL |     let _ = std::mem::replace(&mut binary_heap, BinaryHeap::new());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut binary_heap)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:55:13
+  --> tests/ui/mem_replace.rs:54:13
    |
 LL |     let _ = std::mem::replace(&mut tuple, (vec![], BinaryHeap::new()));
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut tuple)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:58:13
+  --> tests/ui/mem_replace.rs:57:13
    |
 LL |     let _ = std::mem::replace(&mut refstr, "");
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut refstr)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:61:13
+  --> tests/ui/mem_replace.rs:60:13
    |
 LL |     let _ = std::mem::replace(&mut slice, &[]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut slice)`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:97:13
+  --> tests/ui/mem_replace.rs:96:13
    |
 LL |     let _ = std::mem::replace(&mut s, String::default());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut s)`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace.rs:127:13
+  --> tests/ui/mem_replace.rs:126:13
    |
 LL |     let _ = std::mem::replace(&mut f.0, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace.rs:128:13
+  --> tests/ui/mem_replace.rs:127:13
    |
 LL |     let _ = std::mem::replace(&mut *f, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace.rs:129:13
+  --> tests/ui/mem_replace.rs:128:13
    |
 LL |     let _ = std::mem::replace(&mut b.opt, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`
-  --> tests/ui/mem_replace.rs:131:13
+  --> tests/ui/mem_replace.rs:130:13
    |
 LL |     let _ = std::mem::replace(&mut b.val, String::default());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::mem::take(&mut b.val)`
diff --git a/src/tools/clippy/tests/ui/mem_replace_no_std.fixed b/src/tools/clippy/tests/ui/mem_replace_no_std.fixed
index c970f2ba2814b..60f523c8ef1ec 100644
--- a/src/tools/clippy/tests/ui/mem_replace_no_std.fixed
+++ b/src/tools/clippy/tests/ui/mem_replace_no_std.fixed
@@ -1,6 +1,5 @@
-#![allow(unused)]
+#![allow(unused, clippy::needless_lifetimes)]
 #![warn(
-    clippy::all,
     clippy::style,
     clippy::mem_replace_option_with_none,
     clippy::mem_replace_with_default
diff --git a/src/tools/clippy/tests/ui/mem_replace_no_std.rs b/src/tools/clippy/tests/ui/mem_replace_no_std.rs
index 673d5c7b4f45a..d1cb9a5817bad 100644
--- a/src/tools/clippy/tests/ui/mem_replace_no_std.rs
+++ b/src/tools/clippy/tests/ui/mem_replace_no_std.rs
@@ -1,6 +1,5 @@
-#![allow(unused)]
+#![allow(unused, clippy::needless_lifetimes)]
 #![warn(
-    clippy::all,
     clippy::style,
     clippy::mem_replace_option_with_none,
     clippy::mem_replace_with_default
diff --git a/src/tools/clippy/tests/ui/mem_replace_no_std.stderr b/src/tools/clippy/tests/ui/mem_replace_no_std.stderr
index eea538da4277a..6ba6d2162a745 100644
--- a/src/tools/clippy/tests/ui/mem_replace_no_std.stderr
+++ b/src/tools/clippy/tests/ui/mem_replace_no_std.stderr
@@ -1,5 +1,5 @@
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace_no_std.rs:24:13
+  --> tests/ui/mem_replace_no_std.rs:23:13
    |
 LL |     let _ = mem::replace(&mut an_option, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
@@ -8,13 +8,13 @@ LL |     let _ = mem::replace(&mut an_option, None);
    = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace_no_std.rs:26:13
+  --> tests/ui/mem_replace_no_std.rs:25:13
    |
 LL |     let _ = mem::replace(an_option, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take`
-  --> tests/ui/mem_replace_no_std.rs:31:13
+  --> tests/ui/mem_replace_no_std.rs:30:13
    |
 LL |     let _ = mem::replace(&mut refstr, "");
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut refstr)`
@@ -23,25 +23,25 @@ LL |     let _ = mem::replace(&mut refstr, "");
    = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]`
 
 error: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take`
-  --> tests/ui/mem_replace_no_std.rs:34:13
+  --> tests/ui/mem_replace_no_std.rs:33:13
    |
 LL |     let _ = mem::replace(&mut slice, &[]);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut slice)`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace_no_std.rs:77:13
+  --> tests/ui/mem_replace_no_std.rs:76:13
    |
 LL |     let _ = mem::replace(&mut f.0, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace_no_std.rs:78:13
+  --> tests/ui/mem_replace_no_std.rs:77:13
    |
 LL |     let _ = mem::replace(&mut *f, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()`
 
 error: replacing an `Option` with `None`
-  --> tests/ui/mem_replace_no_std.rs:79:13
+  --> tests/ui/mem_replace_no_std.rs:78:13
    |
 LL |     let _ = mem::replace(&mut b.opt, None);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()`
diff --git a/src/tools/clippy/tests/ui/mismatching_type_param_order.rs b/src/tools/clippy/tests/ui/mismatching_type_param_order.rs
index af2882e41fb10..a4560f9e9a99b 100644
--- a/src/tools/clippy/tests/ui/mismatching_type_param_order.rs
+++ b/src/tools/clippy/tests/ui/mismatching_type_param_order.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::mismatching_type_param_order)]
-#![allow(clippy::disallowed_names)]
+#![allow(clippy::disallowed_names, clippy::needless_lifetimes)]
 
 fn main() {
     struct Foo<A, B> {
diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.fixed b/src/tools/clippy/tests/ui/mut_mutex_lock.fixed
index bbedbb2bed23f..29c5a27cb6247 100644
--- a/src/tools/clippy/tests/ui/mut_mutex_lock.fixed
+++ b/src/tools/clippy/tests/ui/mut_mutex_lock.fixed
@@ -9,6 +9,11 @@ fn mut_mutex_lock() {
 
     let mut value = value_mutex.get_mut().unwrap();
     *value += 1;
+
+    let mut value_mutex = Mutex::new(42_u8);
+    let mut_ref_mut_ref_mutex = &mut &mut value_mutex;
+    let mut value = mut_ref_mut_ref_mutex.get_mut().unwrap();
+    *value += 1;
 }
 
 fn no_owned_mutex_lock() {
@@ -24,4 +29,11 @@ fn issue9415() {
     *guard += 1;
 }
 
+fn mut_ref_ref_mutex_lock() {
+    let mutex = Mutex::new(42_u8);
+    let mut_ref_ref_mutex = &mut &mutex;
+    let mut guard = mut_ref_ref_mutex.lock().unwrap();
+    *guard += 1;
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.rs b/src/tools/clippy/tests/ui/mut_mutex_lock.rs
index 74116100e82a7..fcdb3ff97dbc5 100644
--- a/src/tools/clippy/tests/ui/mut_mutex_lock.rs
+++ b/src/tools/clippy/tests/ui/mut_mutex_lock.rs
@@ -9,6 +9,11 @@ fn mut_mutex_lock() {
 
     let mut value = value_mutex.lock().unwrap();
     *value += 1;
+
+    let mut value_mutex = Mutex::new(42_u8);
+    let mut_ref_mut_ref_mutex = &mut &mut value_mutex;
+    let mut value = mut_ref_mut_ref_mutex.lock().unwrap();
+    *value += 1;
 }
 
 fn no_owned_mutex_lock() {
@@ -24,4 +29,11 @@ fn issue9415() {
     *guard += 1;
 }
 
+fn mut_ref_ref_mutex_lock() {
+    let mutex = Mutex::new(42_u8);
+    let mut_ref_ref_mutex = &mut &mutex;
+    let mut guard = mut_ref_ref_mutex.lock().unwrap();
+    *guard += 1;
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/mut_mutex_lock.stderr b/src/tools/clippy/tests/ui/mut_mutex_lock.stderr
index a3d4905c04cb7..92601c4c61215 100644
--- a/src/tools/clippy/tests/ui/mut_mutex_lock.stderr
+++ b/src/tools/clippy/tests/ui/mut_mutex_lock.stderr
@@ -7,5 +7,11 @@ LL |     let mut value = value_mutex.lock().unwrap();
    = note: `-D clippy::mut-mutex-lock` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::mut_mutex_lock)]`
 
-error: aborting due to 1 previous error
+error: calling `&mut Mutex::lock` unnecessarily locks an exclusive (mutable) reference
+  --> tests/ui/mut_mutex_lock.rs:15:43
+   |
+LL |     let mut value = mut_ref_mut_ref_mutex.lock().unwrap();
+   |                                           ^^^^ help: change this to: `get_mut`
+
+error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_borrow.fixed b/src/tools/clippy/tests/ui/needless_borrow.fixed
index cabdc22bda840..2763830e09c9f 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.fixed
+++ b/src/tools/clippy/tests/ui/needless_borrow.fixed
@@ -4,7 +4,8 @@
     clippy::uninlined_format_args,
     clippy::unnecessary_mut_passed,
     clippy::unnecessary_to_owned,
-    clippy::unnecessary_literal_unwrap
+    clippy::unnecessary_literal_unwrap,
+    clippy::needless_lifetimes
 )]
 #![warn(clippy::needless_borrow)]
 
diff --git a/src/tools/clippy/tests/ui/needless_borrow.rs b/src/tools/clippy/tests/ui/needless_borrow.rs
index 50062589645f2..b46f82b18c641 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.rs
+++ b/src/tools/clippy/tests/ui/needless_borrow.rs
@@ -4,7 +4,8 @@
     clippy::uninlined_format_args,
     clippy::unnecessary_mut_passed,
     clippy::unnecessary_to_owned,
-    clippy::unnecessary_literal_unwrap
+    clippy::unnecessary_literal_unwrap,
+    clippy::needless_lifetimes
 )]
 #![warn(clippy::needless_borrow)]
 
diff --git a/src/tools/clippy/tests/ui/needless_borrow.stderr b/src/tools/clippy/tests/ui/needless_borrow.stderr
index bf0e265c25030..4b2b17e7e570a 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.stderr
+++ b/src/tools/clippy/tests/ui/needless_borrow.stderr
@@ -1,5 +1,5 @@
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:15:15
+  --> tests/ui/needless_borrow.rs:16:15
    |
 LL |     let _ = x(&&a); // warn
    |               ^^^ help: change this to: `&a`
@@ -8,163 +8,163 @@ LL |     let _ = x(&&a); // warn
    = help: to override `-D warnings` add `#[allow(clippy::needless_borrow)]`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:19:13
+  --> tests/ui/needless_borrow.rs:20:13
    |
 LL |     mut_ref(&mut &mut b); // warn
    |             ^^^^^^^^^^^ help: change this to: `&mut b`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:31:13
+  --> tests/ui/needless_borrow.rs:32:13
    |
 LL |             &&a
    |             ^^^ help: change this to: `&a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:33:15
+  --> tests/ui/needless_borrow.rs:34:15
    |
 LL |         46 => &&a,
    |               ^^^ help: change this to: `&a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:39:27
+  --> tests/ui/needless_borrow.rs:40:27
    |
 LL |                     break &ref_a;
    |                           ^^^^^^ help: change this to: `ref_a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:46:15
+  --> tests/ui/needless_borrow.rs:47:15
    |
 LL |     let _ = x(&&&a);
    |               ^^^^ help: change this to: `&a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:47:15
+  --> tests/ui/needless_borrow.rs:48:15
    |
 LL |     let _ = x(&mut &&a);
    |               ^^^^^^^^ help: change this to: `&a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:48:15
+  --> tests/ui/needless_borrow.rs:49:15
    |
 LL |     let _ = x(&&&mut b);
    |               ^^^^^^^^ help: change this to: `&mut b`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:49:15
+  --> tests/ui/needless_borrow.rs:50:15
    |
 LL |     let _ = x(&&ref_a);
    |               ^^^^^^^ help: change this to: `ref_a`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:52:11
+  --> tests/ui/needless_borrow.rs:53:11
    |
 LL |         x(&b);
    |           ^^ help: change this to: `b`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:59:13
+  --> tests/ui/needless_borrow.rs:60:13
    |
 LL |     mut_ref(&mut x);
    |             ^^^^^^ help: change this to: `x`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:60:13
+  --> tests/ui/needless_borrow.rs:61:13
    |
 LL |     mut_ref(&mut &mut x);
    |             ^^^^^^^^^^^ help: change this to: `x`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:61:23
+  --> tests/ui/needless_borrow.rs:62:23
    |
 LL |     let y: &mut i32 = &mut x;
    |                       ^^^^^^ help: change this to: `x`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:62:23
+  --> tests/ui/needless_borrow.rs:63:23
    |
 LL |     let y: &mut i32 = &mut &mut x;
    |                       ^^^^^^^^^^^ help: change this to: `x`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:71:14
+  --> tests/ui/needless_borrow.rs:72:14
    |
 LL |         0 => &mut x,
    |              ^^^^^^ help: change this to: `x`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:77:14
+  --> tests/ui/needless_borrow.rs:78:14
    |
 LL |         0 => &mut x,
    |              ^^^^^^ help: change this to: `x`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:89:13
+  --> tests/ui/needless_borrow.rs:90:13
    |
 LL |     let _ = (&x).0;
    |             ^^^^ help: change this to: `x`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:91:22
+  --> tests/ui/needless_borrow.rs:92:22
    |
 LL |     let _ = unsafe { (&*x).0 };
    |                      ^^^^^ help: change this to: `(*x)`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:101:5
+  --> tests/ui/needless_borrow.rs:102:5
    |
 LL |     (&&()).foo();
    |     ^^^^^^ help: change this to: `(&())`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:110:5
+  --> tests/ui/needless_borrow.rs:111:5
    |
 LL |     (&&5).foo();
    |     ^^^^^ help: change this to: `(&5)`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:136:23
+  --> tests/ui/needless_borrow.rs:137:23
    |
 LL |     let x: (&str,) = (&"",);
    |                       ^^^ help: change this to: `""`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:178:13
+  --> tests/ui/needless_borrow.rs:179:13
    |
 LL |             (&self.f)()
    |             ^^^^^^^^^ help: change this to: `(self.f)`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:187:13
+  --> tests/ui/needless_borrow.rs:188:13
    |
 LL |             (&mut self.f)()
    |             ^^^^^^^^^^^^^ help: change this to: `(self.f)`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:224:22
+  --> tests/ui/needless_borrow.rs:225:22
    |
 LL |         let _ = &mut (&mut { x.u }).x;
    |                      ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:231:22
+  --> tests/ui/needless_borrow.rs:232:22
    |
 LL |         let _ = &mut (&mut { x.u }).x;
    |                      ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:235:22
+  --> tests/ui/needless_borrow.rs:236:22
    |
 LL |         let _ = &mut (&mut x.u).x;
    |                      ^^^^^^^^^^ help: change this to: `x.u`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> tests/ui/needless_borrow.rs:236:22
+  --> tests/ui/needless_borrow.rs:237:22
    |
 LL |         let _ = &mut (&mut { x.u }).x;
    |                      ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
 
 error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> tests/ui/needless_borrow.rs:257:23
+  --> tests/ui/needless_borrow.rs:258:23
    |
 LL |     option.unwrap_or((&x.0,));
    |                       ^^^^ help: change this to: `x.0`
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.fixed b/src/tools/clippy/tests/ui/needless_lifetimes.fixed
index d1787b35abd23..cfa4cf9da3c56 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.fixed
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.fixed
@@ -329,7 +329,7 @@ mod issue2944 {
         bar: &'a Bar,
     }
 
-    impl<'a> Foo for Baz<'a> {}
+    impl Foo for Baz<'_> {}
     impl Bar {
         fn baz(&self) -> impl Foo + '_ {
             Baz { bar: self }
@@ -384,7 +384,7 @@ mod nested_elision_sites {
         f()
     }
     // lint
-    fn where_clause_elidadable<T>(i: &i32, f: T) -> &i32
+    fn where_clause_elidable<T>(i: &i32, f: T) -> &i32
     where
         T: Fn(&i32) -> &i32,
     {
@@ -543,4 +543,23 @@ mod issue5787 {
     }
 }
 
+// https://github.com/rust-lang/rust-clippy/pull/13286#issuecomment-2374245772
+mod rayon {
+    trait ParallelIterator {
+        type Item;
+    }
+
+    struct Copied<I: ParallelIterator> {
+        base: I,
+    }
+
+    impl<'a, T, I> ParallelIterator for Copied<I>
+    where
+        I: ParallelIterator<Item = &'a T>,
+        T: 'a + Copy + Send + Sync,
+    {
+        type Item = T;
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.rs b/src/tools/clippy/tests/ui/needless_lifetimes.rs
index 03d6f2013586c..5e9d51164268b 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.rs
@@ -384,7 +384,7 @@ mod nested_elision_sites {
         f()
     }
     // lint
-    fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32
+    fn where_clause_elidable<'a, T>(i: &'a i32, f: T) -> &'a i32
     where
         T: Fn(&i32) -> &i32,
     {
@@ -543,4 +543,23 @@ mod issue5787 {
     }
 }
 
+// https://github.com/rust-lang/rust-clippy/pull/13286#issuecomment-2374245772
+mod rayon {
+    trait ParallelIterator {
+        type Item;
+    }
+
+    struct Copied<I: ParallelIterator> {
+        base: I,
+    }
+
+    impl<'a, T, I> ParallelIterator for Copied<I>
+    where
+        I: ParallelIterator<Item = &'a T>,
+        T: 'a + Copy + Send + Sync,
+    {
+        type Item = T;
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.stderr b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
index 50f845e2d9291..e56c914cc86d6 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.stderr
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.stderr
@@ -335,6 +335,18 @@ LL -         fn needless_lt<'a>(_x: &'a u8) {}
 LL +         fn needless_lt(_x: &u8) {}
    |
 
+error: the following explicit lifetimes could be elided: 'a
+  --> tests/ui/needless_lifetimes.rs:332:10
+   |
+LL |     impl<'a> Foo for Baz<'a> {}
+   |          ^^              ^^
+   |
+help: elide the lifetimes
+   |
+LL -     impl<'a> Foo for Baz<'a> {}
+LL +     impl Foo for Baz<'_> {}
+   |
+
 error: the following explicit lifetimes could be elided: 'a
   --> tests/ui/needless_lifetimes.rs:334:16
    |
@@ -372,15 +384,15 @@ LL +     fn generics_elidable<T: Fn(&i32) -> &i32>(i: &i32, f: T) -> &i32 {
    |
 
 error: the following explicit lifetimes could be elided: 'a
-  --> tests/ui/needless_lifetimes.rs:387:32
+  --> tests/ui/needless_lifetimes.rs:387:30
    |
-LL |     fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32
-   |                                ^^         ^^                ^^
+LL |     fn where_clause_elidable<'a, T>(i: &'a i32, f: T) -> &'a i32
+   |                              ^^         ^^                ^^
    |
 help: elide the lifetimes
    |
-LL -     fn where_clause_elidadable<'a, T>(i: &'a i32, f: T) -> &'a i32
-LL +     fn where_clause_elidadable<T>(i: &i32, f: T) -> &i32
+LL -     fn where_clause_elidable<'a, T>(i: &'a i32, f: T) -> &'a i32
+LL +     fn where_clause_elidable<T>(i: &i32, f: T) -> &i32
    |
 
 error: the following explicit lifetimes could be elided: 'a
@@ -564,5 +576,5 @@ LL -         fn one_input<'a>(x: &'a u8) -> &'a u8 {
 LL +         fn one_input(x: &u8) -> &u8 {
    |
 
-error: aborting due to 47 previous errors
+error: aborting due to 48 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_value.rs b/src/tools/clippy/tests/ui/needless_pass_by_value.rs
index 9408b8c948fed..a8d9db95dcc77 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_value.rs
+++ b/src/tools/clippy/tests/ui/needless_pass_by_value.rs
@@ -5,7 +5,8 @@
     clippy::redundant_clone,
     clippy::redundant_pattern_matching,
     clippy::single_match,
-    clippy::uninlined_format_args
+    clippy::uninlined_format_args,
+    clippy::needless_lifetimes
 )]
 //@no-rustfix
 use std::borrow::Borrow;
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_value.stderr b/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
index 46ef8f3e8da43..2587d3f8c52f7 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
+++ b/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
@@ -1,5 +1,5 @@
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:18:23
+  --> tests/ui/needless_pass_by_value.rs:19:23
    |
 LL | fn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T> {
    |                       ^^^^^^ help: consider changing the type to: `&[T]`
@@ -8,55 +8,55 @@ LL | fn foo<T: Default>(v: Vec<T>, w: Vec<T>, mut x: Vec<T>, y: Vec<T>) -> Vec<T
    = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_value)]`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:34:11
+  --> tests/ui/needless_pass_by_value.rs:35:11
    |
 LL | fn bar(x: String, y: Wrapper) {
    |           ^^^^^^ help: consider changing the type to: `&str`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:34:22
+  --> tests/ui/needless_pass_by_value.rs:35:22
    |
 LL | fn bar(x: String, y: Wrapper) {
    |                      ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:42:71
+  --> tests/ui/needless_pass_by_value.rs:43:71
    |
 LL | fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: V) {
    |                                                                       ^ help: consider taking a reference instead: `&V`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:55:18
+  --> tests/ui/needless_pass_by_value.rs:56:18
    |
 LL | fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {
    |                  ^^^^^^^^^^^^^^^^^^^^^^ help: consider taking a reference instead: `&Option<Option<String>>`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:69:24
+  --> tests/ui/needless_pass_by_value.rs:70:24
    |
 LL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
    |                        ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:69:36
+  --> tests/ui/needless_pass_by_value.rs:70:36
    |
 LL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
    |                                    ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:87:49
+  --> tests/ui/needless_pass_by_value.rs:88:49
    |
 LL | fn test_blanket_ref<T: Foo, S: Serialize>(vals: T, serializable: S) {}
    |                                                 ^ help: consider taking a reference instead: `&T`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:90:18
+  --> tests/ui/needless_pass_by_value.rs:91:18
    |
 LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
    |                  ^^^^^^ help: consider taking a reference instead: `&String`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:90:29
+  --> tests/ui/needless_pass_by_value.rs:91:29
    |
 LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
    |                             ^^^^^^
@@ -71,13 +71,13 @@ LL |     let _ = t.to_string();
    |             ~~~~~~~~~~~~~
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:90:40
+  --> tests/ui/needless_pass_by_value.rs:91:40
    |
 LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
    |                                        ^^^^^^^^ help: consider taking a reference instead: `&Vec<i32>`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:90:53
+  --> tests/ui/needless_pass_by_value.rs:91:53
    |
 LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
    |                                                     ^^^^^^^^
@@ -92,85 +92,85 @@ LL |     let _ = v.to_owned();
    |             ~~~~~~~~~~~~
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:107:12
+  --> tests/ui/needless_pass_by_value.rs:108:12
    |
 LL |         s: String,
    |            ^^^^^^ help: consider changing the type to: `&str`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:109:12
+  --> tests/ui/needless_pass_by_value.rs:110:12
    |
 LL |         t: String,
    |            ^^^^^^ help: consider taking a reference instead: `&String`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:119:23
+  --> tests/ui/needless_pass_by_value.rs:120:23
    |
 LL |     fn baz(&self, uu: U, ss: Self) {}
    |                       ^ help: consider taking a reference instead: `&U`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:119:30
+  --> tests/ui/needless_pass_by_value.rs:120:30
    |
 LL |     fn baz(&self, uu: U, ss: Self) {}
    |                              ^^^^ help: consider taking a reference instead: `&Self`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:143:24
+  --> tests/ui/needless_pass_by_value.rs:144:24
    |
 LL | fn bar_copy(x: u32, y: CopyWrapper) {
    |                        ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
    |
 help: or consider marking this type as `Copy`
-  --> tests/ui/needless_pass_by_value.rs:141:1
+  --> tests/ui/needless_pass_by_value.rs:142:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:150:29
+  --> tests/ui/needless_pass_by_value.rs:151:29
    |
 LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
    |                             ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
    |
 help: or consider marking this type as `Copy`
-  --> tests/ui/needless_pass_by_value.rs:141:1
+  --> tests/ui/needless_pass_by_value.rs:142:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:150:45
+  --> tests/ui/needless_pass_by_value.rs:151:45
    |
 LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
    |                                             ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
    |
 help: or consider marking this type as `Copy`
-  --> tests/ui/needless_pass_by_value.rs:141:1
+  --> tests/ui/needless_pass_by_value.rs:142:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:150:61
+  --> tests/ui/needless_pass_by_value.rs:151:61
    |
 LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
    |                                                             ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
    |
 help: or consider marking this type as `Copy`
-  --> tests/ui/needless_pass_by_value.rs:141:1
+  --> tests/ui/needless_pass_by_value.rs:142:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:165:40
+  --> tests/ui/needless_pass_by_value.rs:166:40
    |
 LL | fn some_fun<'b, S: Bar<'b, ()>>(items: S) {}
    |                                        ^ help: consider taking a reference instead: `&S`
 
 error: this argument is passed by value, but not consumed in the function body
-  --> tests/ui/needless_pass_by_value.rs:171:20
+  --> tests/ui/needless_pass_by_value.rs:172:20
    |
 LL | fn more_fun(items: impl Club<'static, i32>) {}
    |                    ^^^^^^^^^^^^^^^^^^^^^^^ help: consider taking a reference instead: `&impl Club<'static, i32>`
diff --git a/src/tools/clippy/tests/ui/needless_return.fixed b/src/tools/clippy/tests/ui/needless_return.fixed
index c5c570690b450..ca422e605d666 100644
--- a/src/tools/clippy/tests/ui/needless_return.fixed
+++ b/src/tools/clippy/tests/ui/needless_return.fixed
@@ -360,3 +360,23 @@ fn issue12907() -> String {
 }
 
 fn main() {}
+
+fn a(x: Option<u8>) -> Option<u8> {
+    match x {
+        Some(_) => None,
+        None => {
+            #[expect(clippy::needless_return, reason = "Use early return for errors.")]
+            return None;
+        },
+    }
+}
+
+fn b(x: Option<u8>) -> Option<u8> {
+    match x {
+        Some(_) => None,
+        None => {
+            #[expect(clippy::needless_return)]
+            return None;
+        },
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_return.rs b/src/tools/clippy/tests/ui/needless_return.rs
index 738611391dfdf..aad6e13136f1a 100644
--- a/src/tools/clippy/tests/ui/needless_return.rs
+++ b/src/tools/clippy/tests/ui/needless_return.rs
@@ -370,3 +370,23 @@ fn issue12907() -> String {
 }
 
 fn main() {}
+
+fn a(x: Option<u8>) -> Option<u8> {
+    match x {
+        Some(_) => None,
+        None => {
+            #[expect(clippy::needless_return, reason = "Use early return for errors.")]
+            return None;
+        },
+    }
+}
+
+fn b(x: Option<u8>) -> Option<u8> {
+    match x {
+        Some(_) => None,
+        None => {
+            #[expect(clippy::needless_return)]
+            return None;
+        },
+    }
+}
diff --git a/src/tools/clippy/tests/ui/new_without_default.fixed b/src/tools/clippy/tests/ui/new_without_default.fixed
index 85408c4e17f45..5a6a92394a7fd 100644
--- a/src/tools/clippy/tests/ui/new_without_default.fixed
+++ b/src/tools/clippy/tests/ui/new_without_default.fixed
@@ -2,7 +2,8 @@
     dead_code,
     clippy::missing_safety_doc,
     clippy::extra_unused_lifetimes,
-    clippy::extra_unused_type_parameters
+    clippy::extra_unused_type_parameters,
+    clippy::needless_lifetimes
 )]
 #![warn(clippy::new_without_default)]
 
diff --git a/src/tools/clippy/tests/ui/new_without_default.rs b/src/tools/clippy/tests/ui/new_without_default.rs
index 3ac7292c2362f..12ea729253ac9 100644
--- a/src/tools/clippy/tests/ui/new_without_default.rs
+++ b/src/tools/clippy/tests/ui/new_without_default.rs
@@ -2,7 +2,8 @@
     dead_code,
     clippy::missing_safety_doc,
     clippy::extra_unused_lifetimes,
-    clippy::extra_unused_type_parameters
+    clippy::extra_unused_type_parameters,
+    clippy::needless_lifetimes
 )]
 #![warn(clippy::new_without_default)]
 
diff --git a/src/tools/clippy/tests/ui/new_without_default.stderr b/src/tools/clippy/tests/ui/new_without_default.stderr
index a30830ae7b2e9..57bf4bd847cce 100644
--- a/src/tools/clippy/tests/ui/new_without_default.stderr
+++ b/src/tools/clippy/tests/ui/new_without_default.stderr
@@ -1,5 +1,5 @@
 error: you should consider adding a `Default` implementation for `Foo`
-  --> tests/ui/new_without_default.rs:12:5
+  --> tests/ui/new_without_default.rs:13:5
    |
 LL | /     pub fn new() -> Foo {
 LL | |
@@ -20,7 +20,7 @@ LL + }
    |
 
 error: you should consider adding a `Default` implementation for `Bar`
-  --> tests/ui/new_without_default.rs:22:5
+  --> tests/ui/new_without_default.rs:23:5
    |
 LL | /     pub fn new() -> Self {
 LL | |
@@ -38,7 +38,7 @@ LL + }
    |
 
 error: you should consider adding a `Default` implementation for `LtKo<'c>`
-  --> tests/ui/new_without_default.rs:87:5
+  --> tests/ui/new_without_default.rs:88:5
    |
 LL | /     pub fn new() -> LtKo<'c> {
 LL | |
@@ -56,7 +56,7 @@ LL + }
    |
 
 error: you should consider adding a `Default` implementation for `Const`
-  --> tests/ui/new_without_default.rs:120:5
+  --> tests/ui/new_without_default.rs:121:5
    |
 LL | /     pub const fn new() -> Const {
 LL | |         Const
@@ -73,7 +73,7 @@ LL + }
    |
 
 error: you should consider adding a `Default` implementation for `NewNotEqualToDerive`
-  --> tests/ui/new_without_default.rs:180:5
+  --> tests/ui/new_without_default.rs:181:5
    |
 LL | /     pub fn new() -> Self {
 LL | |
@@ -91,7 +91,7 @@ LL + }
    |
 
 error: you should consider adding a `Default` implementation for `FooGenerics<T>`
-  --> tests/ui/new_without_default.rs:189:5
+  --> tests/ui/new_without_default.rs:190:5
    |
 LL | /     pub fn new() -> Self {
 LL | |
@@ -109,7 +109,7 @@ LL + }
    |
 
 error: you should consider adding a `Default` implementation for `BarGenerics<T>`
-  --> tests/ui/new_without_default.rs:197:5
+  --> tests/ui/new_without_default.rs:198:5
    |
 LL | /     pub fn new() -> Self {
 LL | |
@@ -127,7 +127,7 @@ LL + }
    |
 
 error: you should consider adding a `Default` implementation for `Foo<T>`
-  --> tests/ui/new_without_default.rs:209:9
+  --> tests/ui/new_without_default.rs:210:9
    |
 LL | /         pub fn new() -> Self {
 LL | |
@@ -147,7 +147,7 @@ LL ~     impl<T> Foo<T> {
    |
 
 error: you should consider adding a `Default` implementation for `MyStruct<K, V>`
-  --> tests/ui/new_without_default.rs:255:5
+  --> tests/ui/new_without_default.rs:256:5
    |
 LL | /     pub fn new() -> Self {
 LL | |         Self { _kv: None }
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed b/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
index cc91ba6ec66e1..a23310c1ad9fd 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.fixed
@@ -115,4 +115,66 @@ fn issue_12625() {
     if a as u64 > b {} //~ ERROR: this boolean expression can be simplified
 }
 
+fn issue_13436() {
+    fn not_zero(x: i32) -> bool {
+        x != 0
+    }
+
+    let opt = Some(500);
+    _ = opt.is_some_and(|x| x < 1000);
+    _ = opt.is_some_and(|x| x <= 1000);
+    _ = opt.is_some_and(|x| x > 1000);
+    _ = opt.is_some_and(|x| x >= 1000);
+    _ = opt.is_some_and(|x| x == 1000);
+    _ = opt.is_some_and(|x| x != 1000);
+    _ = opt.is_some_and(not_zero);
+    _ = opt.is_none_or(|x| x >= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x > 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x <= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x < 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x != 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x == 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(not_zero);
+    _ = opt.is_none_or(|x| x < 1000);
+    _ = opt.is_none_or(|x| x <= 1000);
+    _ = opt.is_none_or(|x| x > 1000);
+    _ = opt.is_none_or(|x| x >= 1000);
+    _ = opt.is_none_or(|x| x == 1000);
+    _ = opt.is_none_or(|x| x != 1000);
+    _ = opt.is_none_or(not_zero);
+    _ = opt.is_some_and(|x| x >= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_some_and(|x| x > 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_some_and(|x| x <= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_some_and(|x| x < 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_some_and(|x| x != 1000); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_some_and(|x| x == 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(not_zero);
+
+    let opt = Some(true);
+    _ = opt.is_some_and(|x| x);
+    _ = opt.is_some_and(|x| !x);
+    _ = !opt.is_some_and(|x| x);
+    _ = opt.is_none_or(|x| x); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x);
+    _ = opt.is_none_or(|x| !x);
+    _ = !opt.is_none_or(|x| x);
+    _ = opt.is_some_and(|x| x); //~ ERROR: this boolean expression can be simplified
+
+    let opt: Option<Result<i32, i32>> = Some(Ok(123));
+    _ = opt.is_some_and(|x| x.is_ok());
+    _ = opt.is_some_and(|x| x.is_err());
+    _ = opt.is_none_or(|x| x.is_ok());
+    _ = opt.is_none_or(|x| x.is_err());
+    _ = opt.is_none_or(|x| x.is_err()); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x.is_ok()); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_some_and(|x| x.is_err()); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_some_and(|x| x.is_ok()); //~ ERROR: this boolean expression can be simplified
+
+    #[clippy::msrv = "1.81"]
+    fn before_stabilization() {
+        let opt = Some(500);
+        _ = !opt.is_some_and(|x| x < 1000);
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs b/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
index c812f6f0ca4f5..6c844373af709 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.rs
@@ -115,4 +115,66 @@ fn issue_12625() {
     if !(a as u64 <= b) {} //~ ERROR: this boolean expression can be simplified
 }
 
+fn issue_13436() {
+    fn not_zero(x: i32) -> bool {
+        x != 0
+    }
+
+    let opt = Some(500);
+    _ = opt.is_some_and(|x| x < 1000);
+    _ = opt.is_some_and(|x| x <= 1000);
+    _ = opt.is_some_and(|x| x > 1000);
+    _ = opt.is_some_and(|x| x >= 1000);
+    _ = opt.is_some_and(|x| x == 1000);
+    _ = opt.is_some_and(|x| x != 1000);
+    _ = opt.is_some_and(not_zero);
+    _ = !opt.is_some_and(|x| x < 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(|x| x <= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(|x| x > 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(|x| x >= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(|x| x == 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(|x| x != 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(not_zero);
+    _ = opt.is_none_or(|x| x < 1000);
+    _ = opt.is_none_or(|x| x <= 1000);
+    _ = opt.is_none_or(|x| x > 1000);
+    _ = opt.is_none_or(|x| x >= 1000);
+    _ = opt.is_none_or(|x| x == 1000);
+    _ = opt.is_none_or(|x| x != 1000);
+    _ = opt.is_none_or(not_zero);
+    _ = !opt.is_none_or(|x| x < 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(|x| x <= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(|x| x > 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(|x| x >= 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(|x| x == 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(|x| x != 1000); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(not_zero);
+
+    let opt = Some(true);
+    _ = opt.is_some_and(|x| x);
+    _ = opt.is_some_and(|x| !x);
+    _ = !opt.is_some_and(|x| x);
+    _ = !opt.is_some_and(|x| !x); //~ ERROR: this boolean expression can be simplified
+    _ = opt.is_none_or(|x| x);
+    _ = opt.is_none_or(|x| !x);
+    _ = !opt.is_none_or(|x| x);
+    _ = !opt.is_none_or(|x| !x); //~ ERROR: this boolean expression can be simplified
+
+    let opt: Option<Result<i32, i32>> = Some(Ok(123));
+    _ = opt.is_some_and(|x| x.is_ok());
+    _ = opt.is_some_and(|x| x.is_err());
+    _ = opt.is_none_or(|x| x.is_ok());
+    _ = opt.is_none_or(|x| x.is_err());
+    _ = !opt.is_some_and(|x| x.is_ok()); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_some_and(|x| x.is_err()); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(|x| x.is_ok()); //~ ERROR: this boolean expression can be simplified
+    _ = !opt.is_none_or(|x| x.is_err()); //~ ERROR: this boolean expression can be simplified
+
+    #[clippy::msrv = "1.81"]
+    fn before_stabilization() {
+        let opt = Some(500);
+        _ = !opt.is_some_and(|x| x < 1000);
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr b/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
index d7adc0638b373..52803e828aed0 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods.stderr
@@ -97,5 +97,113 @@ error: this boolean expression can be simplified
 LL |     if !(a as u64 <= b) {}
    |        ^^^^^^^^^^^^^^^^ help: try: `a as u64 > b`
 
-error: aborting due to 16 previous errors
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:131:9
+   |
+LL |     _ = !opt.is_some_and(|x| x < 1000);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x >= 1000)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:132:9
+   |
+LL |     _ = !opt.is_some_and(|x| x <= 1000);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x > 1000)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:133:9
+   |
+LL |     _ = !opt.is_some_and(|x| x > 1000);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x <= 1000)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:134:9
+   |
+LL |     _ = !opt.is_some_and(|x| x >= 1000);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x < 1000)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:135:9
+   |
+LL |     _ = !opt.is_some_and(|x| x == 1000);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x != 1000)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:136:9
+   |
+LL |     _ = !opt.is_some_and(|x| x != 1000);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x == 1000)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:145:9
+   |
+LL |     _ = !opt.is_none_or(|x| x < 1000);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x >= 1000)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:146:9
+   |
+LL |     _ = !opt.is_none_or(|x| x <= 1000);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x > 1000)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:147:9
+   |
+LL |     _ = !opt.is_none_or(|x| x > 1000);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x <= 1000)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:148:9
+   |
+LL |     _ = !opt.is_none_or(|x| x >= 1000);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x < 1000)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:149:9
+   |
+LL |     _ = !opt.is_none_or(|x| x == 1000);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x != 1000)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:150:9
+   |
+LL |     _ = !opt.is_none_or(|x| x != 1000);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x == 1000)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:157:9
+   |
+LL |     _ = !opt.is_some_and(|x| !x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:161:9
+   |
+LL |     _ = !opt.is_none_or(|x| !x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:168:9
+   |
+LL |     _ = !opt.is_some_and(|x| x.is_ok());
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_err())`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:169:9
+   |
+LL |     _ = !opt.is_some_and(|x| x.is_err());
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_ok())`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:170:9
+   |
+LL |     _ = !opt.is_none_or(|x| x.is_ok());
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_err())`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:171:9
+   |
+LL |     _ = !opt.is_none_or(|x| x.is_err());
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_ok())`
+
+error: aborting due to 34 previous errors
 
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods_unfixable.rs b/src/tools/clippy/tests/ui/nonminimal_bool_methods_unfixable.rs
new file mode 100644
index 0000000000000..60b8da30a2f13
--- /dev/null
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods_unfixable.rs
@@ -0,0 +1,9 @@
+#![warn(clippy::nonminimal_bool)]
+//@no-rustfix
+
+fn issue_13436() {
+    let opt_opt = Some(Some(500));
+    _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000)); //~ ERROR: this boolean expression can be simplified
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool_methods_unfixable.stderr b/src/tools/clippy/tests/ui/nonminimal_bool_methods_unfixable.stderr
new file mode 100644
index 0000000000000..5a90155844cd3
--- /dev/null
+++ b/src/tools/clippy/tests/ui/nonminimal_bool_methods_unfixable.stderr
@@ -0,0 +1,17 @@
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods_unfixable.rs:6:9
+   |
+LL |     _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000));
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt_opt.is_none_or(|x| x.is_some_and(|y| y != 1000))`
+   |
+   = note: `-D clippy::nonminimal-bool` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods_unfixable.rs:6:34
+   |
+LL |     _ = !opt_opt.is_some_and(|x| !x.is_some_and(|y| y != 1000));
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.is_none_or(|y| y == 1000)`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/ref_as_ptr.fixed b/src/tools/clippy/tests/ui/ref_as_ptr.fixed
index 466a628a00265..6048267092f1b 100644
--- a/src/tools/clippy/tests/ui/ref_as_ptr.fixed
+++ b/src/tools/clippy/tests/ui/ref_as_ptr.fixed
@@ -1,5 +1,5 @@
 #![warn(clippy::ref_as_ptr)]
-#![allow(clippy::unnecessary_mut_passed)]
+#![allow(clippy::unnecessary_mut_passed, clippy::needless_lifetimes)]
 
 fn f<T>(_: T) {}
 
diff --git a/src/tools/clippy/tests/ui/ref_as_ptr.rs b/src/tools/clippy/tests/ui/ref_as_ptr.rs
index 0fdc753dc225a..7f1d59b856e4b 100644
--- a/src/tools/clippy/tests/ui/ref_as_ptr.rs
+++ b/src/tools/clippy/tests/ui/ref_as_ptr.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::ref_as_ptr)]
-#![allow(clippy::unnecessary_mut_passed)]
+#![allow(clippy::unnecessary_mut_passed, clippy::needless_lifetimes)]
 
 fn f<T>(_: T) {}
 
diff --git a/src/tools/clippy/tests/ui/ref_option/all/clippy.toml b/src/tools/clippy/tests/ui/ref_option/all/clippy.toml
new file mode 100644
index 0000000000000..cda8d17eed44c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/all/clippy.toml
@@ -0,0 +1 @@
+avoid-breaking-exported-api = false
diff --git a/src/tools/clippy/tests/ui/ref_option/private/clippy.toml b/src/tools/clippy/tests/ui/ref_option/private/clippy.toml
new file mode 100644
index 0000000000000..5f304987aa94a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/private/clippy.toml
@@ -0,0 +1 @@
+avoid-breaking-exported-api = true
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option.all.fixed b/src/tools/clippy/tests/ui/ref_option/ref_option.all.fixed
new file mode 100644
index 0000000000000..47781a97c983f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option.all.fixed
@@ -0,0 +1,62 @@
+//@revisions: private all
+//@[private] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/private
+//@[all] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/all
+
+#![allow(unused, clippy::needless_lifetimes, clippy::borrowed_box)]
+#![warn(clippy::ref_option)]
+
+fn opt_u8(a: Option<&u8>) {}
+fn opt_gen<T>(a: Option<&T>) {}
+fn opt_string(a: std::option::Option<&String>) {}
+fn ret_string<'a>(p: &'a str) -> Option<&'a u8> {
+    panic!()
+}
+fn ret_string_static() -> Option<&'static u8> {
+    panic!()
+}
+fn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}
+fn ret_box<'a>() -> Option<&'a Box<u8>> {
+    panic!()
+}
+
+pub fn pub_opt_string(a: Option<&String>) {}
+pub fn pub_mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}
+
+pub trait PubTrait {
+    fn pub_trait_opt(&self, a: Option<&Vec<u8>>);
+    fn pub_trait_ret(&self) -> Option<&Vec<u8>>;
+}
+
+trait PrivateTrait {
+    fn trait_opt(&self, a: Option<&String>);
+    fn trait_ret(&self) -> Option<&String>;
+}
+
+pub struct PubStruct;
+
+impl PubStruct {
+    pub fn pub_opt_params(&self, a: Option<&()>) {}
+    pub fn pub_opt_ret(&self) -> Option<&String> {
+        panic!()
+    }
+
+    fn private_opt_params(&self, a: Option<&()>) {}
+    fn private_opt_ret(&self) -> Option<&String> {
+        panic!()
+    }
+}
+
+// valid, don't change
+fn mut_u8(a: &mut Option<u8>) {}
+pub fn pub_mut_u8(a: &mut Option<String>) {}
+
+// might be good to catch in the future
+fn mut_u8_ref(a: &mut &Option<u8>) {}
+pub fn pub_mut_u8_ref(a: &mut &Option<String>) {}
+fn lambdas() {
+    // Not handled for now, not sure if we should
+    let x = |a: &Option<String>| {};
+    let x = |a: &Option<String>| -> &Option<String> { panic!() };
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option.all.stderr b/src/tools/clippy/tests/ui/ref_option/ref_option.all.stderr
new file mode 100644
index 0000000000000..b4c69ac629625
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option.all.stderr
@@ -0,0 +1,162 @@
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:8:1
+   |
+LL | fn opt_u8(a: &Option<u8>) {}
+   | ^^^^^^^^^^^^^-----------^^^^
+   |              |
+   |              help: change this to: `Option<&u8>`
+   |
+   = note: `-D clippy::ref-option` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::ref_option)]`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:9:1
+   |
+LL | fn opt_gen<T>(a: &Option<T>) {}
+   | ^^^^^^^^^^^^^^^^^----------^^^^
+   |                  |
+   |                  help: change this to: `Option<&T>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:10:1
+   |
+LL | fn opt_string(a: &std::option::Option<String>) {}
+   | ^^^^^^^^^^^^^^^^^----------------------------^^^^
+   |                  |
+   |                  help: change this to: `std::option::Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:11:1
+   |
+LL |   fn ret_string<'a>(p: &'a str) -> &'a Option<u8> {
+   |   ^                                -------------- help: change this to: `Option<&'a u8>`
+   |  _|
+   | |
+LL | |     panic!()
+LL | | }
+   | |_^
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:14:1
+   |
+LL |   fn ret_string_static() -> &'static Option<u8> {
+   |   ^                         ------------------- help: change this to: `Option<&'static u8>`
+   |  _|
+   | |
+LL | |     panic!()
+LL | | }
+   | |_^
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:17:1
+   |
+LL | fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: change this to
+   |
+LL | fn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}
+   |                   ~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:18:1
+   |
+LL |   fn ret_box<'a>() -> &'a Option<Box<u8>> {
+   |   ^                   ------------------- help: change this to: `Option<&'a Box<u8>>`
+   |  _|
+   | |
+LL | |     panic!()
+LL | | }
+   | |_^
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:22:1
+   |
+LL | pub fn pub_opt_string(a: &Option<String>) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^---------------^^^^
+   |                          |
+   |                          help: change this to: `Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:23:1
+   |
+LL | pub fn pub_mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: change this to
+   |
+LL | pub fn pub_mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}
+   |                           ~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:26:5
+   |
+LL |     fn pub_trait_opt(&self, a: &Option<Vec<u8>>);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------^^
+   |                                |
+   |                                help: change this to: `Option<&Vec<u8>>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:27:5
+   |
+LL |     fn pub_trait_ret(&self) -> &Option<Vec<u8>>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------^
+   |                                |
+   |                                help: change this to: `Option<&Vec<u8>>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:31:5
+   |
+LL |     fn trait_opt(&self, a: &Option<String>);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:32:5
+   |
+LL |     fn trait_ret(&self) -> &Option<String>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:38:5
+   |
+LL |     pub fn pub_opt_params(&self, a: &Option<()>) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^
+   |                                     |
+   |                                     help: change this to: `Option<&()>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:39:5
+   |
+LL |       pub fn pub_opt_ret(&self) -> &Option<String> {
+   |       ^                            --------------- help: change this to: `Option<&String>`
+   |  _____|
+   | |
+LL | |         panic!()
+LL | |     }
+   | |_____^
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:43:5
+   |
+LL |     fn private_opt_params(&self, a: &Option<()>) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^
+   |                                     |
+   |                                     help: change this to: `Option<&()>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:44:5
+   |
+LL |       fn private_opt_ret(&self) -> &Option<String> {
+   |       ^                            --------------- help: change this to: `Option<&String>`
+   |  _____|
+   | |
+LL | |         panic!()
+LL | |     }
+   | |_____^
+
+error: aborting due to 17 previous errors
+
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option.private.fixed b/src/tools/clippy/tests/ui/ref_option/ref_option.private.fixed
new file mode 100644
index 0000000000000..8c42556e9b0d7
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option.private.fixed
@@ -0,0 +1,62 @@
+//@revisions: private all
+//@[private] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/private
+//@[all] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/all
+
+#![allow(unused, clippy::needless_lifetimes, clippy::borrowed_box)]
+#![warn(clippy::ref_option)]
+
+fn opt_u8(a: Option<&u8>) {}
+fn opt_gen<T>(a: Option<&T>) {}
+fn opt_string(a: std::option::Option<&String>) {}
+fn ret_string<'a>(p: &'a str) -> Option<&'a u8> {
+    panic!()
+}
+fn ret_string_static() -> Option<&'static u8> {
+    panic!()
+}
+fn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}
+fn ret_box<'a>() -> Option<&'a Box<u8>> {
+    panic!()
+}
+
+pub fn pub_opt_string(a: &Option<String>) {}
+pub fn pub_mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}
+
+pub trait PubTrait {
+    fn pub_trait_opt(&self, a: &Option<Vec<u8>>);
+    fn pub_trait_ret(&self) -> &Option<Vec<u8>>;
+}
+
+trait PrivateTrait {
+    fn trait_opt(&self, a: Option<&String>);
+    fn trait_ret(&self) -> Option<&String>;
+}
+
+pub struct PubStruct;
+
+impl PubStruct {
+    pub fn pub_opt_params(&self, a: &Option<()>) {}
+    pub fn pub_opt_ret(&self) -> &Option<String> {
+        panic!()
+    }
+
+    fn private_opt_params(&self, a: Option<&()>) {}
+    fn private_opt_ret(&self) -> Option<&String> {
+        panic!()
+    }
+}
+
+// valid, don't change
+fn mut_u8(a: &mut Option<u8>) {}
+pub fn pub_mut_u8(a: &mut Option<String>) {}
+
+// might be good to catch in the future
+fn mut_u8_ref(a: &mut &Option<u8>) {}
+pub fn pub_mut_u8_ref(a: &mut &Option<String>) {}
+fn lambdas() {
+    // Not handled for now, not sure if we should
+    let x = |a: &Option<String>| {};
+    let x = |a: &Option<String>| -> &Option<String> { panic!() };
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option.private.stderr b/src/tools/clippy/tests/ui/ref_option/ref_option.private.stderr
new file mode 100644
index 0000000000000..17c90536da344
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option.private.stderr
@@ -0,0 +1,108 @@
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:8:1
+   |
+LL | fn opt_u8(a: &Option<u8>) {}
+   | ^^^^^^^^^^^^^-----------^^^^
+   |              |
+   |              help: change this to: `Option<&u8>`
+   |
+   = note: `-D clippy::ref-option` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::ref_option)]`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:9:1
+   |
+LL | fn opt_gen<T>(a: &Option<T>) {}
+   | ^^^^^^^^^^^^^^^^^----------^^^^
+   |                  |
+   |                  help: change this to: `Option<&T>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:10:1
+   |
+LL | fn opt_string(a: &std::option::Option<String>) {}
+   | ^^^^^^^^^^^^^^^^^----------------------------^^^^
+   |                  |
+   |                  help: change this to: `std::option::Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:11:1
+   |
+LL |   fn ret_string<'a>(p: &'a str) -> &'a Option<u8> {
+   |   ^                                -------------- help: change this to: `Option<&'a u8>`
+   |  _|
+   | |
+LL | |     panic!()
+LL | | }
+   | |_^
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:14:1
+   |
+LL |   fn ret_string_static() -> &'static Option<u8> {
+   |   ^                         ------------------- help: change this to: `Option<&'static u8>`
+   |  _|
+   | |
+LL | |     panic!()
+LL | | }
+   | |_^
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:17:1
+   |
+LL | fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: change this to
+   |
+LL | fn mult_string(a: Option<&String>, b: Option<&Vec<u8>>) {}
+   |                   ~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:18:1
+   |
+LL |   fn ret_box<'a>() -> &'a Option<Box<u8>> {
+   |   ^                   ------------------- help: change this to: `Option<&'a Box<u8>>`
+   |  _|
+   | |
+LL | |     panic!()
+LL | | }
+   | |_^
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:31:5
+   |
+LL |     fn trait_opt(&self, a: &Option<String>);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:32:5
+   |
+LL |     fn trait_ret(&self) -> &Option<String>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:43:5
+   |
+LL |     fn private_opt_params(&self, a: &Option<()>) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-----------^^^^
+   |                                     |
+   |                                     help: change this to: `Option<&()>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option.rs:44:5
+   |
+LL |       fn private_opt_ret(&self) -> &Option<String> {
+   |       ^                            --------------- help: change this to: `Option<&String>`
+   |  _____|
+   | |
+LL | |         panic!()
+LL | |     }
+   | |_____^
+
+error: aborting due to 11 previous errors
+
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option.rs b/src/tools/clippy/tests/ui/ref_option/ref_option.rs
new file mode 100644
index 0000000000000..05251bcf12cd0
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option.rs
@@ -0,0 +1,62 @@
+//@revisions: private all
+//@[private] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/private
+//@[all] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/all
+
+#![allow(unused, clippy::needless_lifetimes, clippy::borrowed_box)]
+#![warn(clippy::ref_option)]
+
+fn opt_u8(a: &Option<u8>) {}
+fn opt_gen<T>(a: &Option<T>) {}
+fn opt_string(a: &std::option::Option<String>) {}
+fn ret_string<'a>(p: &'a str) -> &'a Option<u8> {
+    panic!()
+}
+fn ret_string_static() -> &'static Option<u8> {
+    panic!()
+}
+fn mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}
+fn ret_box<'a>() -> &'a Option<Box<u8>> {
+    panic!()
+}
+
+pub fn pub_opt_string(a: &Option<String>) {}
+pub fn pub_mult_string(a: &Option<String>, b: &Option<Vec<u8>>) {}
+
+pub trait PubTrait {
+    fn pub_trait_opt(&self, a: &Option<Vec<u8>>);
+    fn pub_trait_ret(&self) -> &Option<Vec<u8>>;
+}
+
+trait PrivateTrait {
+    fn trait_opt(&self, a: &Option<String>);
+    fn trait_ret(&self) -> &Option<String>;
+}
+
+pub struct PubStruct;
+
+impl PubStruct {
+    pub fn pub_opt_params(&self, a: &Option<()>) {}
+    pub fn pub_opt_ret(&self) -> &Option<String> {
+        panic!()
+    }
+
+    fn private_opt_params(&self, a: &Option<()>) {}
+    fn private_opt_ret(&self) -> &Option<String> {
+        panic!()
+    }
+}
+
+// valid, don't change
+fn mut_u8(a: &mut Option<u8>) {}
+pub fn pub_mut_u8(a: &mut Option<String>) {}
+
+// might be good to catch in the future
+fn mut_u8_ref(a: &mut &Option<u8>) {}
+pub fn pub_mut_u8_ref(a: &mut &Option<String>) {}
+fn lambdas() {
+    // Not handled for now, not sure if we should
+    let x = |a: &Option<String>| {};
+    let x = |a: &Option<String>| -> &Option<String> { panic!() };
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option_traits.all.stderr b/src/tools/clippy/tests/ui/ref_option/ref_option_traits.all.stderr
new file mode 100644
index 0000000000000..a9967168c12e3
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option_traits.all.stderr
@@ -0,0 +1,37 @@
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option_traits.rs:10:5
+   |
+LL |     fn pub_trait_opt(&self, a: &Option<Vec<u8>>);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------^^
+   |                                |
+   |                                help: change this to: `Option<&Vec<u8>>`
+   |
+   = note: `-D clippy::ref-option` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::ref_option)]`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option_traits.rs:11:5
+   |
+LL |     fn pub_trait_ret(&self) -> &Option<Vec<u8>>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^----------------^
+   |                                |
+   |                                help: change this to: `Option<&Vec<u8>>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option_traits.rs:15:5
+   |
+LL |     fn trait_opt(&self, a: &Option<String>);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option_traits.rs:16:5
+   |
+LL |     fn trait_ret(&self) -> &Option<String>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option_traits.private.stderr b/src/tools/clippy/tests/ui/ref_option/ref_option_traits.private.stderr
new file mode 100644
index 0000000000000..36d0833af8a23
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option_traits.private.stderr
@@ -0,0 +1,21 @@
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option_traits.rs:15:5
+   |
+LL |     fn trait_opt(&self, a: &Option<String>);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+   |
+   = note: `-D clippy::ref-option` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::ref_option)]`
+
+error: it is more idiomatic to use `Option<&T>` instead of `&Option<T>`
+  --> tests/ui/ref_option/ref_option_traits.rs:16:5
+   |
+LL |     fn trait_ret(&self) -> &Option<String>;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^---------------^
+   |                            |
+   |                            help: change this to: `Option<&String>`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/ref_option/ref_option_traits.rs b/src/tools/clippy/tests/ui/ref_option/ref_option_traits.rs
new file mode 100644
index 0000000000000..5d5f113c83db5
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_option/ref_option_traits.rs
@@ -0,0 +1,37 @@
+//@no-rustfix: fixes are only done to traits, not the impls
+//@revisions: private all
+//@[private] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/private
+//@[all] rustc-env:CLIPPY_CONF_DIR=tests/ui/ref_option/all
+
+#![allow(unused, clippy::all)]
+#![warn(clippy::ref_option)]
+
+pub trait PubTrait {
+    fn pub_trait_opt(&self, a: &Option<Vec<u8>>);
+    fn pub_trait_ret(&self) -> &Option<Vec<u8>>;
+}
+
+trait PrivateTrait {
+    fn trait_opt(&self, a: &Option<String>);
+    fn trait_ret(&self) -> &Option<String>;
+}
+
+pub struct PubStruct;
+
+impl PubTrait for PubStruct {
+    fn pub_trait_opt(&self, a: &Option<Vec<u8>>) {}
+    fn pub_trait_ret(&self) -> &Option<Vec<u8>> {
+        panic!()
+    }
+}
+
+struct PrivateStruct;
+
+impl PrivateTrait for PrivateStruct {
+    fn trait_opt(&self, a: &Option<String>) {}
+    fn trait_ret(&self) -> &Option<String> {
+        panic!()
+    }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/serde.rs b/src/tools/clippy/tests/ui/serde.rs
index 610a50020ec56..af8b10f3e6aeb 100644
--- a/src/tools/clippy/tests/ui/serde.rs
+++ b/src/tools/clippy/tests/ui/serde.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::serde_api_misuse)]
-#![allow(dead_code)]
+#![allow(dead_code, clippy::needless_lifetimes)]
 
 extern crate serde;
 
diff --git a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs
index 0db6fbfb7be9b..8468d1d7c7d42 100644
--- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs
+++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.rs
@@ -2,7 +2,12 @@
 //@no-rustfix
 #![warn(clippy::significant_drop_in_scrutinee)]
 #![allow(dead_code, unused_assignments)]
-#![allow(clippy::match_single_binding, clippy::single_match, clippy::uninlined_format_args)]
+#![allow(
+    clippy::match_single_binding,
+    clippy::single_match,
+    clippy::uninlined_format_args,
+    clippy::needless_lifetimes
+)]
 
 use std::num::ParseIntError;
 use std::ops::Deref;
diff --git a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr
index c0c93cd10c027..62030cbe70e7f 100644
--- a/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr
+++ b/src/tools/clippy/tests/ui/significant_drop_in_scrutinee.stderr
@@ -1,5 +1,5 @@
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:55:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:60:11
    |
 LL |     match mutex.lock().unwrap().foo() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -20,7 +20,7 @@ LL ~     match value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:143:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:148:11
    |
 LL |     match s.lock_m().get_the_value() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -42,7 +42,7 @@ LL ~     match value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:166:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:171:11
    |
 LL |     match s.lock_m_m().get_the_value() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,7 +64,7 @@ LL ~     match value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:216:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:221:11
    |
 LL |     match counter.temp_increment().len() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -80,7 +80,7 @@ LL ~     match value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:241:16
+  --> tests/ui/significant_drop_in_scrutinee.rs:246:16
    |
 LL |         match (mutex1.lock().unwrap().s.len(), true) {
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -99,7 +99,7 @@ LL ~         match (value, true) {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:252:22
+  --> tests/ui/significant_drop_in_scrutinee.rs:257:22
    |
 LL |         match (true, mutex1.lock().unwrap().s.len(), true) {
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -118,7 +118,7 @@ LL ~         match (true, value, true) {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:264:16
+  --> tests/ui/significant_drop_in_scrutinee.rs:269:16
    |
 LL |         match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) {
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -139,7 +139,7 @@ LL ~         match (value, true, mutex2.lock().unwrap().s.len()) {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:264:54
+  --> tests/ui/significant_drop_in_scrutinee.rs:269:54
    |
 LL |         match (mutex1.lock().unwrap().s.len(), true, mutex2.lock().unwrap().s.len()) {
    |                                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -160,7 +160,7 @@ LL ~         match (mutex1.lock().unwrap().s.len(), true, value) {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:319:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:324:11
    |
 LL |     match mutex.lock().unwrap().s.len() > 1 {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -179,7 +179,7 @@ LL ~     match value > 1 {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:328:15
+  --> tests/ui/significant_drop_in_scrutinee.rs:333:15
    |
 LL |     match 1 < mutex.lock().unwrap().s.len() {
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -198,7 +198,7 @@ LL ~     match 1 < value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:348:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:353:11
    |
 LL |     match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -219,7 +219,7 @@ LL ~     match value < mutex2.lock().unwrap().s.len() {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:348:44
+  --> tests/ui/significant_drop_in_scrutinee.rs:353:44
    |
 LL |     match mutex1.lock().unwrap().s.len() < mutex2.lock().unwrap().s.len() {
    |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -240,7 +240,7 @@ LL ~     match mutex1.lock().unwrap().s.len() < value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:361:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:366:11
    |
 LL |     match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -261,7 +261,7 @@ LL ~     match value >= mutex2.lock().unwrap().s.len() {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:361:45
+  --> tests/ui/significant_drop_in_scrutinee.rs:366:45
    |
 LL |     match mutex1.lock().unwrap().s.len() >= mutex2.lock().unwrap().s.len() {
    |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -282,7 +282,7 @@ LL ~     match mutex1.lock().unwrap().s.len() >= value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:398:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:403:11
    |
 LL |     match get_mutex_guard().s.len() > 1 {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -301,7 +301,7 @@ LL ~     match value > 1 {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:417:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:422:11
    |
 LL |       match match i {
    |  ___________^
@@ -334,7 +334,7 @@ LL ~     match value
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:445:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:450:11
    |
 LL |       match if i > 1 {
    |  ___________^
@@ -368,7 +368,7 @@ LL ~     match value
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:501:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:506:11
    |
 LL |     match s.lock().deref().deref() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -386,7 +386,7 @@ LL ~     match (&value) {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:551:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:556:11
    |
 LL |     match mutex.lock().unwrap().i = i {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -405,7 +405,7 @@ LL ~     match () {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:559:15
+  --> tests/ui/significant_drop_in_scrutinee.rs:564:15
    |
 LL |     match i = mutex.lock().unwrap().i {
    |               ^^^^^^^^^^^^^^^^^^^^^^^
@@ -424,7 +424,7 @@ LL ~     match i = value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:567:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:572:11
    |
 LL |     match mutex.lock().unwrap().i += 1 {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -443,7 +443,7 @@ LL ~     match () {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:575:16
+  --> tests/ui/significant_drop_in_scrutinee.rs:580:16
    |
 LL |     match i += mutex.lock().unwrap().i {
    |                ^^^^^^^^^^^^^^^^^^^^^^^
@@ -462,7 +462,7 @@ LL ~     match i += value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:640:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:645:11
    |
 LL |     match rwlock.read().unwrap().to_number() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -478,7 +478,7 @@ LL ~     match value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:668:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:673:11
    |
 LL |     match mutex.lock().unwrap().foo() {
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -494,7 +494,7 @@ LL ~     match value {
    |
 
 error: temporary with significant `Drop` in `match` scrutinee will live until the end of the `match` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:731:11
+  --> tests/ui/significant_drop_in_scrutinee.rs:736:11
    |
 LL |     match guard.take().len() {
    |           ^^^^^^^^^^^^^^^^^^
@@ -510,7 +510,7 @@ LL ~     match value {
    |
 
 error: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:757:16
+  --> tests/ui/significant_drop_in_scrutinee.rs:762:16
    |
 LL |     for val in mutex.lock().unwrap().copy_old_lifetime() {
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -526,7 +526,7 @@ LL ~     for val in value {
    |
 
 error: temporary with significant `Drop` in `for` loop condition will live until the end of the `for` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:797:17
+  --> tests/ui/significant_drop_in_scrutinee.rs:802:17
    |
 LL |     for val in [mutex.lock().unwrap()[0], 2] {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -542,7 +542,7 @@ LL ~     for val in [value, 2] {
    |
 
 error: temporary with significant `Drop` in `if let` scrutinee will live until the end of the `if let` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:807:24
+  --> tests/ui/significant_drop_in_scrutinee.rs:812:24
    |
 LL |     if let Some(val) = mutex.lock().unwrap().first().copied() {
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -558,7 +558,7 @@ LL ~     if let Some(val) = value {
    |
 
 error: temporary with significant `Drop` in `while let` scrutinee will live until the end of the `while let` expression
-  --> tests/ui/significant_drop_in_scrutinee.rs:823:27
+  --> tests/ui/significant_drop_in_scrutinee.rs:828:27
    |
 LL |     while let Some(val) = mutex.lock().unwrap().pop() {
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/str_split.fixed b/src/tools/clippy/tests/ui/str_split.fixed
index 4f33241da7a22..57a3c315a8779 100644
--- a/src/tools/clippy/tests/ui/str_split.fixed
+++ b/src/tools/clippy/tests/ui/str_split.fixed
@@ -1,4 +1,5 @@
 #![warn(clippy::str_split_at_newline)]
+#![allow(clippy::needless_lifetimes)]
 
 use core::str::Split;
 use std::ops::Deref;
diff --git a/src/tools/clippy/tests/ui/str_split.rs b/src/tools/clippy/tests/ui/str_split.rs
index f24caa61c3053..fcff036f2649a 100644
--- a/src/tools/clippy/tests/ui/str_split.rs
+++ b/src/tools/clippy/tests/ui/str_split.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::str_split_at_newline)]
+#![allow(clippy::needless_lifetimes)]
 
 use core::str::Split;
 use std::ops::Deref;
diff --git a/src/tools/clippy/tests/ui/str_split.stderr b/src/tools/clippy/tests/ui/str_split.stderr
index ebe0d4ef4d301..7b560468f1269 100644
--- a/src/tools/clippy/tests/ui/str_split.stderr
+++ b/src/tools/clippy/tests/ui/str_split.stderr
@@ -1,5 +1,5 @@
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:59:13
+  --> tests/ui/str_split.rs:60:13
    |
 LL |     let _ = s1.trim().split('\n');
    |             ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s1.lines()`
@@ -8,55 +8,55 @@ LL |     let _ = s1.trim().split('\n');
    = help: to override `-D warnings` add `#[allow(clippy::str_split_at_newline)]`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:61:13
+  --> tests/ui/str_split.rs:62:13
    |
 LL |     let _ = s1.trim().split("\n");
    |             ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s1.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:62:13
+  --> tests/ui/str_split.rs:63:13
    |
 LL |     let _ = s1.trim().split("\r\n");
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s1.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:65:13
+  --> tests/ui/str_split.rs:66:13
    |
 LL |     let _ = s2.trim().split('\n');
    |             ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s2.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:67:13
+  --> tests/ui/str_split.rs:68:13
    |
 LL |     let _ = s2.trim().split("\n");
    |             ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s2.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:68:13
+  --> tests/ui/str_split.rs:69:13
    |
 LL |     let _ = s2.trim().split("\r\n");
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s2.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:72:13
+  --> tests/ui/str_split.rs:73:13
    |
 LL |     let _ = s3.trim().split('\n');
    |             ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s3.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:74:13
+  --> tests/ui/str_split.rs:75:13
    |
 LL |     let _ = s3.trim().split("\n");
    |             ^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s3.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:75:13
+  --> tests/ui/str_split.rs:76:13
    |
 LL |     let _ = s3.trim().split("\r\n");
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `s3.lines()`
 
 error: using `str.trim().split()` with hard-coded newlines
-  --> tests/ui/str_split.rs:78:13
+  --> tests/ui/str_split.rs:79:13
    |
 LL |     let _ = make_str!(s1).trim().split('\n');
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `str.lines()` instead: `make_str!(s1).lines()`
diff --git a/src/tools/clippy/tests/ui/temporary_assignment.rs b/src/tools/clippy/tests/ui/temporary_assignment.rs
index 383e70be925f7..d269f91b9fa82 100644
--- a/src/tools/clippy/tests/ui/temporary_assignment.rs
+++ b/src/tools/clippy/tests/ui/temporary_assignment.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::temporary_assignment)]
-#![allow(const_item_mutation)]
+#![allow(clippy::needless_lifetimes)]
 
 use std::ops::{Deref, DerefMut};
 
diff --git a/src/tools/clippy/tests/ui/unconditional_recursion.rs b/src/tools/clippy/tests/ui/unconditional_recursion.rs
index a51fc567f50c9..b8476a7088a10 100644
--- a/src/tools/clippy/tests/ui/unconditional_recursion.rs
+++ b/src/tools/clippy/tests/ui/unconditional_recursion.rs
@@ -4,7 +4,8 @@
 #![allow(
     clippy::partialeq_ne_impl,
     clippy::default_constructed_unit_structs,
-    clippy::only_used_in_recursion
+    clippy::only_used_in_recursion,
+    clippy::needless_lifetimes
 )]
 
 enum Foo {
diff --git a/src/tools/clippy/tests/ui/unconditional_recursion.stderr b/src/tools/clippy/tests/ui/unconditional_recursion.stderr
index 03c27bd8ed8aa..6a0078ee09068 100644
--- a/src/tools/clippy/tests/ui/unconditional_recursion.stderr
+++ b/src/tools/clippy/tests/ui/unconditional_recursion.stderr
@@ -1,5 +1,5 @@
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:46:5
+  --> tests/ui/unconditional_recursion.rs:47:5
    |
 LL |     fn ne(&self, other: &Self) -> bool {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -12,7 +12,7 @@ LL |         self.ne(other)
    = help: to override `-D warnings` add `#[allow(unconditional_recursion)]`
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:50:5
+  --> tests/ui/unconditional_recursion.rs:51:5
    |
 LL |     fn eq(&self, other: &Self) -> bool {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -23,7 +23,7 @@ LL |         self.eq(other)
    = help: a `loop` may express intention better if this is on purpose
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:215:5
+  --> tests/ui/unconditional_recursion.rs:216:5
    |
 LL |     fn to_string(&self) -> String {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -34,7 +34,7 @@ LL |         self.to_string()
    = help: a `loop` may express intention better if this is on purpose
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:225:5
+  --> tests/ui/unconditional_recursion.rs:226:5
    |
 LL |     fn to_string(&self) -> String {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -45,7 +45,7 @@ LL |         x.to_string()
    = help: a `loop` may express intention better if this is on purpose
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:236:5
+  --> tests/ui/unconditional_recursion.rs:237:5
    |
 LL |     fn to_string(&self) -> String {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -56,7 +56,7 @@ LL |         (self as &Self).to_string()
    = help: a `loop` may express intention better if this is on purpose
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:16:5
+  --> tests/ui/unconditional_recursion.rs:17:5
    |
 LL | /     fn ne(&self, other: &Self) -> bool {
 LL | |
@@ -65,7 +65,7 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:18:9
+  --> tests/ui/unconditional_recursion.rs:19:9
    |
 LL |         self != other
    |         ^^^^^^^^^^^^^
@@ -73,7 +73,7 @@ LL |         self != other
    = help: to override `-D warnings` add `#[allow(clippy::unconditional_recursion)]`
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:20:5
+  --> tests/ui/unconditional_recursion.rs:21:5
    |
 LL | /     fn eq(&self, other: &Self) -> bool {
 LL | |
@@ -82,13 +82,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:22:9
+  --> tests/ui/unconditional_recursion.rs:23:9
    |
 LL |         self == other
    |         ^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:32:5
+  --> tests/ui/unconditional_recursion.rs:33:5
    |
 LL | /     fn ne(&self, other: &Self) -> bool {
 LL | |         self != &Foo2::B // no error here
@@ -96,13 +96,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:33:9
+  --> tests/ui/unconditional_recursion.rs:34:9
    |
 LL |         self != &Foo2::B // no error here
    |         ^^^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:35:5
+  --> tests/ui/unconditional_recursion.rs:36:5
    |
 LL | /     fn eq(&self, other: &Self) -> bool {
 LL | |         self == &Foo2::B // no error here
@@ -110,13 +110,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:36:9
+  --> tests/ui/unconditional_recursion.rs:37:9
    |
 LL |         self == &Foo2::B // no error here
    |         ^^^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:46:5
+  --> tests/ui/unconditional_recursion.rs:47:5
    |
 LL | /     fn ne(&self, other: &Self) -> bool {
 LL | |
@@ -125,13 +125,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:48:9
+  --> tests/ui/unconditional_recursion.rs:49:9
    |
 LL |         self.ne(other)
    |         ^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:50:5
+  --> tests/ui/unconditional_recursion.rs:51:5
    |
 LL | /     fn eq(&self, other: &Self) -> bool {
 LL | |
@@ -140,13 +140,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:52:9
+  --> tests/ui/unconditional_recursion.rs:53:9
    |
 LL |         self.eq(other)
    |         ^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:94:5
+  --> tests/ui/unconditional_recursion.rs:95:5
    |
 LL | /     fn ne(&self, other: &Self) -> bool {
 LL | |
@@ -155,13 +155,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:96:9
+  --> tests/ui/unconditional_recursion.rs:97:9
    |
 LL |         other != self
    |         ^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:98:5
+  --> tests/ui/unconditional_recursion.rs:99:5
    |
 LL | /     fn eq(&self, other: &Self) -> bool {
 LL | |
@@ -170,13 +170,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:100:9
+  --> tests/ui/unconditional_recursion.rs:101:9
    |
 LL |         other == self
    |         ^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:108:5
+  --> tests/ui/unconditional_recursion.rs:109:5
    |
 LL | /     fn ne(&self, other: &Self) -> bool {
 LL | |
@@ -185,13 +185,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:110:9
+  --> tests/ui/unconditional_recursion.rs:111:9
    |
 LL |         other != other
    |         ^^^^^^^^^^^^^^
 
 error: equal expressions as operands to `!=`
-  --> tests/ui/unconditional_recursion.rs:110:9
+  --> tests/ui/unconditional_recursion.rs:111:9
    |
 LL |         other != other
    |         ^^^^^^^^^^^^^^
@@ -199,7 +199,7 @@ LL |         other != other
    = note: `#[deny(clippy::eq_op)]` on by default
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:112:5
+  --> tests/ui/unconditional_recursion.rs:113:5
    |
 LL | /     fn eq(&self, other: &Self) -> bool {
 LL | |
@@ -208,19 +208,19 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:114:9
+  --> tests/ui/unconditional_recursion.rs:115:9
    |
 LL |         other == other
    |         ^^^^^^^^^^^^^^
 
 error: equal expressions as operands to `==`
-  --> tests/ui/unconditional_recursion.rs:114:9
+  --> tests/ui/unconditional_recursion.rs:115:9
    |
 LL |         other == other
    |         ^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:121:5
+  --> tests/ui/unconditional_recursion.rs:122:5
    |
 LL | /     fn ne(&self, _other: &Self) -> bool {
 LL | |
@@ -229,19 +229,19 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:123:9
+  --> tests/ui/unconditional_recursion.rs:124:9
    |
 LL |         self != self
    |         ^^^^^^^^^^^^
 
 error: equal expressions as operands to `!=`
-  --> tests/ui/unconditional_recursion.rs:123:9
+  --> tests/ui/unconditional_recursion.rs:124:9
    |
 LL |         self != self
    |         ^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:125:5
+  --> tests/ui/unconditional_recursion.rs:126:5
    |
 LL | /     fn eq(&self, _other: &Self) -> bool {
 LL | |
@@ -250,19 +250,19 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:127:9
+  --> tests/ui/unconditional_recursion.rs:128:9
    |
 LL |         self == self
    |         ^^^^^^^^^^^^
 
 error: equal expressions as operands to `==`
-  --> tests/ui/unconditional_recursion.rs:127:9
+  --> tests/ui/unconditional_recursion.rs:128:9
    |
 LL |         self == self
    |         ^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:153:13
+  --> tests/ui/unconditional_recursion.rs:154:13
    |
 LL | /             fn eq(&self, other: &Self) -> bool {
 LL | |
@@ -274,7 +274,7 @@ LL |   impl_partial_eq!(S5);
    |   -------------------- in this macro invocation
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:155:17
+  --> tests/ui/unconditional_recursion.rs:156:17
    |
 LL |                 self == other
    |                 ^^^^^^^^^^^^^
@@ -284,7 +284,7 @@ LL | impl_partial_eq!(S5);
    = note: this error originates in the macro `impl_partial_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:182:5
+  --> tests/ui/unconditional_recursion.rs:183:5
    |
 LL | /     fn eq(&self, other: &Self) -> bool {
 LL | |
@@ -295,13 +295,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:186:9
+  --> tests/ui/unconditional_recursion.rs:187:9
    |
 LL |         mine == theirs
    |         ^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:251:5
+  --> tests/ui/unconditional_recursion.rs:252:5
    |
 LL | /     fn new() -> Self {
 LL | |
@@ -310,13 +310,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:253:9
+  --> tests/ui/unconditional_recursion.rs:254:9
    |
 LL |         Self::default()
    |         ^^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:290:5
+  --> tests/ui/unconditional_recursion.rs:291:5
    |
 LL | /     fn eq(&self, other: &Self) -> bool {
 LL | |
@@ -327,13 +327,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:294:9
+  --> tests/ui/unconditional_recursion.rs:295:9
    |
 LL |         mine.eq(theirs)
    |         ^^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:361:5
+  --> tests/ui/unconditional_recursion.rs:362:5
    |
 LL | /     fn from(f: BadFromTy1<'a>) -> Self {
 LL | |         f.into()
@@ -341,13 +341,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:362:9
+  --> tests/ui/unconditional_recursion.rs:363:9
    |
 LL |         f.into()
    |         ^^^^^^^^
 
 error: function cannot return without recursing
-  --> tests/ui/unconditional_recursion.rs:370:5
+  --> tests/ui/unconditional_recursion.rs:371:5
    |
 LL | /     fn from(f: BadFromTy2<'a>) -> Self {
 LL | |         Into::into(f)
@@ -355,7 +355,7 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> tests/ui/unconditional_recursion.rs:371:9
+  --> tests/ui/unconditional_recursion.rs:372:9
    |
 LL |         Into::into(f)
    |         ^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unused_async.rs b/src/tools/clippy/tests/ui/unused_async.rs
index 7ec8a3adb4cd5..838d6f0aa9711 100644
--- a/src/tools/clippy/tests/ui/unused_async.rs
+++ b/src/tools/clippy/tests/ui/unused_async.rs
@@ -55,6 +55,22 @@ mod issue9695 {
     }
 }
 
+mod issue13466 {
+    use std::future::Future;
+
+    struct Wrap<F>(F);
+    impl<F> From<F> for Wrap<F> {
+        fn from(f: F) -> Self {
+            Self(f)
+        }
+    }
+    fn takes_fut<F: Fn() -> Fut, Fut: Future>(_: Wrap<F>) {}
+    async fn unused_async() {}
+    fn fp() {
+        takes_fut(unused_async.into());
+    }
+}
+
 async fn foo() -> i32 {
     //~^ ERROR: unused `async` for function with no await statements
     4
diff --git a/src/tools/clippy/tests/ui/unused_async.stderr b/src/tools/clippy/tests/ui/unused_async.stderr
index 337c650e029f8..4811df63658a9 100644
--- a/src/tools/clippy/tests/ui/unused_async.stderr
+++ b/src/tools/clippy/tests/ui/unused_async.stderr
@@ -27,7 +27,7 @@ LL |     async fn f3() {}
    = help: consider removing the `async` from this function
 
 error: unused `async` for function with no await statements
-  --> tests/ui/unused_async.rs:58:1
+  --> tests/ui/unused_async.rs:74:1
    |
 LL | / async fn foo() -> i32 {
 LL | |
@@ -38,7 +38,7 @@ LL | | }
    = help: consider removing the `async` from this function
 
 error: unused `async` for function with no await statements
-  --> tests/ui/unused_async.rs:70:5
+  --> tests/ui/unused_async.rs:86:5
    |
 LL | /     async fn unused(&self) -> i32 {
 LL | |
diff --git a/src/tools/clippy/tests/ui/unused_format_specs.1.fixed b/src/tools/clippy/tests/ui/unused_format_specs.1.fixed
new file mode 100644
index 0000000000000..b7d1cce287016
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unused_format_specs.1.fixed
@@ -0,0 +1,35 @@
+#![warn(clippy::unused_format_specs)]
+#![allow(unused)]
+
+macro_rules! format_args_from_macro {
+    () => {
+        format_args!("from macro")
+    };
+}
+
+fn main() {
+    // prints `.`, not `     .`
+    println!("{:5}.", format!(""));
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+    //~| NOTE: `-D clippy::unused-format-specs` implied by `-D warnings`
+    //prints `abcde`, not `abc`
+    println!("{:.3}", format!("abcde"));
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+
+    println!("{}.", format_args_from_macro!());
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+
+    let args = format_args!("");
+    println!("{args}");
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+}
+
+fn should_not_lint() {
+    println!("{}", format_args!(""));
+    // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use
+    // debug formatting so allow it
+    println!("{:?}", format_args!(""));
+
+    let args = format_args!("");
+    println!("{args}");
+}
diff --git a/src/tools/clippy/tests/ui/unused_format_specs.2.fixed b/src/tools/clippy/tests/ui/unused_format_specs.2.fixed
new file mode 100644
index 0000000000000..94bb6b7036bde
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unused_format_specs.2.fixed
@@ -0,0 +1,35 @@
+#![warn(clippy::unused_format_specs)]
+#![allow(unused)]
+
+macro_rules! format_args_from_macro {
+    () => {
+        format_args!("from macro")
+    };
+}
+
+fn main() {
+    // prints `.`, not `     .`
+    println!("{}.", format_args!(""));
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+    //~| NOTE: `-D clippy::unused-format-specs` implied by `-D warnings`
+    //prints `abcde`, not `abc`
+    println!("{}", format_args!("abcde"));
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+
+    println!("{}.", format_args_from_macro!());
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+
+    let args = format_args!("");
+    println!("{args}");
+    //~^ ERROR: format specifiers have no effect on `format_args!()`
+}
+
+fn should_not_lint() {
+    println!("{}", format_args!(""));
+    // Technically the same as `{}`, but the `format_args` docs specifically mention that you can use
+    // debug formatting so allow it
+    println!("{:?}", format_args!(""));
+
+    let args = format_args!("");
+    println!("{args}");
+}
diff --git a/src/tools/clippy/tests/ui/unused_format_specs_unfixable.rs b/src/tools/clippy/tests/ui/unused_format_specs.rs
similarity index 98%
rename from src/tools/clippy/tests/ui/unused_format_specs_unfixable.rs
rename to src/tools/clippy/tests/ui/unused_format_specs.rs
index be991935366fe..2c85e3711493e 100644
--- a/src/tools/clippy/tests/ui/unused_format_specs_unfixable.rs
+++ b/src/tools/clippy/tests/ui/unused_format_specs.rs
@@ -1,6 +1,6 @@
 #![warn(clippy::unused_format_specs)]
 #![allow(unused)]
-//@no-rustfix
+
 macro_rules! format_args_from_macro {
     () => {
         format_args!("from macro")
diff --git a/src/tools/clippy/tests/ui/unused_format_specs_unfixable.stderr b/src/tools/clippy/tests/ui/unused_format_specs.stderr
similarity index 89%
rename from src/tools/clippy/tests/ui/unused_format_specs_unfixable.stderr
rename to src/tools/clippy/tests/ui/unused_format_specs.stderr
index d3b334c6092ed..2b5c81c63d600 100644
--- a/src/tools/clippy/tests/ui/unused_format_specs_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/unused_format_specs.stderr
@@ -1,5 +1,5 @@
 error: format specifiers have no effect on `format_args!()`
-  --> tests/ui/unused_format_specs_unfixable.rs:12:15
+  --> tests/ui/unused_format_specs.rs:12:15
    |
 LL |     println!("{:5}.", format_args!(""));
    |               ^^^^
@@ -17,7 +17,7 @@ LL +     println!("{}.", format_args!(""));
    |
 
 error: format specifiers have no effect on `format_args!()`
-  --> tests/ui/unused_format_specs_unfixable.rs:16:15
+  --> tests/ui/unused_format_specs.rs:16:15
    |
 LL |     println!("{:.3}", format_args!("abcde"));
    |               ^^^^^
@@ -33,7 +33,7 @@ LL +     println!("{}", format_args!("abcde"));
    |
 
 error: format specifiers have no effect on `format_args!()`
-  --> tests/ui/unused_format_specs_unfixable.rs:19:15
+  --> tests/ui/unused_format_specs.rs:19:15
    |
 LL |     println!("{:5}.", format_args_from_macro!());
    |               ^^^^
@@ -46,7 +46,7 @@ LL +     println!("{}.", format_args_from_macro!());
    |
 
 error: format specifiers have no effect on `format_args!()`
-  --> tests/ui/unused_format_specs_unfixable.rs:23:15
+  --> tests/ui/unused_format_specs.rs:23:15
    |
 LL |     println!("{args:5}");
    |               ^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/useful_asref.rs b/src/tools/clippy/tests/ui/useful_asref.rs
index a9f0170a79cd9..d17db9371ee8d 100644
--- a/src/tools/clippy/tests/ui/useful_asref.rs
+++ b/src/tools/clippy/tests/ui/useful_asref.rs
@@ -1,4 +1,5 @@
 #![deny(clippy::useless_asref)]
+#![allow(clippy::needless_lifetimes)]
 
 trait Trait {
     fn as_ptr(&self);
diff --git a/src/tools/clippy/tests/ui/wild_in_or_pats.rs b/src/tools/clippy/tests/ui/wild_in_or_pats.rs
index f8bb31b83c48b..bc8a1dbee71db 100644
--- a/src/tools/clippy/tests/ui/wild_in_or_pats.rs
+++ b/src/tools/clippy/tests/ui/wild_in_or_pats.rs
@@ -37,4 +37,72 @@ fn main() {
             dbg!("matched (bar or) wild");
         },
     };
+
+    // shouldn't lint
+    #[non_exhaustive]
+    pub enum NonExhaustiveEnum<'a> {
+        Message(&'a str),
+        Quit(&'a str),
+        Other,
+    }
+
+    match NonExhaustiveEnum::Message("Pass") {
+        NonExhaustiveEnum::Message(_) => dbg!("message"),
+        NonExhaustiveEnum::Quit(_) => dbg!("quit"),
+        NonExhaustiveEnum::Other | _ => dbg!("wildcard"),
+    };
+
+    // should lint
+    enum ExhaustiveEnum {
+        Quit,
+        Write(String),
+        ChangeColor(i32, i32, i32),
+    }
+
+    match ExhaustiveEnum::ChangeColor(0, 160, 255) {
+        ExhaustiveEnum::Write(text) => {
+            dbg!("Write");
+        },
+        ExhaustiveEnum::ChangeColor(r, g, b) => {
+            dbg!("Change the color");
+        },
+        ExhaustiveEnum::Quit | _ => {
+            dbg!("Quit or other");
+        },
+    };
+
+    // shouldn't lint
+    #[non_exhaustive]
+    struct NonExhaustiveStruct {
+        a: u32,
+        b: u32,
+        c: u64,
+    }
+
+    let b = NonExhaustiveStruct { a: 5, b: 42, c: 342 };
+
+    match b {
+        NonExhaustiveStruct { a: 5, b: 42, .. } => {},
+        NonExhaustiveStruct { a: 0, b: 0, c: 128 } => {},
+        NonExhaustiveStruct { a: 0, b: 0, c: 128, .. } | _ => {},
+    }
+
+    // should lint
+    struct ExhaustiveStruct {
+        x: i32,
+        y: i32,
+    }
+
+    let p = ExhaustiveStruct { x: 0, y: 7 };
+    match p {
+        ExhaustiveStruct { x: 0, y: 0 } => {
+            dbg!("On the x axis at {x}");
+        },
+        ExhaustiveStruct { x: 0, y: 1 } => {
+            dbg!("On the y axis at {y}");
+        },
+        ExhaustiveStruct { x: 1, y: 1 } | _ => {
+            dbg!("On neither axis: ({x}, {y})");
+        },
+    }
 }
diff --git a/src/tools/clippy/tests/ui/wild_in_or_pats.stderr b/src/tools/clippy/tests/ui/wild_in_or_pats.stderr
index 06b2415d221e9..5e409d6dfa6d7 100644
--- a/src/tools/clippy/tests/ui/wild_in_or_pats.stderr
+++ b/src/tools/clippy/tests/ui/wild_in_or_pats.stderr
@@ -32,5 +32,21 @@ LL |         _ | "bar" => {
    |
    = help: consider handling `_` separately
 
-error: aborting due to 4 previous errors
+error: wildcard pattern covers any other pattern as it will match anyway
+  --> tests/ui/wild_in_or_pats.rs:69:9
+   |
+LL |         ExhaustiveEnum::Quit | _ => {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider handling `_` separately
+
+error: wildcard pattern covers any other pattern as it will match anyway
+  --> tests/ui/wild_in_or_pats.rs:104:9
+   |
+LL |         ExhaustiveStruct { x: 1, y: 1 } | _ => {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider handling `_` separately
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/zombie_processes.rs b/src/tools/clippy/tests/ui/zombie_processes.rs
index a2abc7fc3a179..b41bcce3f7f7c 100644
--- a/src/tools/clippy/tests/ui/zombie_processes.rs
+++ b/src/tools/clippy/tests/ui/zombie_processes.rs
@@ -131,6 +131,13 @@ fn main() {
         }
         x.wait().unwrap();
     }
+
+    {
+        let mut x = Command::new("").spawn().unwrap();
+        std::thread::spawn(move || {
+            x.wait().unwrap();
+        });
+    }
 }
 
 fn process_child(c: Child) {