about summary refs log tree commit diff
path: root/clippy_lints/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-11-22 17:09:06 +0000
committerbors <bors@rust-lang.org>2022-11-22 17:09:06 +0000
commitb33afd61edfb690ace17d0672b367e44758c1bef (patch)
tree4b806322d7fb1463672319546e1aadc3e2a0b5cc /clippy_lints/src
parent9e093072457d9cafe8a7259992d1a05d179e4757 (diff)
parente95d40980b3044a6a9cad1b5e72eb57390790d18 (diff)
Auto merge of #104688 - flip1995:clippyup, r=Manishearth,flip1995
Update Clippy

r? `@Manishearth`

Sorry for taking so long. There were so many blockers and so little time. This situation should be mitigated with #104007 in the future.
Diffstat (limited to 'clippy_lints/src')
-rw-r--r--clippy_lints/src/attrs.rs37
-rw-r--r--clippy_lints/src/await_holding_invalid.rs3
-rw-r--r--clippy_lints/src/bool_to_int_with_if.rs27
-rw-r--r--clippy_lints/src/booleans.rs2
-rw-r--r--clippy_lints/src/casts/mod.rs2
-rw-r--r--clippy_lints/src/cognitive_complexity.rs21
-rw-r--r--clippy_lints/src/declared_lints.rs628
-rw-r--r--clippy_lints/src/dereference.rs128
-rw-r--r--clippy_lints/src/disallowed_macros.rs5
-rw-r--r--clippy_lints/src/disallowed_methods.rs5
-rw-r--r--clippy_lints/src/disallowed_types.rs40
-rw-r--r--clippy_lints/src/doc.rs123
-rw-r--r--clippy_lints/src/enum_variants.rs2
-rw-r--r--clippy_lints/src/equatable_if_let.rs27
-rw-r--r--clippy_lints/src/escape.rs8
-rw-r--r--clippy_lints/src/excessive_bools.rs129
-rw-r--r--clippy_lints/src/fallible_impl_from.rs2
-rw-r--r--clippy_lints/src/from_raw_with_void_ptr.rs77
-rw-r--r--clippy_lints/src/functions/mod.rs2
-rw-r--r--clippy_lints/src/functions/must_use.rs30
-rw-r--r--clippy_lints/src/functions/result.rs68
-rw-r--r--clippy_lints/src/implicit_hasher.rs4
-rw-r--r--clippy_lints/src/index_refutable_slice.rs4
-rw-r--r--clippy_lints/src/indexing_slicing.rs6
-rw-r--r--clippy_lints/src/instant_subtraction.rs184
-rw-r--r--clippy_lints/src/int_plus_one.rs28
-rw-r--r--clippy_lints/src/invalid_upcast_comparisons.rs2
-rw-r--r--clippy_lints/src/large_enum_variant.rs60
-rw-r--r--clippy_lints/src/len_zero.rs3
-rw-r--r--clippy_lints/src/let_underscore.rs157
-rw-r--r--clippy_lints/src/lib.register_all.rs368
-rw-r--r--clippy_lints/src/lib.register_cargo.rs11
-rw-r--r--clippy_lints/src/lib.register_complexity.rs111
-rw-r--r--clippy_lints/src/lib.register_correctness.rs78
-rw-r--r--clippy_lints/src/lib.register_internal.rs22
-rw-r--r--clippy_lints/src/lib.register_lints.rs620
-rw-r--r--clippy_lints/src/lib.register_nursery.rs39
-rw-r--r--clippy_lints/src/lib.register_pedantic.rs104
-rw-r--r--clippy_lints/src/lib.register_perf.rs34
-rw-r--r--clippy_lints/src/lib.register_restriction.rs90
-rw-r--r--clippy_lints/src/lib.register_style.rs131
-rw-r--r--clippy_lints/src/lib.register_suspicious.rs38
-rw-r--r--clippy_lints/src/lib.rs267
-rw-r--r--clippy_lints/src/lifetimes.rs131
-rw-r--r--clippy_lints/src/loops/mod.rs26
-rw-r--r--clippy_lints/src/loops/mut_range_bound.rs12
-rw-r--r--clippy_lints/src/loops/never_loop.rs114
-rw-r--r--clippy_lints/src/manual_instant_elapsed.rs69
-rw-r--r--clippy_lints/src/manual_is_ascii_check.rs158
-rw-r--r--clippy_lints/src/manual_let_else.rs297
-rw-r--r--clippy_lints/src/map_unit_fn.rs2
-rw-r--r--clippy_lints/src/matches/infallible_destructuring_match.rs7
-rw-r--r--clippy_lints/src/matches/manual_filter.rs2
-rw-r--r--clippy_lints/src/matches/significant_drop_in_scrutinee.rs8
-rw-r--r--clippy_lints/src/matches/single_match.rs2
-rw-r--r--clippy_lints/src/methods/chars_cmp_with_unwrap.rs4
-rw-r--r--clippy_lints/src/methods/chars_last_cmp.rs2
-rw-r--r--clippy_lints/src/methods/chars_last_cmp_with_unwrap.rs2
-rw-r--r--clippy_lints/src/methods/chars_next_cmp.rs2
-rw-r--r--clippy_lints/src/methods/chars_next_cmp_with_unwrap.rs2
-rw-r--r--clippy_lints/src/methods/collapsible_str_replace.rs6
-rw-r--r--clippy_lints/src/methods/expect_used.rs10
-rw-r--r--clippy_lints/src/methods/filter_map.rs8
-rw-r--r--clippy_lints/src/methods/inefficient_to_string.rs4
-rw-r--r--clippy_lints/src/methods/iter_nth_zero.rs2
-rw-r--r--clippy_lints/src/methods/iter_on_single_or_empty_collections.rs2
-rw-r--r--clippy_lints/src/methods/manual_saturating_arithmetic.rs2
-rw-r--r--clippy_lints/src/methods/manual_str_repeat.rs2
-rw-r--r--clippy_lints/src/methods/map_clone.rs4
-rw-r--r--clippy_lints/src/methods/map_collect_result_unit.rs15
-rw-r--r--clippy_lints/src/methods/map_err_ignore.rs2
-rw-r--r--clippy_lints/src/methods/mod.rs281
-rw-r--r--clippy_lints/src/methods/needless_collect.rs (renamed from clippy_lints/src/loops/needless_collect.rs)223
-rw-r--r--clippy_lints/src/methods/option_as_ref_deref.rs4
-rw-r--r--clippy_lints/src/methods/or_fun_call.rs57
-rw-r--r--clippy_lints/src/methods/seek_from_current.rs48
-rw-r--r--clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs45
-rw-r--r--clippy_lints/src/methods/string_extend_chars.rs6
-rw-r--r--clippy_lints/src/methods/suspicious_map.rs2
-rw-r--r--clippy_lints/src/methods/unnecessary_join.rs2
-rw-r--r--clippy_lints/src/methods/unwrap_used.rs10
-rw-r--r--clippy_lints/src/missing_enforced_import_rename.rs2
-rw-r--r--clippy_lints/src/mixed_read_write_in_expression.rs4
-rw-r--r--clippy_lints/src/mut_key.rs155
-rw-r--r--clippy_lints/src/mut_mut.rs16
-rw-r--r--clippy_lints/src/needless_borrowed_ref.rs108
-rw-r--r--clippy_lints/src/needless_continue.rs8
-rw-r--r--clippy_lints/src/needless_pass_by_value.rs8
-rw-r--r--clippy_lints/src/octal_escapes.rs4
-rw-r--r--clippy_lints/src/operators/arithmetic_side_effects.rs110
-rw-r--r--clippy_lints/src/operators/op_ref.rs2
-rw-r--r--clippy_lints/src/option_if_let_else.rs13
-rw-r--r--clippy_lints/src/partialeq_to_none.rs2
-rw-r--r--clippy_lints/src/pattern_type_mismatch.rs4
-rw-r--r--clippy_lints/src/ptr_offset_with_cast.rs8
-rw-r--r--clippy_lints/src/question_mark.rs1
-rw-r--r--clippy_lints/src/redundant_closure_call.rs4
-rw-r--r--clippy_lints/src/redundant_pub_crate.rs3
-rw-r--r--clippy_lints/src/renamed_lints.rs5
-rw-r--r--clippy_lints/src/single_component_path_imports.rs219
-rw-r--r--clippy_lints/src/slow_vector_initialization.rs2
-rw-r--r--clippy_lints/src/suspicious_xor_used_as_pow.rs53
-rw-r--r--clippy_lints/src/swap.rs8
-rw-r--r--clippy_lints/src/trailing_empty_array.rs8
-rw-r--r--clippy_lints/src/transmute/transmute_undefined_repr.rs164
-rw-r--r--clippy_lints/src/transmute/utils.rs11
-rw-r--r--clippy_lints/src/types/box_collection.rs19
-rw-r--r--clippy_lints/src/types/mod.rs4
-rw-r--r--clippy_lints/src/types/redundant_allocation.rs24
-rw-r--r--clippy_lints/src/types/vec_box.rs2
-rw-r--r--clippy_lints/src/undocumented_unsafe_blocks.rs40
-rw-r--r--clippy_lints/src/unsafe_removed_from_name.rs2
-rw-r--r--clippy_lints/src/unused_peekable.rs2
-rw-r--r--clippy_lints/src/unused_rounding.rs11
-rw-r--r--clippy_lints/src/unused_unit.rs8
-rw-r--r--clippy_lints/src/use_self.rs39
-rw-r--r--clippy_lints/src/utils/conf.rs31
-rw-r--r--clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs4
-rw-r--r--clippy_lints/src/utils/internal_lints/invalid_paths.rs4
-rw-r--r--clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs2
-rw-r--r--clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs45
-rw-r--r--clippy_lints/src/write.rs17
122 files changed, 3324 insertions, 3154 deletions
diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs
index 0bd1f8b784e..ecf8e83375d 100644
--- a/clippy_lints/src/attrs.rs
+++ b/clippy_lints/src/attrs.rs
@@ -11,14 +11,14 @@ use rustc_errors::Applicability;
 use rustc_hir::{
     Block, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, StmtKind, TraitFn, TraitItem, TraitItemKind,
 };
-use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
+use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_semver::RustcVersion;
 use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::Span;
-use rustc_span::sym;
 use rustc_span::symbol::Symbol;
+use rustc_span::{sym, DUMMY_SP};
 use semver::Version;
 
 static UNIX_SYSTEMS: &[&str] = &[
@@ -303,6 +303,26 @@ declare_lint_pass!(Attributes => [
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Attributes {
+    fn check_crate(&mut self, cx: &LateContext<'tcx>) {
+        for (name, level) in &cx.sess().opts.lint_opts {
+            if name == "clippy::restriction" && *level > Level::Allow {
+                span_lint_and_then(
+                    cx,
+                    BLANKET_CLIPPY_RESTRICTION_LINTS,
+                    DUMMY_SP,
+                    "`clippy::restriction` is not meant to be enabled as a group",
+                    |diag| {
+                        diag.note(format!(
+                            "because of the command line `--{} clippy::restriction`",
+                            level.as_str()
+                        ));
+                        diag.help("enable the restriction lints you need individually");
+                    },
+                );
+            }
+        }
+    }
+
     fn check_attribute(&mut self, cx: &LateContext<'tcx>, attr: &'tcx Attribute) {
         if let Some(items) = &attr.meta_item_list() {
             if let Some(ident) = attr.ident() {
@@ -358,7 +378,9 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
                                                         | "enum_glob_use"
                                                         | "redundant_pub_crate"
                                                         | "macro_use_imports"
-                                                        | "unsafe_removed_from_name",
+                                                        | "unsafe_removed_from_name"
+                                                        | "module_name_repetitions"
+                                                        | "single_component_path_imports"
                                                 )
                                             })
                                         {
@@ -441,9 +463,9 @@ fn check_clippy_lint_names(cx: &LateContext<'_>, name: Symbol, items: &[NestedMe
                     cx,
                     BLANKET_CLIPPY_RESTRICTION_LINTS,
                     lint.span(),
-                    "restriction lints are not meant to be all enabled",
+                    "`clippy::restriction` is not meant to be enabled as a group",
                     None,
-                    "try enabling only the lints you really need",
+                    "enable the restriction lints you need individually",
                 );
             }
         }
@@ -464,6 +486,11 @@ fn check_lint_reason(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem
         return;
     }
 
+    // Check if the attribute is in an external macro and therefore out of the developer's control
+    if in_external_macro(cx.sess(), attr.span) {
+        return;
+    }
+
     span_lint_and_help(
         cx,
         ALLOW_ATTRIBUTES_WITHOUT_REASON,
diff --git a/clippy_lints/src/await_holding_invalid.rs b/clippy_lints/src/await_holding_invalid.rs
index 34717811866..d40a385435a 100644
--- a/clippy_lints/src/await_holding_invalid.rs
+++ b/clippy_lints/src/await_holding_invalid.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::{match_def_path, paths};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::def::{Namespace, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{AsyncGeneratorKind, Body, BodyId, GeneratorKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -189,7 +188,7 @@ impl LateLintPass<'_> for AwaitHolding {
     fn check_crate(&mut self, cx: &LateContext<'_>) {
         for conf in &self.conf_invalid_types {
             let segs: Vec<_> = conf.path().split("::").collect();
-            if let Res::Def(_, id) = clippy_utils::def_path_res(cx, &segs, Some(Namespace::TypeNS)) {
+            for id in clippy_utils::def_path_def_ids(cx, &segs) {
                 self.def_ids.insert(id, conf.clone());
             }
         }
diff --git a/clippy_lints/src/bool_to_int_with_if.rs b/clippy_lints/src/bool_to_int_with_if.rs
index 001d74c2605..bdb3a011602 100644
--- a/clippy_lints/src/bool_to_int_with_if.rs
+++ b/clippy_lints/src/bool_to_int_with_if.rs
@@ -1,9 +1,10 @@
+use clippy_utils::higher::If;
 use rustc_ast::LitKind;
 use rustc_hir::{Block, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 
-use clippy_utils::{diagnostics::span_lint_and_then, is_else_clause, is_integer_literal, sugg::Sugg};
+use clippy_utils::{diagnostics::span_lint_and_then, in_constant, is_else_clause, is_integer_literal, sugg::Sugg};
 use rustc_errors::Applicability;
 
 declare_clippy_lint! {
@@ -12,7 +13,7 @@ declare_clippy_lint! {
     /// this lint suggests using a `from()` function or an `as` coercion.
     ///
     /// ### Why is this bad?
-    /// Coercion or `from()` is idiomatic way to convert bool to a number.
+    /// Coercion or `from()` is another way to convert bool to a number.
     /// Both methods are guaranteed to return 1 for true, and 0 for false.
     ///
     /// See https://doc.rust-lang.org/std/primitive.bool.html#impl-From%3Cbool%3E
@@ -38,23 +39,23 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.65.0"]
     pub BOOL_TO_INT_WITH_IF,
-    style,
+    pedantic,
     "using if to convert bool to int"
 }
 declare_lint_pass!(BoolToIntWithIf => [BOOL_TO_INT_WITH_IF]);
 
 impl<'tcx> LateLintPass<'tcx> for BoolToIntWithIf {
-    fn check_expr(&mut self, ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
-        if !expr.span.from_expansion() {
-            check_if_else(ctx, expr);
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
+        if !expr.span.from_expansion() && !in_constant(cx, expr.hir_id) {
+            check_if_else(cx, expr);
         }
     }
 }
 
-fn check_if_else<'tcx>(ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
-    if let ExprKind::If(check, then, Some(else_)) = expr.kind
+fn check_if_else<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
+    if let Some(If { cond, then, r#else: Some(r#else) }) = If::hir(expr)
         && let Some(then_lit) = int_literal(then)
-        && let Some(else_lit) = int_literal(else_)
+        && let Some(else_lit) = int_literal(r#else)
     {
         let inverted = if is_integer_literal(then_lit, 1) && is_integer_literal(else_lit, 0) {
             false
@@ -66,17 +67,17 @@ fn check_if_else<'tcx>(ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx
         };
         let mut applicability = Applicability::MachineApplicable;
         let snippet = {
-            let mut sugg = Sugg::hir_with_applicability(ctx, check, "..", &mut applicability);
+            let mut sugg = Sugg::hir_with_applicability(cx, cond, "..", &mut applicability);
             if inverted {
                 sugg = !sugg;
             }
             sugg
         };
 
-        let ty = ctx.typeck_results().expr_ty(then_lit); // then and else must be of same type
+        let ty = cx.typeck_results().expr_ty(then_lit); // then and else must be of same type
 
         let suggestion = {
-            let wrap_in_curly = is_else_clause(ctx.tcx, expr);
+            let wrap_in_curly = is_else_clause(cx.tcx, expr);
             let mut s = Sugg::NonParen(format!("{ty}::from({snippet})").into());
             if wrap_in_curly {
                 s = s.blockify();
@@ -87,7 +88,7 @@ fn check_if_else<'tcx>(ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx
         let into_snippet = snippet.clone().maybe_par();
         let as_snippet = snippet.as_ty(ty);
 
-        span_lint_and_then(ctx,
+        span_lint_and_then(cx,
             BOOL_TO_INT_WITH_IF,
             expr.span,
             "boolean to int conversion using if",
diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs
index 08164c0b654..939bdbcdc7c 100644
--- a/clippy_lints/src/booleans.rs
+++ b/clippy_lints/src/booleans.rs
@@ -481,7 +481,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NonminimalBoolVisitor<'a, 'tcx> {
     }
 }
 
-fn implements_ord<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> bool {
+fn implements_ord(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     let ty = cx.typeck_results().expr_ty(expr);
     cx.tcx
         .get_diagnostic_item(sym::Ord)
diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs
index b72c4c772f1..7148b5e6ebf 100644
--- a/clippy_lints/src/casts/mod.rs
+++ b/clippy_lints/src/casts/mod.rs
@@ -593,7 +593,7 @@ declare_clippy_lint! {
     /// let _: *mut [u8] = std::ptr::slice_from_raw_parts_mut(ptr, len);
     /// ```
     /// [safety requirements]: https://doc.rust-lang.org/std/slice/fn.from_raw_parts.html#safety
-    #[clippy::version = "1.64.0"]
+    #[clippy::version = "1.65.0"]
     pub CAST_SLICE_FROM_RAW_PARTS,
     suspicious,
     "casting a slice created from a pointer and length to a slice pointer"
diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs
index 77af3b53d63..1c3a89a9782 100644
--- a/clippy_lints/src/cognitive_complexity.rs
+++ b/clippy_lints/src/cognitive_complexity.rs
@@ -4,11 +4,11 @@ use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::source::snippet_opt;
 use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::visitors::for_each_expr;
-use clippy_utils::LimitStack;
+use clippy_utils::{get_async_fn_body, is_async_fn, LimitStack};
 use core::ops::ControlFlow;
 use rustc_ast::ast::Attribute;
 use rustc_hir::intravisit::FnKind;
-use rustc_hir::{Body, ExprKind, FnDecl, HirId};
+use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::Span;
@@ -56,15 +56,13 @@ impl CognitiveComplexity {
         cx: &LateContext<'tcx>,
         kind: FnKind<'tcx>,
         decl: &'tcx FnDecl<'_>,
-        body: &'tcx Body<'_>,
+        expr: &'tcx Expr<'_>,
         body_span: Span,
     ) {
         if body_span.from_expansion() {
             return;
         }
 
-        let expr = body.value;
-
         let mut cc = 1u64;
         let mut returns = 0u64;
         let _: Option<!> = for_each_expr(expr, |e| {
@@ -146,7 +144,18 @@ impl<'tcx> LateLintPass<'tcx> for CognitiveComplexity {
     ) {
         let def_id = cx.tcx.hir().local_def_id(hir_id);
         if !cx.tcx.has_attr(def_id.to_def_id(), sym::test) {
-            self.check(cx, kind, decl, body, span);
+            let expr = if is_async_fn(kind) {
+                match get_async_fn_body(cx.tcx, body) {
+                    Some(b) => b,
+                    None => {
+                        return;
+                    },
+                }
+            } else {
+                body.value
+            };
+
+            self.check(cx, kind, decl, expr, span);
         }
     }
 
diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs
new file mode 100644
index 00000000000..0d3fc43a644
--- /dev/null
+++ b/clippy_lints/src/declared_lints.rs
@@ -0,0 +1,628 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
+pub(crate) static LINTS: &[&crate::LintInfo] = &[
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::clippy_lints_internal::CLIPPY_LINTS_INTERNAL_INFO,
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::collapsible_calls::COLLAPSIBLE_SPAN_LINT_CALLS_INFO,
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::compiler_lint_functions::COMPILER_LINT_FUNCTIONS_INFO,
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::if_chain_style::IF_CHAIN_STYLE_INFO,
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::interning_defined_symbol::INTERNING_DEFINED_SYMBOL_INFO,
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::interning_defined_symbol::UNNECESSARY_SYMBOL_STR_INFO,
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::invalid_paths::INVALID_PATHS_INFO,
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::lint_without_lint_pass::DEFAULT_DEPRECATION_REASON_INFO,
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::lint_without_lint_pass::DEFAULT_LINT_INFO,
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::lint_without_lint_pass::INVALID_CLIPPY_VERSION_ATTRIBUTE_INFO,
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::lint_without_lint_pass::LINT_WITHOUT_LINT_PASS_INFO,
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::lint_without_lint_pass::MISSING_CLIPPY_VERSION_ATTRIBUTE_INFO,
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::msrv_attr_impl::MISSING_MSRV_ATTR_IMPL_INFO,
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::outer_expn_data_pass::OUTER_EXPN_EXPN_DATA_INFO,
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::produce_ice::PRODUCE_ICE_INFO,
+    #[cfg(feature = "internal")]
+    crate::utils::internal_lints::unnecessary_def_path::UNNECESSARY_DEF_PATH_INFO,
+    crate::almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE_INFO,
+    crate::approx_const::APPROX_CONSTANT_INFO,
+    crate::as_conversions::AS_CONVERSIONS_INFO,
+    crate::asm_syntax::INLINE_ASM_X86_ATT_SYNTAX_INFO,
+    crate::asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX_INFO,
+    crate::assertions_on_constants::ASSERTIONS_ON_CONSTANTS_INFO,
+    crate::assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES_INFO,
+    crate::async_yields_async::ASYNC_YIELDS_ASYNC_INFO,
+    crate::attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON_INFO,
+    crate::attrs::BLANKET_CLIPPY_RESTRICTION_LINTS_INFO,
+    crate::attrs::DEPRECATED_CFG_ATTR_INFO,
+    crate::attrs::DEPRECATED_SEMVER_INFO,
+    crate::attrs::EMPTY_LINE_AFTER_OUTER_ATTR_INFO,
+    crate::attrs::INLINE_ALWAYS_INFO,
+    crate::attrs::MISMATCHED_TARGET_OS_INFO,
+    crate::attrs::USELESS_ATTRIBUTE_INFO,
+    crate::await_holding_invalid::AWAIT_HOLDING_INVALID_TYPE_INFO,
+    crate::await_holding_invalid::AWAIT_HOLDING_LOCK_INFO,
+    crate::await_holding_invalid::AWAIT_HOLDING_REFCELL_REF_INFO,
+    crate::blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS_INFO,
+    crate::bool_assert_comparison::BOOL_ASSERT_COMPARISON_INFO,
+    crate::bool_to_int_with_if::BOOL_TO_INT_WITH_IF_INFO,
+    crate::booleans::NONMINIMAL_BOOL_INFO,
+    crate::booleans::OVERLY_COMPLEX_BOOL_EXPR_INFO,
+    crate::borrow_deref_ref::BORROW_DEREF_REF_INFO,
+    crate::box_default::BOX_DEFAULT_INFO,
+    crate::cargo::CARGO_COMMON_METADATA_INFO,
+    crate::cargo::MULTIPLE_CRATE_VERSIONS_INFO,
+    crate::cargo::NEGATIVE_FEATURE_NAMES_INFO,
+    crate::cargo::REDUNDANT_FEATURE_NAMES_INFO,
+    crate::cargo::WILDCARD_DEPENDENCIES_INFO,
+    crate::casts::AS_PTR_CAST_MUT_INFO,
+    crate::casts::AS_UNDERSCORE_INFO,
+    crate::casts::BORROW_AS_PTR_INFO,
+    crate::casts::CAST_ABS_TO_UNSIGNED_INFO,
+    crate::casts::CAST_ENUM_CONSTRUCTOR_INFO,
+    crate::casts::CAST_ENUM_TRUNCATION_INFO,
+    crate::casts::CAST_LOSSLESS_INFO,
+    crate::casts::CAST_NAN_TO_INT_INFO,
+    crate::casts::CAST_POSSIBLE_TRUNCATION_INFO,
+    crate::casts::CAST_POSSIBLE_WRAP_INFO,
+    crate::casts::CAST_PRECISION_LOSS_INFO,
+    crate::casts::CAST_PTR_ALIGNMENT_INFO,
+    crate::casts::CAST_REF_TO_MUT_INFO,
+    crate::casts::CAST_SIGN_LOSS_INFO,
+    crate::casts::CAST_SLICE_DIFFERENT_SIZES_INFO,
+    crate::casts::CAST_SLICE_FROM_RAW_PARTS_INFO,
+    crate::casts::CHAR_LIT_AS_U8_INFO,
+    crate::casts::FN_TO_NUMERIC_CAST_INFO,
+    crate::casts::FN_TO_NUMERIC_CAST_ANY_INFO,
+    crate::casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION_INFO,
+    crate::casts::PTR_AS_PTR_INFO,
+    crate::casts::UNNECESSARY_CAST_INFO,
+    crate::checked_conversions::CHECKED_CONVERSIONS_INFO,
+    crate::cognitive_complexity::COGNITIVE_COMPLEXITY_INFO,
+    crate::collapsible_if::COLLAPSIBLE_ELSE_IF_INFO,
+    crate::collapsible_if::COLLAPSIBLE_IF_INFO,
+    crate::comparison_chain::COMPARISON_CHAIN_INFO,
+    crate::copies::BRANCHES_SHARING_CODE_INFO,
+    crate::copies::IFS_SAME_COND_INFO,
+    crate::copies::IF_SAME_THEN_ELSE_INFO,
+    crate::copies::SAME_FUNCTIONS_IN_IF_CONDITION_INFO,
+    crate::copy_iterator::COPY_ITERATOR_INFO,
+    crate::crate_in_macro_def::CRATE_IN_MACRO_DEF_INFO,
+    crate::create_dir::CREATE_DIR_INFO,
+    crate::dbg_macro::DBG_MACRO_INFO,
+    crate::default::DEFAULT_TRAIT_ACCESS_INFO,
+    crate::default::FIELD_REASSIGN_WITH_DEFAULT_INFO,
+    crate::default_instead_of_iter_empty::DEFAULT_INSTEAD_OF_ITER_EMPTY_INFO,
+    crate::default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK_INFO,
+    crate::default_union_representation::DEFAULT_UNION_REPRESENTATION_INFO,
+    crate::dereference::EXPLICIT_AUTO_DEREF_INFO,
+    crate::dereference::EXPLICIT_DEREF_METHODS_INFO,
+    crate::dereference::NEEDLESS_BORROW_INFO,
+    crate::dereference::REF_BINDING_TO_REFERENCE_INFO,
+    crate::derivable_impls::DERIVABLE_IMPLS_INFO,
+    crate::derive::DERIVE_HASH_XOR_EQ_INFO,
+    crate::derive::DERIVE_ORD_XOR_PARTIAL_ORD_INFO,
+    crate::derive::DERIVE_PARTIAL_EQ_WITHOUT_EQ_INFO,
+    crate::derive::EXPL_IMPL_CLONE_ON_COPY_INFO,
+    crate::derive::UNSAFE_DERIVE_DESERIALIZE_INFO,
+    crate::disallowed_macros::DISALLOWED_MACROS_INFO,
+    crate::disallowed_methods::DISALLOWED_METHODS_INFO,
+    crate::disallowed_names::DISALLOWED_NAMES_INFO,
+    crate::disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS_INFO,
+    crate::disallowed_types::DISALLOWED_TYPES_INFO,
+    crate::doc::DOC_LINK_WITH_QUOTES_INFO,
+    crate::doc::DOC_MARKDOWN_INFO,
+    crate::doc::MISSING_ERRORS_DOC_INFO,
+    crate::doc::MISSING_PANICS_DOC_INFO,
+    crate::doc::MISSING_SAFETY_DOC_INFO,
+    crate::doc::NEEDLESS_DOCTEST_MAIN_INFO,
+    crate::doc::UNNECESSARY_SAFETY_DOC_INFO,
+    crate::double_parens::DOUBLE_PARENS_INFO,
+    crate::drop_forget_ref::DROP_COPY_INFO,
+    crate::drop_forget_ref::DROP_NON_DROP_INFO,
+    crate::drop_forget_ref::DROP_REF_INFO,
+    crate::drop_forget_ref::FORGET_COPY_INFO,
+    crate::drop_forget_ref::FORGET_NON_DROP_INFO,
+    crate::drop_forget_ref::FORGET_REF_INFO,
+    crate::drop_forget_ref::UNDROPPED_MANUALLY_DROPS_INFO,
+    crate::duplicate_mod::DUPLICATE_MOD_INFO,
+    crate::else_if_without_else::ELSE_IF_WITHOUT_ELSE_INFO,
+    crate::empty_drop::EMPTY_DROP_INFO,
+    crate::empty_enum::EMPTY_ENUM_INFO,
+    crate::empty_structs_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS_INFO,
+    crate::entry::MAP_ENTRY_INFO,
+    crate::enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT_INFO,
+    crate::enum_variants::ENUM_VARIANT_NAMES_INFO,
+    crate::enum_variants::MODULE_INCEPTION_INFO,
+    crate::enum_variants::MODULE_NAME_REPETITIONS_INFO,
+    crate::equatable_if_let::EQUATABLE_IF_LET_INFO,
+    crate::escape::BOXED_LOCAL_INFO,
+    crate::eta_reduction::REDUNDANT_CLOSURE_INFO,
+    crate::eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS_INFO,
+    crate::excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS_INFO,
+    crate::excessive_bools::STRUCT_EXCESSIVE_BOOLS_INFO,
+    crate::exhaustive_items::EXHAUSTIVE_ENUMS_INFO,
+    crate::exhaustive_items::EXHAUSTIVE_STRUCTS_INFO,
+    crate::exit::EXIT_INFO,
+    crate::explicit_write::EXPLICIT_WRITE_INFO,
+    crate::fallible_impl_from::FALLIBLE_IMPL_FROM_INFO,
+    crate::float_literal::EXCESSIVE_PRECISION_INFO,
+    crate::float_literal::LOSSY_FLOAT_LITERAL_INFO,
+    crate::floating_point_arithmetic::IMPRECISE_FLOPS_INFO,
+    crate::floating_point_arithmetic::SUBOPTIMAL_FLOPS_INFO,
+    crate::format::USELESS_FORMAT_INFO,
+    crate::format_args::FORMAT_IN_FORMAT_ARGS_INFO,
+    crate::format_args::TO_STRING_IN_FORMAT_ARGS_INFO,
+    crate::format_args::UNINLINED_FORMAT_ARGS_INFO,
+    crate::format_args::UNUSED_FORMAT_SPECS_INFO,
+    crate::format_impl::PRINT_IN_FORMAT_IMPL_INFO,
+    crate::format_impl::RECURSIVE_FORMAT_IMPL_INFO,
+    crate::format_push_string::FORMAT_PUSH_STRING_INFO,
+    crate::formatting::POSSIBLE_MISSING_COMMA_INFO,
+    crate::formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING_INFO,
+    crate::formatting::SUSPICIOUS_ELSE_FORMATTING_INFO,
+    crate::formatting::SUSPICIOUS_UNARY_OP_FORMATTING_INFO,
+    crate::from_over_into::FROM_OVER_INTO_INFO,
+    crate::from_raw_with_void_ptr::FROM_RAW_WITH_VOID_PTR_INFO,
+    crate::from_str_radix_10::FROM_STR_RADIX_10_INFO,
+    crate::functions::DOUBLE_MUST_USE_INFO,
+    crate::functions::MUST_USE_CANDIDATE_INFO,
+    crate::functions::MUST_USE_UNIT_INFO,
+    crate::functions::NOT_UNSAFE_PTR_ARG_DEREF_INFO,
+    crate::functions::RESULT_LARGE_ERR_INFO,
+    crate::functions::RESULT_UNIT_ERR_INFO,
+    crate::functions::TOO_MANY_ARGUMENTS_INFO,
+    crate::functions::TOO_MANY_LINES_INFO,
+    crate::future_not_send::FUTURE_NOT_SEND_INFO,
+    crate::if_let_mutex::IF_LET_MUTEX_INFO,
+    crate::if_not_else::IF_NOT_ELSE_INFO,
+    crate::if_then_some_else_none::IF_THEN_SOME_ELSE_NONE_INFO,
+    crate::implicit_hasher::IMPLICIT_HASHER_INFO,
+    crate::implicit_return::IMPLICIT_RETURN_INFO,
+    crate::implicit_saturating_add::IMPLICIT_SATURATING_ADD_INFO,
+    crate::implicit_saturating_sub::IMPLICIT_SATURATING_SUB_INFO,
+    crate::inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR_INFO,
+    crate::index_refutable_slice::INDEX_REFUTABLE_SLICE_INFO,
+    crate::indexing_slicing::INDEXING_SLICING_INFO,
+    crate::indexing_slicing::OUT_OF_BOUNDS_INDEXING_INFO,
+    crate::infinite_iter::INFINITE_ITER_INFO,
+    crate::infinite_iter::MAYBE_INFINITE_ITER_INFO,
+    crate::inherent_impl::MULTIPLE_INHERENT_IMPL_INFO,
+    crate::inherent_to_string::INHERENT_TO_STRING_INFO,
+    crate::inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY_INFO,
+    crate::init_numbered_fields::INIT_NUMBERED_FIELDS_INFO,
+    crate::inline_fn_without_body::INLINE_FN_WITHOUT_BODY_INFO,
+    crate::instant_subtraction::MANUAL_INSTANT_ELAPSED_INFO,
+    crate::instant_subtraction::UNCHECKED_DURATION_SUBTRACTION_INFO,
+    crate::int_plus_one::INT_PLUS_ONE_INFO,
+    crate::invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS_INFO,
+    crate::invalid_utf8_in_unchecked::INVALID_UTF8_IN_UNCHECKED_INFO,
+    crate::items_after_statements::ITEMS_AFTER_STATEMENTS_INFO,
+    crate::iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR_INFO,
+    crate::large_const_arrays::LARGE_CONST_ARRAYS_INFO,
+    crate::large_enum_variant::LARGE_ENUM_VARIANT_INFO,
+    crate::large_include_file::LARGE_INCLUDE_FILE_INFO,
+    crate::large_stack_arrays::LARGE_STACK_ARRAYS_INFO,
+    crate::len_zero::COMPARISON_TO_EMPTY_INFO,
+    crate::len_zero::LEN_WITHOUT_IS_EMPTY_INFO,
+    crate::len_zero::LEN_ZERO_INFO,
+    crate::let_if_seq::USELESS_LET_IF_SEQ_INFO,
+    crate::let_underscore::LET_UNDERSCORE_FUTURE_INFO,
+    crate::let_underscore::LET_UNDERSCORE_LOCK_INFO,
+    crate::let_underscore::LET_UNDERSCORE_MUST_USE_INFO,
+    crate::lifetimes::EXTRA_UNUSED_LIFETIMES_INFO,
+    crate::lifetimes::NEEDLESS_LIFETIMES_INFO,
+    crate::literal_representation::DECIMAL_LITERAL_REPRESENTATION_INFO,
+    crate::literal_representation::INCONSISTENT_DIGIT_GROUPING_INFO,
+    crate::literal_representation::LARGE_DIGIT_GROUPS_INFO,
+    crate::literal_representation::MISTYPED_LITERAL_SUFFIXES_INFO,
+    crate::literal_representation::UNREADABLE_LITERAL_INFO,
+    crate::literal_representation::UNUSUAL_BYTE_GROUPINGS_INFO,
+    crate::loops::EMPTY_LOOP_INFO,
+    crate::loops::EXPLICIT_COUNTER_LOOP_INFO,
+    crate::loops::EXPLICIT_INTO_ITER_LOOP_INFO,
+    crate::loops::EXPLICIT_ITER_LOOP_INFO,
+    crate::loops::FOR_KV_MAP_INFO,
+    crate::loops::ITER_NEXT_LOOP_INFO,
+    crate::loops::MANUAL_FIND_INFO,
+    crate::loops::MANUAL_FLATTEN_INFO,
+    crate::loops::MANUAL_MEMCPY_INFO,
+    crate::loops::MISSING_SPIN_LOOP_INFO,
+    crate::loops::MUT_RANGE_BOUND_INFO,
+    crate::loops::NEEDLESS_RANGE_LOOP_INFO,
+    crate::loops::NEVER_LOOP_INFO,
+    crate::loops::SAME_ITEM_PUSH_INFO,
+    crate::loops::SINGLE_ELEMENT_LOOP_INFO,
+    crate::loops::WHILE_IMMUTABLE_CONDITION_INFO,
+    crate::loops::WHILE_LET_LOOP_INFO,
+    crate::loops::WHILE_LET_ON_ITERATOR_INFO,
+    crate::macro_use::MACRO_USE_IMPORTS_INFO,
+    crate::main_recursion::MAIN_RECURSION_INFO,
+    crate::manual_assert::MANUAL_ASSERT_INFO,
+    crate::manual_async_fn::MANUAL_ASYNC_FN_INFO,
+    crate::manual_bits::MANUAL_BITS_INFO,
+    crate::manual_clamp::MANUAL_CLAMP_INFO,
+    crate::manual_is_ascii_check::MANUAL_IS_ASCII_CHECK_INFO,
+    crate::manual_let_else::MANUAL_LET_ELSE_INFO,
+    crate::manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE_INFO,
+    crate::manual_rem_euclid::MANUAL_REM_EUCLID_INFO,
+    crate::manual_retain::MANUAL_RETAIN_INFO,
+    crate::manual_string_new::MANUAL_STRING_NEW_INFO,
+    crate::manual_strip::MANUAL_STRIP_INFO,
+    crate::map_unit_fn::OPTION_MAP_UNIT_FN_INFO,
+    crate::map_unit_fn::RESULT_MAP_UNIT_FN_INFO,
+    crate::match_result_ok::MATCH_RESULT_OK_INFO,
+    crate::matches::COLLAPSIBLE_MATCH_INFO,
+    crate::matches::INFALLIBLE_DESTRUCTURING_MATCH_INFO,
+    crate::matches::MANUAL_FILTER_INFO,
+    crate::matches::MANUAL_MAP_INFO,
+    crate::matches::MANUAL_UNWRAP_OR_INFO,
+    crate::matches::MATCH_AS_REF_INFO,
+    crate::matches::MATCH_BOOL_INFO,
+    crate::matches::MATCH_LIKE_MATCHES_MACRO_INFO,
+    crate::matches::MATCH_ON_VEC_ITEMS_INFO,
+    crate::matches::MATCH_OVERLAPPING_ARM_INFO,
+    crate::matches::MATCH_REF_PATS_INFO,
+    crate::matches::MATCH_SAME_ARMS_INFO,
+    crate::matches::MATCH_SINGLE_BINDING_INFO,
+    crate::matches::MATCH_STR_CASE_MISMATCH_INFO,
+    crate::matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS_INFO,
+    crate::matches::MATCH_WILD_ERR_ARM_INFO,
+    crate::matches::NEEDLESS_MATCH_INFO,
+    crate::matches::REDUNDANT_PATTERN_MATCHING_INFO,
+    crate::matches::REST_PAT_IN_FULLY_BOUND_STRUCTS_INFO,
+    crate::matches::SIGNIFICANT_DROP_IN_SCRUTINEE_INFO,
+    crate::matches::SINGLE_MATCH_INFO,
+    crate::matches::SINGLE_MATCH_ELSE_INFO,
+    crate::matches::TRY_ERR_INFO,
+    crate::matches::WILDCARD_ENUM_MATCH_ARM_INFO,
+    crate::matches::WILDCARD_IN_OR_PATTERNS_INFO,
+    crate::mem_forget::MEM_FORGET_INFO,
+    crate::mem_replace::MEM_REPLACE_OPTION_WITH_NONE_INFO,
+    crate::mem_replace::MEM_REPLACE_WITH_DEFAULT_INFO,
+    crate::mem_replace::MEM_REPLACE_WITH_UNINIT_INFO,
+    crate::methods::BIND_INSTEAD_OF_MAP_INFO,
+    crate::methods::BYTES_COUNT_TO_LEN_INFO,
+    crate::methods::BYTES_NTH_INFO,
+    crate::methods::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS_INFO,
+    crate::methods::CHARS_LAST_CMP_INFO,
+    crate::methods::CHARS_NEXT_CMP_INFO,
+    crate::methods::CLONED_INSTEAD_OF_COPIED_INFO,
+    crate::methods::CLONE_DOUBLE_REF_INFO,
+    crate::methods::CLONE_ON_COPY_INFO,
+    crate::methods::CLONE_ON_REF_PTR_INFO,
+    crate::methods::COLLAPSIBLE_STR_REPLACE_INFO,
+    crate::methods::ERR_EXPECT_INFO,
+    crate::methods::EXPECT_FUN_CALL_INFO,
+    crate::methods::EXPECT_USED_INFO,
+    crate::methods::EXTEND_WITH_DRAIN_INFO,
+    crate::methods::FILETYPE_IS_FILE_INFO,
+    crate::methods::FILTER_MAP_IDENTITY_INFO,
+    crate::methods::FILTER_MAP_NEXT_INFO,
+    crate::methods::FILTER_NEXT_INFO,
+    crate::methods::FLAT_MAP_IDENTITY_INFO,
+    crate::methods::FLAT_MAP_OPTION_INFO,
+    crate::methods::FROM_ITER_INSTEAD_OF_COLLECT_INFO,
+    crate::methods::GET_FIRST_INFO,
+    crate::methods::GET_LAST_WITH_LEN_INFO,
+    crate::methods::GET_UNWRAP_INFO,
+    crate::methods::IMPLICIT_CLONE_INFO,
+    crate::methods::INEFFICIENT_TO_STRING_INFO,
+    crate::methods::INSPECT_FOR_EACH_INFO,
+    crate::methods::INTO_ITER_ON_REF_INFO,
+    crate::methods::IS_DIGIT_ASCII_RADIX_INFO,
+    crate::methods::ITERATOR_STEP_BY_ZERO_INFO,
+    crate::methods::ITER_CLONED_COLLECT_INFO,
+    crate::methods::ITER_COUNT_INFO,
+    crate::methods::ITER_KV_MAP_INFO,
+    crate::methods::ITER_NEXT_SLICE_INFO,
+    crate::methods::ITER_NTH_INFO,
+    crate::methods::ITER_NTH_ZERO_INFO,
+    crate::methods::ITER_ON_EMPTY_COLLECTIONS_INFO,
+    crate::methods::ITER_ON_SINGLE_ITEMS_INFO,
+    crate::methods::ITER_OVEREAGER_CLONED_INFO,
+    crate::methods::ITER_SKIP_NEXT_INFO,
+    crate::methods::ITER_WITH_DRAIN_INFO,
+    crate::methods::MANUAL_FILTER_MAP_INFO,
+    crate::methods::MANUAL_FIND_MAP_INFO,
+    crate::methods::MANUAL_OK_OR_INFO,
+    crate::methods::MANUAL_SATURATING_ARITHMETIC_INFO,
+    crate::methods::MANUAL_SPLIT_ONCE_INFO,
+    crate::methods::MANUAL_STR_REPEAT_INFO,
+    crate::methods::MAP_CLONE_INFO,
+    crate::methods::MAP_COLLECT_RESULT_UNIT_INFO,
+    crate::methods::MAP_ERR_IGNORE_INFO,
+    crate::methods::MAP_FLATTEN_INFO,
+    crate::methods::MAP_IDENTITY_INFO,
+    crate::methods::MAP_UNWRAP_OR_INFO,
+    crate::methods::MUT_MUTEX_LOCK_INFO,
+    crate::methods::NAIVE_BYTECOUNT_INFO,
+    crate::methods::NEEDLESS_COLLECT_INFO,
+    crate::methods::NEEDLESS_OPTION_AS_DEREF_INFO,
+    crate::methods::NEEDLESS_OPTION_TAKE_INFO,
+    crate::methods::NEEDLESS_SPLITN_INFO,
+    crate::methods::NEW_RET_NO_SELF_INFO,
+    crate::methods::NONSENSICAL_OPEN_OPTIONS_INFO,
+    crate::methods::NO_EFFECT_REPLACE_INFO,
+    crate::methods::OBFUSCATED_IF_ELSE_INFO,
+    crate::methods::OK_EXPECT_INFO,
+    crate::methods::OPTION_AS_REF_DEREF_INFO,
+    crate::methods::OPTION_FILTER_MAP_INFO,
+    crate::methods::OPTION_MAP_OR_NONE_INFO,
+    crate::methods::OR_FUN_CALL_INFO,
+    crate::methods::OR_THEN_UNWRAP_INFO,
+    crate::methods::PATH_BUF_PUSH_OVERWRITE_INFO,
+    crate::methods::RANGE_ZIP_WITH_LEN_INFO,
+    crate::methods::REPEAT_ONCE_INFO,
+    crate::methods::RESULT_MAP_OR_INTO_OPTION_INFO,
+    crate::methods::SEARCH_IS_SOME_INFO,
+    crate::methods::SEEK_FROM_CURRENT_INFO,
+    crate::methods::SEEK_TO_START_INSTEAD_OF_REWIND_INFO,
+    crate::methods::SHOULD_IMPLEMENT_TRAIT_INFO,
+    crate::methods::SINGLE_CHAR_ADD_STR_INFO,
+    crate::methods::SINGLE_CHAR_PATTERN_INFO,
+    crate::methods::SKIP_WHILE_NEXT_INFO,
+    crate::methods::STABLE_SORT_PRIMITIVE_INFO,
+    crate::methods::STRING_EXTEND_CHARS_INFO,
+    crate::methods::SUSPICIOUS_MAP_INFO,
+    crate::methods::SUSPICIOUS_SPLITN_INFO,
+    crate::methods::SUSPICIOUS_TO_OWNED_INFO,
+    crate::methods::UNINIT_ASSUMED_INIT_INFO,
+    crate::methods::UNIT_HASH_INFO,
+    crate::methods::UNNECESSARY_FILTER_MAP_INFO,
+    crate::methods::UNNECESSARY_FIND_MAP_INFO,
+    crate::methods::UNNECESSARY_FOLD_INFO,
+    crate::methods::UNNECESSARY_JOIN_INFO,
+    crate::methods::UNNECESSARY_LAZY_EVALUATIONS_INFO,
+    crate::methods::UNNECESSARY_SORT_BY_INFO,
+    crate::methods::UNNECESSARY_TO_OWNED_INFO,
+    crate::methods::UNWRAP_OR_ELSE_DEFAULT_INFO,
+    crate::methods::UNWRAP_USED_INFO,
+    crate::methods::USELESS_ASREF_INFO,
+    crate::methods::VEC_RESIZE_TO_ZERO_INFO,
+    crate::methods::VERBOSE_FILE_READS_INFO,
+    crate::methods::WRONG_SELF_CONVENTION_INFO,
+    crate::methods::ZST_OFFSET_INFO,
+    crate::minmax::MIN_MAX_INFO,
+    crate::misc::SHORT_CIRCUIT_STATEMENT_INFO,
+    crate::misc::TOPLEVEL_REF_ARG_INFO,
+    crate::misc::USED_UNDERSCORE_BINDING_INFO,
+    crate::misc::ZERO_PTR_INFO,
+    crate::misc_early::BUILTIN_TYPE_SHADOW_INFO,
+    crate::misc_early::DOUBLE_NEG_INFO,
+    crate::misc_early::DUPLICATE_UNDERSCORE_ARGUMENT_INFO,
+    crate::misc_early::MIXED_CASE_HEX_LITERALS_INFO,
+    crate::misc_early::REDUNDANT_PATTERN_INFO,
+    crate::misc_early::SEPARATED_LITERAL_SUFFIX_INFO,
+    crate::misc_early::UNNEEDED_FIELD_PATTERN_INFO,
+    crate::misc_early::UNNEEDED_WILDCARD_PATTERN_INFO,
+    crate::misc_early::UNSEPARATED_LITERAL_SUFFIX_INFO,
+    crate::misc_early::ZERO_PREFIXED_LITERAL_INFO,
+    crate::mismatching_type_param_order::MISMATCHING_TYPE_PARAM_ORDER_INFO,
+    crate::missing_const_for_fn::MISSING_CONST_FOR_FN_INFO,
+    crate::missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS_INFO,
+    crate::missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES_INFO,
+    crate::missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS_INFO,
+    crate::missing_trait_methods::MISSING_TRAIT_METHODS_INFO,
+    crate::mixed_read_write_in_expression::DIVERGING_SUB_EXPRESSION_INFO,
+    crate::mixed_read_write_in_expression::MIXED_READ_WRITE_IN_EXPRESSION_INFO,
+    crate::module_style::MOD_MODULE_FILES_INFO,
+    crate::module_style::SELF_NAMED_MODULE_FILES_INFO,
+    crate::multi_assignments::MULTI_ASSIGNMENTS_INFO,
+    crate::mut_key::MUTABLE_KEY_TYPE_INFO,
+    crate::mut_mut::MUT_MUT_INFO,
+    crate::mut_reference::UNNECESSARY_MUT_PASSED_INFO,
+    crate::mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL_INFO,
+    crate::mutex_atomic::MUTEX_ATOMIC_INFO,
+    crate::mutex_atomic::MUTEX_INTEGER_INFO,
+    crate::needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE_INFO,
+    crate::needless_bool::BOOL_COMPARISON_INFO,
+    crate::needless_bool::NEEDLESS_BOOL_INFO,
+    crate::needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE_INFO,
+    crate::needless_continue::NEEDLESS_CONTINUE_INFO,
+    crate::needless_for_each::NEEDLESS_FOR_EACH_INFO,
+    crate::needless_late_init::NEEDLESS_LATE_INIT_INFO,
+    crate::needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS_INFO,
+    crate::needless_pass_by_value::NEEDLESS_PASS_BY_VALUE_INFO,
+    crate::needless_question_mark::NEEDLESS_QUESTION_MARK_INFO,
+    crate::needless_update::NEEDLESS_UPDATE_INFO,
+    crate::neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD_INFO,
+    crate::neg_multiply::NEG_MULTIPLY_INFO,
+    crate::new_without_default::NEW_WITHOUT_DEFAULT_INFO,
+    crate::no_effect::NO_EFFECT_INFO,
+    crate::no_effect::NO_EFFECT_UNDERSCORE_BINDING_INFO,
+    crate::no_effect::UNNECESSARY_OPERATION_INFO,
+    crate::non_copy_const::BORROW_INTERIOR_MUTABLE_CONST_INFO,
+    crate::non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST_INFO,
+    crate::non_expressive_names::JUST_UNDERSCORES_AND_DIGITS_INFO,
+    crate::non_expressive_names::MANY_SINGLE_CHAR_NAMES_INFO,
+    crate::non_expressive_names::SIMILAR_NAMES_INFO,
+    crate::non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS_INFO,
+    crate::non_send_fields_in_send_ty::NON_SEND_FIELDS_IN_SEND_TY_INFO,
+    crate::nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES_INFO,
+    crate::octal_escapes::OCTAL_ESCAPES_INFO,
+    crate::only_used_in_recursion::ONLY_USED_IN_RECURSION_INFO,
+    crate::operators::ABSURD_EXTREME_COMPARISONS_INFO,
+    crate::operators::ARITHMETIC_SIDE_EFFECTS_INFO,
+    crate::operators::ASSIGN_OP_PATTERN_INFO,
+    crate::operators::BAD_BIT_MASK_INFO,
+    crate::operators::CMP_NAN_INFO,
+    crate::operators::CMP_OWNED_INFO,
+    crate::operators::DOUBLE_COMPARISONS_INFO,
+    crate::operators::DURATION_SUBSEC_INFO,
+    crate::operators::EQ_OP_INFO,
+    crate::operators::ERASING_OP_INFO,
+    crate::operators::FLOAT_ARITHMETIC_INFO,
+    crate::operators::FLOAT_CMP_INFO,
+    crate::operators::FLOAT_CMP_CONST_INFO,
+    crate::operators::FLOAT_EQUALITY_WITHOUT_ABS_INFO,
+    crate::operators::IDENTITY_OP_INFO,
+    crate::operators::INEFFECTIVE_BIT_MASK_INFO,
+    crate::operators::INTEGER_ARITHMETIC_INFO,
+    crate::operators::INTEGER_DIVISION_INFO,
+    crate::operators::MISREFACTORED_ASSIGN_OP_INFO,
+    crate::operators::MODULO_ARITHMETIC_INFO,
+    crate::operators::MODULO_ONE_INFO,
+    crate::operators::NEEDLESS_BITWISE_BOOL_INFO,
+    crate::operators::OP_REF_INFO,
+    crate::operators::PTR_EQ_INFO,
+    crate::operators::SELF_ASSIGNMENT_INFO,
+    crate::operators::VERBOSE_BIT_MASK_INFO,
+    crate::option_env_unwrap::OPTION_ENV_UNWRAP_INFO,
+    crate::option_if_let_else::OPTION_IF_LET_ELSE_INFO,
+    crate::overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL_INFO,
+    crate::panic_in_result_fn::PANIC_IN_RESULT_FN_INFO,
+    crate::panic_unimplemented::PANIC_INFO,
+    crate::panic_unimplemented::TODO_INFO,
+    crate::panic_unimplemented::UNIMPLEMENTED_INFO,
+    crate::panic_unimplemented::UNREACHABLE_INFO,
+    crate::partial_pub_fields::PARTIAL_PUB_FIELDS_INFO,
+    crate::partialeq_ne_impl::PARTIALEQ_NE_IMPL_INFO,
+    crate::partialeq_to_none::PARTIALEQ_TO_NONE_INFO,
+    crate::pass_by_ref_or_value::LARGE_TYPES_PASSED_BY_VALUE_INFO,
+    crate::pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF_INFO,
+    crate::pattern_type_mismatch::PATTERN_TYPE_MISMATCH_INFO,
+    crate::precedence::PRECEDENCE_INFO,
+    crate::ptr::CMP_NULL_INFO,
+    crate::ptr::INVALID_NULL_PTR_USAGE_INFO,
+    crate::ptr::MUT_FROM_REF_INFO,
+    crate::ptr::PTR_ARG_INFO,
+    crate::ptr_offset_with_cast::PTR_OFFSET_WITH_CAST_INFO,
+    crate::pub_use::PUB_USE_INFO,
+    crate::question_mark::QUESTION_MARK_INFO,
+    crate::ranges::MANUAL_RANGE_CONTAINS_INFO,
+    crate::ranges::RANGE_MINUS_ONE_INFO,
+    crate::ranges::RANGE_PLUS_ONE_INFO,
+    crate::ranges::REVERSED_EMPTY_RANGES_INFO,
+    crate::rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT_INFO,
+    crate::read_zero_byte_vec::READ_ZERO_BYTE_VEC_INFO,
+    crate::redundant_clone::REDUNDANT_CLONE_INFO,
+    crate::redundant_closure_call::REDUNDANT_CLOSURE_CALL_INFO,
+    crate::redundant_else::REDUNDANT_ELSE_INFO,
+    crate::redundant_field_names::REDUNDANT_FIELD_NAMES_INFO,
+    crate::redundant_pub_crate::REDUNDANT_PUB_CRATE_INFO,
+    crate::redundant_slicing::DEREF_BY_SLICING_INFO,
+    crate::redundant_slicing::REDUNDANT_SLICING_INFO,
+    crate::redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES_INFO,
+    crate::ref_option_ref::REF_OPTION_REF_INFO,
+    crate::reference::DEREF_ADDROF_INFO,
+    crate::regex::INVALID_REGEX_INFO,
+    crate::regex::TRIVIAL_REGEX_INFO,
+    crate::return_self_not_must_use::RETURN_SELF_NOT_MUST_USE_INFO,
+    crate::returns::LET_AND_RETURN_INFO,
+    crate::returns::NEEDLESS_RETURN_INFO,
+    crate::same_name_method::SAME_NAME_METHOD_INFO,
+    crate::self_named_constructors::SELF_NAMED_CONSTRUCTORS_INFO,
+    crate::semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED_INFO,
+    crate::serde_api::SERDE_API_MISUSE_INFO,
+    crate::shadow::SHADOW_REUSE_INFO,
+    crate::shadow::SHADOW_SAME_INFO,
+    crate::shadow::SHADOW_UNRELATED_INFO,
+    crate::single_char_lifetime_names::SINGLE_CHAR_LIFETIME_NAMES_INFO,
+    crate::single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS_INFO,
+    crate::size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT_INFO,
+    crate::slow_vector_initialization::SLOW_VECTOR_INITIALIZATION_INFO,
+    crate::std_instead_of_core::ALLOC_INSTEAD_OF_CORE_INFO,
+    crate::std_instead_of_core::STD_INSTEAD_OF_ALLOC_INFO,
+    crate::std_instead_of_core::STD_INSTEAD_OF_CORE_INFO,
+    crate::strings::STRING_ADD_INFO,
+    crate::strings::STRING_ADD_ASSIGN_INFO,
+    crate::strings::STRING_FROM_UTF8_AS_BYTES_INFO,
+    crate::strings::STRING_LIT_AS_BYTES_INFO,
+    crate::strings::STRING_SLICE_INFO,
+    crate::strings::STRING_TO_STRING_INFO,
+    crate::strings::STR_TO_STRING_INFO,
+    crate::strings::TRIM_SPLIT_WHITESPACE_INFO,
+    crate::strlen_on_c_strings::STRLEN_ON_C_STRINGS_INFO,
+    crate::suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS_INFO,
+    crate::suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL_INFO,
+    crate::suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL_INFO,
+    crate::suspicious_xor_used_as_pow::SUSPICIOUS_XOR_USED_AS_POW_INFO,
+    crate::swap::ALMOST_SWAPPED_INFO,
+    crate::swap::MANUAL_SWAP_INFO,
+    crate::swap_ptr_to_ref::SWAP_PTR_TO_REF_INFO,
+    crate::tabs_in_doc_comments::TABS_IN_DOC_COMMENTS_INFO,
+    crate::temporary_assignment::TEMPORARY_ASSIGNMENT_INFO,
+    crate::to_digit_is_some::TO_DIGIT_IS_SOME_INFO,
+    crate::trailing_empty_array::TRAILING_EMPTY_ARRAY_INFO,
+    crate::trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS_INFO,
+    crate::trait_bounds::TYPE_REPETITION_IN_BOUNDS_INFO,
+    crate::transmute::CROSSPOINTER_TRANSMUTE_INFO,
+    crate::transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS_INFO,
+    crate::transmute::TRANSMUTE_BYTES_TO_STR_INFO,
+    crate::transmute::TRANSMUTE_FLOAT_TO_INT_INFO,
+    crate::transmute::TRANSMUTE_INT_TO_BOOL_INFO,
+    crate::transmute::TRANSMUTE_INT_TO_CHAR_INFO,
+    crate::transmute::TRANSMUTE_INT_TO_FLOAT_INFO,
+    crate::transmute::TRANSMUTE_NUM_TO_BYTES_INFO,
+    crate::transmute::TRANSMUTE_PTR_TO_PTR_INFO,
+    crate::transmute::TRANSMUTE_PTR_TO_REF_INFO,
+    crate::transmute::TRANSMUTE_UNDEFINED_REPR_INFO,
+    crate::transmute::TRANSMUTING_NULL_INFO,
+    crate::transmute::UNSOUND_COLLECTION_TRANSMUTE_INFO,
+    crate::transmute::USELESS_TRANSMUTE_INFO,
+    crate::transmute::WRONG_TRANSMUTE_INFO,
+    crate::types::BORROWED_BOX_INFO,
+    crate::types::BOX_COLLECTION_INFO,
+    crate::types::LINKEDLIST_INFO,
+    crate::types::OPTION_OPTION_INFO,
+    crate::types::RC_BUFFER_INFO,
+    crate::types::RC_MUTEX_INFO,
+    crate::types::REDUNDANT_ALLOCATION_INFO,
+    crate::types::TYPE_COMPLEXITY_INFO,
+    crate::types::VEC_BOX_INFO,
+    crate::undocumented_unsafe_blocks::UNDOCUMENTED_UNSAFE_BLOCKS_INFO,
+    crate::unicode::INVISIBLE_CHARACTERS_INFO,
+    crate::unicode::NON_ASCII_LITERAL_INFO,
+    crate::unicode::UNICODE_NOT_NFC_INFO,
+    crate::uninit_vec::UNINIT_VEC_INFO,
+    crate::unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD_INFO,
+    crate::unit_types::LET_UNIT_VALUE_INFO,
+    crate::unit_types::UNIT_ARG_INFO,
+    crate::unit_types::UNIT_CMP_INFO,
+    crate::unnamed_address::FN_ADDRESS_COMPARISONS_INFO,
+    crate::unnamed_address::VTABLE_ADDRESS_COMPARISONS_INFO,
+    crate::unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS_INFO,
+    crate::unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS_INFO,
+    crate::unnecessary_wraps::UNNECESSARY_WRAPS_INFO,
+    crate::unnested_or_patterns::UNNESTED_OR_PATTERNS_INFO,
+    crate::unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME_INFO,
+    crate::unused_async::UNUSED_ASYNC_INFO,
+    crate::unused_io_amount::UNUSED_IO_AMOUNT_INFO,
+    crate::unused_peekable::UNUSED_PEEKABLE_INFO,
+    crate::unused_rounding::UNUSED_ROUNDING_INFO,
+    crate::unused_self::UNUSED_SELF_INFO,
+    crate::unused_unit::UNUSED_UNIT_INFO,
+    crate::unwrap::PANICKING_UNWRAP_INFO,
+    crate::unwrap::UNNECESSARY_UNWRAP_INFO,
+    crate::unwrap_in_result::UNWRAP_IN_RESULT_INFO,
+    crate::upper_case_acronyms::UPPER_CASE_ACRONYMS_INFO,
+    crate::use_self::USE_SELF_INFO,
+    crate::useless_conversion::USELESS_CONVERSION_INFO,
+    crate::vec::USELESS_VEC_INFO,
+    crate::vec_init_then_push::VEC_INIT_THEN_PUSH_INFO,
+    crate::wildcard_imports::ENUM_GLOB_USE_INFO,
+    crate::wildcard_imports::WILDCARD_IMPORTS_INFO,
+    crate::write::PRINTLN_EMPTY_STRING_INFO,
+    crate::write::PRINT_LITERAL_INFO,
+    crate::write::PRINT_STDERR_INFO,
+    crate::write::PRINT_STDOUT_INFO,
+    crate::write::PRINT_WITH_NEWLINE_INFO,
+    crate::write::USE_DEBUG_INFO,
+    crate::write::WRITELN_EMPTY_STRING_INFO,
+    crate::write::WRITE_LITERAL_INFO,
+    crate::write::WRITE_WITH_NEWLINE_INFO,
+    crate::zero_div_zero::ZERO_DIVIDED_BY_ZERO_INFO,
+    crate::zero_sized_map_values::ZERO_SIZED_MAP_VALUES_INFO,
+];
diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs
index c4e7f8bfe1e..18e742a85b3 100644
--- a/clippy_lints/src/dereference.rs
+++ b/clippy_lints/src/dereference.rs
@@ -9,6 +9,7 @@ use clippy_utils::{
 };
 use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX};
 use rustc_data_structures::fx::FxIndexMap;
+use rustc_data_structures::graph::iterate::{CycleDetector, TriColorDepthFirstSearch};
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_ty, Visitor};
 use rustc_hir::{
@@ -274,9 +275,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
         }
 
         let typeck = cx.typeck_results();
-        let (kind, sub_expr) = if let Some(x) = try_parse_ref_op(cx.tcx, typeck, expr) {
-            x
-        } else {
+        let Some((kind, sub_expr)) = try_parse_ref_op(cx.tcx, typeck, expr) else {
             // The whole chain of reference operations has been seen
             if let Some((state, data)) = self.state.take() {
                 report(cx, expr, state, data);
@@ -806,30 +805,39 @@ fn walk_parents<'tcx>(
                     .position(|arg| arg.hir_id == child_id)
                     .zip(expr_sig(cx, func))
                     .and_then(|(i, sig)| {
-                        sig.input_with_hir(i).map(|(hir_ty, ty)| match hir_ty {
-                            // Type inference for closures can depend on how they're called. Only go by the explicit
-                            // types here.
-                            Some(hir_ty) => binding_ty_auto_deref_stability(cx, hir_ty, precedence, ty.bound_vars()),
-                            None => {
-                                if let ty::Param(param_ty) = ty.skip_binder().kind() {
-                                    needless_borrow_impl_arg_position(
-                                        cx,
-                                        possible_borrowers,
-                                        parent,
-                                        i,
-                                        *param_ty,
-                                        e,
-                                        precedence,
-                                        msrv,
-                                    )
-                                } else {
-                                    ty_auto_deref_stability(cx, cx.tcx.erase_late_bound_regions(ty), precedence)
-                                        .position_for_arg()
-                                }
-                            },
+                        sig.input_with_hir(i).map(|(hir_ty, ty)| {
+                            match hir_ty {
+                                // Type inference for closures can depend on how they're called. Only go by the explicit
+                                // types here.
+                                Some(hir_ty) => {
+                                    binding_ty_auto_deref_stability(cx, hir_ty, precedence, ty.bound_vars())
+                                },
+                                None => {
+                                    // `e.hir_id == child_id` for https://github.com/rust-lang/rust-clippy/issues/9739
+                                    // `!call_is_qualified(func)` for https://github.com/rust-lang/rust-clippy/issues/9782
+                                    if e.hir_id == child_id
+                                        && !call_is_qualified(func)
+                                        && let ty::Param(param_ty) = ty.skip_binder().kind()
+                                    {
+                                        needless_borrow_impl_arg_position(
+                                            cx,
+                                            possible_borrowers,
+                                            parent,
+                                            i,
+                                            *param_ty,
+                                            e,
+                                            precedence,
+                                            msrv,
+                                        )
+                                    } else {
+                                        ty_auto_deref_stability(cx, cx.tcx.erase_late_bound_regions(ty), precedence)
+                                            .position_for_arg()
+                                    }
+                                },
+                            }
                         })
                     }),
-                ExprKind::MethodCall(_, receiver, args, _) => {
+                ExprKind::MethodCall(method, receiver, args, _) => {
                     let id = cx.typeck_results().type_dependent_def_id(parent.hir_id).unwrap();
                     if receiver.hir_id == child_id {
                         // Check for calls to trait methods where the trait is implemented on a reference.
@@ -863,7 +871,9 @@ fn walk_parents<'tcx>(
                     }
                     args.iter().position(|arg| arg.hir_id == child_id).map(|i| {
                         let ty = cx.tcx.fn_sig(id).skip_binder().inputs()[i + 1];
-                        if let ty::Param(param_ty) = ty.kind() {
+                        // `e.hir_id == child_id` for https://github.com/rust-lang/rust-clippy/issues/9739
+                        // `method.args.is_none()` for https://github.com/rust-lang/rust-clippy/issues/9782
+                        if e.hir_id == child_id && method.args.is_none() && let ty::Param(param_ty) = ty.kind() {
                             needless_borrow_impl_arg_position(
                                 cx,
                                 possible_borrowers,
@@ -1041,13 +1051,25 @@ fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool {
     v.0
 }
 
+fn call_is_qualified(expr: &Expr<'_>) -> bool {
+    if let ExprKind::Path(path) = &expr.kind {
+        match path {
+            QPath::Resolved(_, path) => path.segments.last().map_or(false, |segment| segment.args.is_some()),
+            QPath::TypeRelative(_, segment) => segment.args.is_some(),
+            QPath::LangItem(..) => false,
+        }
+    } else {
+        false
+    }
+}
+
 // Checks whether:
 // * child is an expression of the form `&e` in an argument position requiring an `impl Trait`
 // * `e`'s type implements `Trait` and is copyable
 // If the conditions are met, returns `Some(Position::ImplArg(..))`; otherwise, returns `None`.
 //   The "is copyable" condition is to avoid the case where removing the `&` means `e` would have to
 // be moved, but it cannot be.
-#[expect(clippy::too_many_arguments)]
+#[expect(clippy::too_many_arguments, clippy::too_many_lines)]
 fn needless_borrow_impl_arg_position<'tcx>(
     cx: &LateContext<'tcx>,
     possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
@@ -1109,6 +1131,16 @@ fn needless_borrow_impl_arg_position<'tcx>(
         return Position::Other(precedence);
     }
 
+    // See:
+    // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1289294201
+    // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1292225232
+    if projection_predicates
+        .iter()
+        .any(|projection_predicate| is_mixed_projection_predicate(cx, callee_def_id, projection_predicate))
+    {
+        return Position::Other(precedence);
+    }
+
     // `substs_with_referent_ty` can be constructed outside of `check_referent` because the same
     // elements are modified each time `check_referent` is called.
     let mut substs_with_referent_ty = substs_with_expr_ty.to_vec();
@@ -1188,6 +1220,37 @@ fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {
         })
 }
 
+fn is_mixed_projection_predicate<'tcx>(
+    cx: &LateContext<'tcx>,
+    callee_def_id: DefId,
+    projection_predicate: &ProjectionPredicate<'tcx>,
+) -> bool {
+    let generics = cx.tcx.generics_of(callee_def_id);
+    // The predicate requires the projected type to equal a type parameter from the parent context.
+    if let Some(term_ty) = projection_predicate.term.ty()
+        && let ty::Param(term_param_ty) = term_ty.kind()
+        && (term_param_ty.index as usize) < generics.parent_count
+    {
+        // The inner-most self type is a type parameter from the current function.
+        let mut projection_ty = projection_predicate.projection_ty;
+        loop {
+            match projection_ty.self_ty().kind() {
+                ty::Projection(inner_projection_ty) => {
+                    projection_ty = *inner_projection_ty;
+                }
+                ty::Param(param_ty) => {
+                    return (param_ty.index as usize) >= generics.parent_count;
+                }
+                _ => {
+                    return false;
+                }
+            }
+        }
+    } else {
+        false
+    }
+}
+
 fn referent_used_exactly_once<'tcx>(
     cx: &LateContext<'tcx>,
     possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
@@ -1199,6 +1262,8 @@ fn referent_used_exactly_once<'tcx>(
         && let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index)
         && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind
         && !place.has_deref()
+        // Ensure not in a loop (https://github.com/rust-lang/rust-clippy/issues/9710)
+        && TriColorDepthFirstSearch::new(&mir.basic_blocks).run_from(location.block, &mut CycleDetector).is_none()
     {
         let body_owner_local_def_id = cx.tcx.hir().enclosing_body_owner(reference.hir_id);
         if possible_borrowers
@@ -1316,6 +1381,7 @@ fn ty_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, precedenc
                 continue;
             },
             ty::Param(_) => TyPosition::new_deref_stable_for_result(precedence, ty),
+            ty::Projection(_) if ty.has_non_region_param() => TyPosition::new_deref_stable_for_result(precedence, ty),
             ty::Infer(_) | ty::Error(_) | ty::Bound(..) | ty::Opaque(..) | ty::Placeholder(_) | ty::Dynamic(..) => {
                 Position::ReborrowStable(precedence).into()
             },
@@ -1342,11 +1408,9 @@ fn ty_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, precedenc
             | ty::Closure(..)
             | ty::Never
             | ty::Tuple(_)
-            | ty::Projection(_) => Position::DerefStable(
-                precedence,
-                ty.is_sized(cx.tcx, cx.param_env.without_caller_bounds()),
-            )
-            .into(),
+            | ty::Projection(_) => {
+                Position::DerefStable(precedence, ty.is_sized(cx.tcx, cx.param_env.without_caller_bounds())).into()
+            },
         };
     }
 }
diff --git a/clippy_lints/src/disallowed_macros.rs b/clippy_lints/src/disallowed_macros.rs
index 5ab7144e290..68122b4cef5 100644
--- a/clippy_lints/src/disallowed_macros.rs
+++ b/clippy_lints/src/disallowed_macros.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::macro_backtrace;
 use rustc_data_structures::fx::FxHashSet;
-use rustc_hir::def::{Namespace, Res};
 use rustc_hir::def_id::DefIdMap;
 use rustc_hir::{Expr, ForeignItem, HirId, ImplItem, Item, Pat, Path, Stmt, TraitItem, Ty};
 use rustc_lint::{LateContext, LateLintPass};
@@ -89,7 +88,7 @@ impl DisallowedMacros {
                     &format!("use of a disallowed macro `{}`", conf.path()),
                     |diag| {
                         if let Some(reason) = conf.reason() {
-                            diag.note(&format!("{reason} (from clippy.toml)"));
+                            diag.note(reason);
                         }
                     },
                 );
@@ -104,7 +103,7 @@ impl LateLintPass<'_> for DisallowedMacros {
     fn check_crate(&mut self, cx: &LateContext<'_>) {
         for (index, conf) in self.conf_disallowed.iter().enumerate() {
             let segs: Vec<_> = conf.path().split("::").collect();
-            if let Res::Def(_, id) = clippy_utils::def_path_res(cx, &segs, Some(Namespace::MacroNS)) {
+            for id in clippy_utils::def_path_def_ids(cx, &segs) {
                 self.disallowed.insert(id, index);
             }
         }
diff --git a/clippy_lints/src/disallowed_methods.rs b/clippy_lints/src/disallowed_methods.rs
index 6ac85606d9c..ca8671c8f1a 100644
--- a/clippy_lints/src/disallowed_methods.rs
+++ b/clippy_lints/src/disallowed_methods.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::{fn_def_id, get_parent_expr, path_def_id};
 
-use rustc_hir::def::{Namespace, Res};
 use rustc_hir::def_id::DefIdMap;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -79,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedMethods {
     fn check_crate(&mut self, cx: &LateContext<'_>) {
         for (index, conf) in self.conf_disallowed.iter().enumerate() {
             let segs: Vec<_> = conf.path().split("::").collect();
-            if let Res::Def(_, id) = clippy_utils::def_path_res(cx, &segs, Some(Namespace::ValueNS)) {
+            for id in clippy_utils::def_path_def_ids(cx, &segs) {
                 self.disallowed.insert(id, index);
             }
         }
@@ -104,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedMethods {
         let msg = format!("use of a disallowed method `{}`", conf.path());
         span_lint_and_then(cx, DISALLOWED_METHODS, expr.span, &msg, |diag| {
             if let Some(reason) = conf.reason() {
-                diag.note(&format!("{reason} (from clippy.toml)"));
+                diag.note(reason);
             }
         });
     }
diff --git a/clippy_lints/src/disallowed_types.rs b/clippy_lints/src/disallowed_types.rs
index c7131fc164d..aee3d8c4f08 100644
--- a/clippy_lints/src/disallowed_types.rs
+++ b/clippy_lints/src/disallowed_types.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::def::{Namespace, Res};
+use rustc_hir::def::Res;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{Item, ItemKind, PolyTraitRef, PrimTy, Ty, TyKind, UseKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -53,8 +53,8 @@ declare_clippy_lint! {
 #[derive(Clone, Debug)]
 pub struct DisallowedTypes {
     conf_disallowed: Vec<conf::DisallowedPath>,
-    def_ids: FxHashMap<DefId, Option<String>>,
-    prim_tys: FxHashMap<PrimTy, Option<String>>,
+    def_ids: FxHashMap<DefId, usize>,
+    prim_tys: FxHashMap<PrimTy, usize>,
 }
 
 impl DisallowedTypes {
@@ -69,13 +69,13 @@ impl DisallowedTypes {
     fn check_res_emit(&self, cx: &LateContext<'_>, res: &Res, span: Span) {
         match res {
             Res::Def(_, did) => {
-                if let Some(reason) = self.def_ids.get(did) {
-                    emit(cx, &cx.tcx.def_path_str(*did), span, reason.as_deref());
+                if let Some(&index) = self.def_ids.get(did) {
+                    emit(cx, &cx.tcx.def_path_str(*did), span, &self.conf_disallowed[index]);
                 }
             },
             Res::PrimTy(prim) => {
-                if let Some(reason) = self.prim_tys.get(prim) {
-                    emit(cx, prim.name_str(), span, reason.as_deref());
+                if let Some(&index) = self.prim_tys.get(prim) {
+                    emit(cx, prim.name_str(), span, &self.conf_disallowed[index]);
                 }
             },
             _ => {},
@@ -87,17 +87,19 @@ impl_lint_pass!(DisallowedTypes => [DISALLOWED_TYPES]);
 
 impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {
     fn check_crate(&mut self, cx: &LateContext<'_>) {
-        for conf in &self.conf_disallowed {
+        for (index, conf) in self.conf_disallowed.iter().enumerate() {
             let segs: Vec<_> = conf.path().split("::").collect();
-            let reason = conf.reason().map(|reason| format!("{reason} (from clippy.toml)"));
-            match clippy_utils::def_path_res(cx, &segs, Some(Namespace::TypeNS)) {
-                Res::Def(_, id) => {
-                    self.def_ids.insert(id, reason);
-                },
-                Res::PrimTy(ty) => {
-                    self.prim_tys.insert(ty, reason);
-                },
-                _ => {},
+
+            for res in clippy_utils::def_path_res(cx, &segs) {
+                match res {
+                    Res::Def(_, id) => {
+                        self.def_ids.insert(id, index);
+                    },
+                    Res::PrimTy(ty) => {
+                        self.prim_tys.insert(ty, index);
+                    },
+                    _ => {},
+                }
             }
         }
     }
@@ -119,14 +121,14 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedTypes {
     }
 }
 
-fn emit(cx: &LateContext<'_>, name: &str, span: Span, reason: Option<&str>) {
+fn emit(cx: &LateContext<'_>, name: &str, span: Span, conf: &conf::DisallowedPath) {
     span_lint_and_then(
         cx,
         DISALLOWED_TYPES,
         span,
         &format!("`{name}` is not allowed according to config"),
         |diag| {
-            if let Some(reason) = reason {
+            if let Some(reason) = conf.reason() {
                 diag.note(reason);
             }
         },
diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs
index daaab79fef9..4557e432885 100644
--- a/clippy_lints/src/doc.rs
+++ b/clippy_lints/src/doc.rs
@@ -11,7 +11,7 @@ use rustc_ast::token::CommentKind;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::emitter::EmitterWriter;
-use rustc_errors::{Applicability, Handler, MultiSpan, SuggestionStyle};
+use rustc_errors::{Applicability, Handler, SuggestionStyle};
 use rustc_hir as hir;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{AnonConst, Expr};
@@ -221,6 +221,42 @@ declare_clippy_lint! {
     "possible typo for an intra-doc link"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for the doc comments of publicly visible
+    /// safe functions and traits and warns if there is a `# Safety` section.
+    ///
+    /// ### Why is this bad?
+    /// Safe functions and traits are safe to implement and therefore do not
+    /// need to describe safety preconditions that users are required to uphold.
+    ///
+    /// ### Examples
+    /// ```rust
+    ///# type Universe = ();
+    /// /// # Safety
+    /// ///
+    /// /// This function should not be called before the horsemen are ready.
+    /// pub fn start_apocalypse_but_safely(u: &mut Universe) {
+    ///     unimplemented!();
+    /// }
+    /// ```
+    ///
+    /// The function is safe, so there shouldn't be any preconditions
+    /// that have to be explained for safety reasons.
+    ///
+    /// ```rust
+    ///# type Universe = ();
+    /// /// This function should really be documented
+    /// pub fn start_apocalypse(u: &mut Universe) {
+    ///     unimplemented!();
+    /// }
+    /// ```
+    #[clippy::version = "1.66.0"]
+    pub UNNECESSARY_SAFETY_DOC,
+    style,
+    "`pub fn` or `pub trait` with `# Safety` docs"
+}
+
 #[expect(clippy::module_name_repetitions)]
 #[derive(Clone)]
 pub struct DocMarkdown {
@@ -243,7 +279,8 @@ impl_lint_pass!(DocMarkdown => [
     MISSING_SAFETY_DOC,
     MISSING_ERRORS_DOC,
     MISSING_PANICS_DOC,
-    NEEDLESS_DOCTEST_MAIN
+    NEEDLESS_DOCTEST_MAIN,
+    UNNECESSARY_SAFETY_DOC,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
@@ -254,7 +291,7 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
 
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
         let attrs = cx.tcx.hir().attrs(item.hir_id());
-        let headers = check_attrs(cx, &self.valid_idents, attrs);
+        let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
         match item.kind {
             hir::ItemKind::Fn(ref sig, _, body_id) => {
                 if !(is_entrypoint_fn(cx, item.owner_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)) {
@@ -265,29 +302,26 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
                         panic_span: None,
                     };
                     fpu.visit_expr(body.value);
-                    lint_for_missing_headers(
-                        cx,
-                        item.owner_id.def_id,
-                        item.span,
-                        sig,
-                        headers,
-                        Some(body_id),
-                        fpu.panic_span,
-                    );
+                    lint_for_missing_headers(cx, item.owner_id.def_id, sig, headers, Some(body_id), fpu.panic_span);
                 }
             },
             hir::ItemKind::Impl(impl_) => {
                 self.in_trait_impl = impl_.of_trait.is_some();
             },
-            hir::ItemKind::Trait(_, unsafety, ..) => {
-                if !headers.safety && unsafety == hir::Unsafety::Unsafe {
-                    span_lint(
-                        cx,
-                        MISSING_SAFETY_DOC,
-                        item.span,
-                        "docs for unsafe trait missing `# Safety` section",
-                    );
-                }
+            hir::ItemKind::Trait(_, unsafety, ..) => match (headers.safety, unsafety) {
+                (false, hir::Unsafety::Unsafe) => span_lint(
+                    cx,
+                    MISSING_SAFETY_DOC,
+                    cx.tcx.def_span(item.owner_id),
+                    "docs for unsafe trait missing `# Safety` section",
+                ),
+                (true, hir::Unsafety::Normal) => span_lint(
+                    cx,
+                    UNNECESSARY_SAFETY_DOC,
+                    cx.tcx.def_span(item.owner_id),
+                    "docs for safe trait have unnecessary `# Safety` section",
+                ),
+                _ => (),
             },
             _ => (),
         }
@@ -301,17 +335,17 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
 
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'_>) {
         let attrs = cx.tcx.hir().attrs(item.hir_id());
-        let headers = check_attrs(cx, &self.valid_idents, attrs);
+        let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
         if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
             if !in_external_macro(cx.tcx.sess, item.span) {
-                lint_for_missing_headers(cx, item.owner_id.def_id, item.span, sig, headers, None, None);
+                lint_for_missing_headers(cx, item.owner_id.def_id, sig, headers, None, None);
             }
         }
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'_>) {
         let attrs = cx.tcx.hir().attrs(item.hir_id());
-        let headers = check_attrs(cx, &self.valid_idents, attrs);
+        let Some(headers) = check_attrs(cx, &self.valid_idents, attrs) else { return };
         if self.in_trait_impl || in_external_macro(cx.tcx.sess, item.span) {
             return;
         }
@@ -323,23 +357,14 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
                 panic_span: None,
             };
             fpu.visit_expr(body.value);
-            lint_for_missing_headers(
-                cx,
-                item.owner_id.def_id,
-                item.span,
-                sig,
-                headers,
-                Some(body_id),
-                fpu.panic_span,
-            );
+            lint_for_missing_headers(cx, item.owner_id.def_id, sig, headers, Some(body_id), fpu.panic_span);
         }
     }
 }
 
-fn lint_for_missing_headers<'tcx>(
-    cx: &LateContext<'tcx>,
+fn lint_for_missing_headers(
+    cx: &LateContext<'_>,
     def_id: LocalDefId,
-    span: impl Into<MultiSpan> + Copy,
     sig: &hir::FnSig<'_>,
     headers: DocHeaders,
     body_id: Option<hir::BodyId>,
@@ -359,13 +384,21 @@ fn lint_for_missing_headers<'tcx>(
         return;
     }
 
-    if !headers.safety && sig.header.unsafety == hir::Unsafety::Unsafe {
-        span_lint(
+    let span = cx.tcx.def_span(def_id);
+    match (headers.safety, sig.header.unsafety) {
+        (false, hir::Unsafety::Unsafe) => span_lint(
             cx,
             MISSING_SAFETY_DOC,
             span,
             "unsafe function's docs miss `# Safety` section",
-        );
+        ),
+        (true, hir::Unsafety::Normal) => span_lint(
+            cx,
+            UNNECESSARY_SAFETY_DOC,
+            span,
+            "safe function's docs have unnecessary `# Safety` section",
+        ),
+        _ => (),
     }
     if !headers.panics && panic_span.is_some() {
         span_lint_and_note(
@@ -467,7 +500,7 @@ struct DocHeaders {
     panics: bool,
 }
 
-fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &'a [Attribute]) -> DocHeaders {
+fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[Attribute]) -> Option<DocHeaders> {
     use pulldown_cmark::{BrokenLink, CowStr, Options};
     /// We don't want the parser to choke on intra doc links. Since we don't
     /// actually care about rendering them, just pretend that all broken links are
@@ -488,11 +521,7 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
         } else if attr.has_name(sym::doc) {
             // ignore mix of sugared and non-sugared doc
             // don't trigger the safety or errors check
-            return DocHeaders {
-                safety: true,
-                errors: true,
-                panics: true,
-            };
+            return None;
         }
     }
 
@@ -504,7 +533,7 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
     }
 
     if doc.is_empty() {
-        return DocHeaders::default();
+        return Some(DocHeaders::default());
     }
 
     let mut cb = fake_broken_link_callback;
@@ -527,7 +556,7 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
             (previous, current) => Err(((previous, previous_range), (current, current_range))),
         }
     });
-    check_doc(cx, valid_idents, events, &spans)
+    Some(check_doc(cx, valid_idents, events, &spans))
 }
 
 const RUST_CODE: &[&str] = &["rust", "no_run", "should_panic", "compile_fail"];
diff --git a/clippy_lints/src/enum_variants.rs b/clippy_lints/src/enum_variants.rs
index 223545fa798..b77b5621b4c 100644
--- a/clippy_lints/src/enum_variants.rs
+++ b/clippy_lints/src/enum_variants.rs
@@ -250,7 +250,7 @@ impl LateLintPass<'_> for EnumVariantNames {
         let item_name = item.ident.name.as_str();
         let item_camel = to_camel_case(item_name);
         if !item.span.from_expansion() && is_present_in_source(cx, item.span) {
-            if let Some(&(ref mod_name, ref mod_camel)) = self.modules.last() {
+            if let Some((mod_name, mod_camel)) = self.modules.last() {
                 // constants don't have surrounding modules
                 if !mod_camel.is_empty() {
                     if mod_name == &item.ident.name {
diff --git a/clippy_lints/src/equatable_if_let.rs b/clippy_lints/src/equatable_if_let.rs
index b40cb7cddaf..c691e6c5402 100644
--- a/clippy_lints/src/equatable_if_let.rs
+++ b/clippy_lints/src/equatable_if_let.rs
@@ -1,7 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::ty::implements_trait;
-use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, Pat, PatKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -67,16 +66,14 @@ fn is_structural_partial_eq<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, other: T
 
 impl<'tcx> LateLintPass<'tcx> for PatternEquality {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
-        if_chain! {
-            if !in_external_macro(cx.sess(), expr.span);
-            if let ExprKind::Let(let_expr) = expr.kind;
-            if unary_pattern(let_expr.pat);
+        if !in_external_macro(cx.sess(), expr.span)
+            && let ExprKind::Let(let_expr) = expr.kind
+            && unary_pattern(let_expr.pat) {
             let exp_ty = cx.typeck_results().expr_ty(let_expr.init);
             let pat_ty = cx.typeck_results().pat_ty(let_expr.pat);
-            if is_structural_partial_eq(cx, exp_ty, pat_ty);
-            then {
+            let mut applicability = Applicability::MachineApplicable;
 
-                let mut applicability = Applicability::MachineApplicable;
+            if is_structural_partial_eq(cx, exp_ty, pat_ty) {
                 let pat_str = match let_expr.pat.kind {
                     PatKind::Struct(..) => format!(
                         "({})",
@@ -96,6 +93,20 @@ impl<'tcx> LateLintPass<'tcx> for PatternEquality {
                     ),
                     applicability,
                 );
+            } else {
+                span_lint_and_sugg(
+                    cx,
+                    EQUATABLE_IF_LET,
+                    expr.span,
+                    "this pattern matching can be expressed using `matches!`",
+                    "try",
+                    format!(
+                        "matches!({}, {})",
+                        snippet_with_context(cx, let_expr.init.span, expr.span.ctxt(), "..", &mut applicability).0,
+                        snippet_with_context(cx, let_expr.pat.span, expr.span.ctxt(), "..", &mut applicability).0,
+                    ),
+                    applicability,
+                );
             }
         }
     }
diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs
index 7f1a4c4beb1..1d09adec12f 100644
--- a/clippy_lints/src/escape.rs
+++ b/clippy_lints/src/escape.rs
@@ -176,13 +176,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
         }
     }
 
-    fn fake_read(
-        &mut self,
-        _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>,
-        _: FakeReadCause,
-        _: HirId,
-    ) {
-    }
+    fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
 }
 
 impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
diff --git a/clippy_lints/src/excessive_bools.rs b/clippy_lints/src/excessive_bools.rs
index 453471c8cdd..fc2912f696e 100644
--- a/clippy_lints/src/excessive_bools.rs
+++ b/clippy_lints/src/excessive_bools.rs
@@ -1,8 +1,11 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use rustc_ast::ast::{AssocItemKind, Extern, Fn, FnSig, Impl, Item, ItemKind, Trait, Ty, TyKind};
-use rustc_lint::{EarlyContext, EarlyLintPass};
+use clippy_utils::{get_parent_as_impl, has_repr_attr, is_bool};
+use rustc_hir::intravisit::FnKind;
+use rustc_hir::{Body, FnDecl, HirId, Item, ItemKind, TraitFn, TraitItem, TraitItemKind, Ty};
+use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::{sym, Span};
+use rustc_span::Span;
+use rustc_target::spec::abi::Abi;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -83,6 +86,12 @@ pub struct ExcessiveBools {
     max_fn_params_bools: u64,
 }
 
+#[derive(Eq, PartialEq, Debug, Copy, Clone)]
+enum Kind {
+    Struct,
+    Fn,
+}
+
 impl ExcessiveBools {
     #[must_use]
     pub fn new(max_struct_bools: u64, max_fn_params_bools: u64) -> Self {
@@ -92,21 +101,20 @@ impl ExcessiveBools {
         }
     }
 
-    fn check_fn_sig(&self, cx: &EarlyContext<'_>, fn_sig: &FnSig, span: Span) {
-        match fn_sig.header.ext {
-            Extern::Implicit(_) | Extern::Explicit(_, _) => return,
-            Extern::None => (),
+    fn too_many_bools<'tcx>(&self, tys: impl Iterator<Item = &'tcx Ty<'tcx>>, kind: Kind) -> bool {
+        if let Ok(bools) = tys.filter(|ty| is_bool(ty)).count().try_into() {
+            (if Kind::Fn == kind {
+                self.max_fn_params_bools
+            } else {
+                self.max_struct_bools
+            }) < bools
+        } else {
+            false
         }
+    }
 
-        let fn_sig_bools = fn_sig
-            .decl
-            .inputs
-            .iter()
-            .filter(|param| is_bool_ty(&param.ty))
-            .count()
-            .try_into()
-            .unwrap();
-        if self.max_fn_params_bools < fn_sig_bools {
+    fn check_fn_sig(&self, cx: &LateContext<'_>, fn_decl: &FnDecl<'_>, span: Span) {
+        if !span.from_expansion() && self.too_many_bools(fn_decl.inputs.iter(), Kind::Fn) {
             span_lint_and_help(
                 cx,
                 FN_PARAMS_EXCESSIVE_BOOLS,
@@ -121,56 +129,55 @@ impl ExcessiveBools {
 
 impl_lint_pass!(ExcessiveBools => [STRUCT_EXCESSIVE_BOOLS, FN_PARAMS_EXCESSIVE_BOOLS]);
 
-fn is_bool_ty(ty: &Ty) -> bool {
-    if let TyKind::Path(None, path) = &ty.kind {
-        if let [name] = path.segments.as_slice() {
-            return name.ident.name == sym::bool;
+impl<'tcx> LateLintPass<'tcx> for ExcessiveBools {
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
+        if item.span.from_expansion() {
+            return;
+        }
+        if let ItemKind::Struct(variant_data, _) = &item.kind {
+            if has_repr_attr(cx, item.hir_id()) {
+                return;
+            }
+
+            if self.too_many_bools(variant_data.fields().iter().map(|field| field.ty), Kind::Struct) {
+                span_lint_and_help(
+                    cx,
+                    STRUCT_EXCESSIVE_BOOLS,
+                    item.span,
+                    &format!("more than {} bools in a struct", self.max_struct_bools),
+                    None,
+                    "consider using a state machine or refactoring bools into two-variant enums",
+                );
+            }
         }
     }
-    false
-}
 
-impl EarlyLintPass for ExcessiveBools {
-    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
-        if item.span.from_expansion() {
-            return;
+    fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'tcx>) {
+        // functions with a body are already checked by `check_fn`
+        if let TraitItemKind::Fn(fn_sig, TraitFn::Required(_)) = &trait_item.kind
+            && fn_sig.header.abi == Abi::Rust
+            {
+            self.check_fn_sig(cx, fn_sig.decl, fn_sig.span);
         }
-        match &item.kind {
-            ItemKind::Struct(variant_data, _) => {
-                if item.attrs.iter().any(|attr| attr.has_name(sym::repr)) {
-                    return;
-                }
+    }
 
-                let struct_bools = variant_data
-                    .fields()
-                    .iter()
-                    .filter(|field| is_bool_ty(&field.ty))
-                    .count()
-                    .try_into()
-                    .unwrap();
-                if self.max_struct_bools < struct_bools {
-                    span_lint_and_help(
-                        cx,
-                        STRUCT_EXCESSIVE_BOOLS,
-                        item.span,
-                        &format!("more than {} bools in a struct", self.max_struct_bools),
-                        None,
-                        "consider using a state machine or refactoring bools into two-variant enums",
-                    );
-                }
-            },
-            ItemKind::Impl(box Impl {
-                of_trait: None, items, ..
-            })
-            | ItemKind::Trait(box Trait { items, .. }) => {
-                for item in items {
-                    if let AssocItemKind::Fn(box Fn { sig, .. }) = &item.kind {
-                        self.check_fn_sig(cx, sig, item.span);
-                    }
-                }
-            },
-            ItemKind::Fn(box Fn { sig, .. }) => self.check_fn_sig(cx, sig, item.span),
-            _ => (),
+    fn check_fn(
+        &mut self,
+        cx: &LateContext<'tcx>,
+        fn_kind: FnKind<'tcx>,
+        fn_decl: &'tcx FnDecl<'tcx>,
+        _: &'tcx Body<'tcx>,
+        span: Span,
+        hir_id: HirId,
+    ) {
+        if let Some(fn_header) = fn_kind.header()
+            && fn_header.abi == Abi::Rust
+            && get_parent_as_impl(cx.tcx, hir_id)
+                .map_or(true,
+                    |impl_item| impl_item.of_trait.is_none()
+                )
+            {
+            self.check_fn_sig(cx, fn_decl, span);
         }
     }
 }
diff --git a/clippy_lints/src/fallible_impl_from.rs b/clippy_lints/src/fallible_impl_from.rs
index 0a633f242a5..9a1058470e1 100644
--- a/clippy_lints/src/fallible_impl_from.rs
+++ b/clippy_lints/src/fallible_impl_from.rs
@@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for FallibleImplFrom {
     }
 }
 
-fn lint_impl_body<'tcx>(cx: &LateContext<'tcx>, impl_span: Span, impl_items: &[hir::ImplItemRef]) {
+fn lint_impl_body(cx: &LateContext<'_>, impl_span: Span, impl_items: &[hir::ImplItemRef]) {
     use rustc_hir::intravisit::{self, Visitor};
     use rustc_hir::{Expr, ImplItemKind};
 
diff --git a/clippy_lints/src/from_raw_with_void_ptr.rs b/clippy_lints/src/from_raw_with_void_ptr.rs
new file mode 100644
index 00000000000..00f5ba56496
--- /dev/null
+++ b/clippy_lints/src/from_raw_with_void_ptr.rs
@@ -0,0 +1,77 @@
+use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::ty::is_c_void;
+use clippy_utils::{match_def_path, path_def_id, paths};
+use rustc_hir::def_id::DefId;
+use rustc_hir::{Expr, ExprKind, QPath};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::RawPtr;
+use rustc_middle::ty::TypeAndMut;
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::sym;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks if we're passing a `c_void` raw pointer to `{Box,Rc,Arc,Weak}::from_raw(_)`
+    ///
+    /// ### Why is this bad?
+    /// When dealing with `c_void` raw pointers in FFI, it is easy to run into the pitfall of calling `from_raw` with the `c_void` pointer.
+    /// The type signature of `Box::from_raw` is `fn from_raw(raw: *mut T) -> Box<T>`, so if you pass a `*mut c_void` you will get a `Box<c_void>` (and similarly for `Rc`, `Arc` and `Weak`).
+    /// For this to be safe, `c_void` would need to have the same memory layout as the original type, which is often not the case.
+    ///
+    /// ### Example
+    /// ```rust
+    /// # use std::ffi::c_void;
+    /// let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void;
+    /// let _ = unsafe { Box::from_raw(ptr) };
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// # use std::ffi::c_void;
+    /// # let ptr = Box::into_raw(Box::new(42usize)) as *mut c_void;
+    /// let _ = unsafe { Box::from_raw(ptr as *mut usize) };
+    /// ```
+    ///
+    #[clippy::version = "1.66.0"]
+    pub FROM_RAW_WITH_VOID_PTR,
+    suspicious,
+    "creating a `Box` from a void raw pointer"
+}
+declare_lint_pass!(FromRawWithVoidPtr => [FROM_RAW_WITH_VOID_PTR]);
+
+impl LateLintPass<'_> for FromRawWithVoidPtr {
+    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+        if let ExprKind::Call(box_from_raw, [arg]) = expr.kind
+        && let ExprKind::Path(QPath::TypeRelative(ty, seg)) = box_from_raw.kind
+        && seg.ident.name == sym!(from_raw)
+        && let Some(type_str) = path_def_id(cx, ty).and_then(|id| def_id_matches_type(cx, id))
+        && let arg_kind = cx.typeck_results().expr_ty(arg).kind()
+        && let RawPtr(TypeAndMut { ty, .. }) = arg_kind
+        && is_c_void(cx, *ty) {
+            let msg = format!("creating a `{type_str}` from a void raw pointer");
+            span_lint_and_help(cx, FROM_RAW_WITH_VOID_PTR, expr.span, &msg, Some(arg.span), "cast this to a pointer of the appropriate type");
+        }
+    }
+}
+
+/// Checks whether a `DefId` matches `Box`, `Rc`, `Arc`, or one of the `Weak` types.
+/// Returns a static string slice with the name of the type, if one was found.
+fn def_id_matches_type(cx: &LateContext<'_>, def_id: DefId) -> Option<&'static str> {
+    // Box
+    if Some(def_id) == cx.tcx.lang_items().owned_box() {
+        return Some("Box");
+    }
+
+    if let Some(symbol) = cx.tcx.get_diagnostic_name(def_id) {
+        if symbol == sym::Arc {
+            return Some("Arc");
+        } else if symbol == sym::Rc {
+            return Some("Rc");
+        }
+    }
+
+    if match_def_path(cx, def_id, &paths::WEAK_RC) || match_def_path(cx, def_id, &paths::WEAK_ARC) {
+        Some("Weak")
+    } else {
+        None
+    }
+}
diff --git a/clippy_lints/src/functions/mod.rs b/clippy_lints/src/functions/mod.rs
index 90911e0bf25..ae0e0833446 100644
--- a/clippy_lints/src/functions/mod.rs
+++ b/clippy_lints/src/functions/mod.rs
@@ -254,7 +254,7 @@ declare_clippy_lint! {
     ///     Ok(())
     /// }
     /// ```
-    #[clippy::version = "1.64.0"]
+    #[clippy::version = "1.65.0"]
     pub RESULT_LARGE_ERR,
     perf,
     "function returning `Result` with large `Err` type"
diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs
index bff69f91518..d22bede36b4 100644
--- a/clippy_lints/src/functions/must_use.rs
+++ b/clippy_lints/src/functions/must_use.rs
@@ -50,7 +50,9 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp
         let attr = cx.tcx.get_attr(item.owner_id.to_def_id(), sym::must_use);
         if let Some(attr) = attr {
             check_needless_must_use(cx, sig.decl, item.hir_id(), item.span, fn_header_span, attr);
-        } else if is_public && !is_proc_macro(cx.sess(), attrs) && trait_ref_of_method(cx, item.owner_id.def_id).is_none()
+        } else if is_public
+            && !is_proc_macro(cx.sess(), attrs)
+            && trait_ref_of_method(cx, item.owner_id.def_id).is_none()
         {
             check_must_use_candidate(
                 cx,
@@ -175,7 +177,7 @@ fn is_mutable_pat(cx: &LateContext<'_>, pat: &hir::Pat<'_>, tys: &mut DefIdSet)
         return false; // ignore `_` patterns
     }
     if cx.tcx.has_typeck_results(pat.hir_id.owner.to_def_id()) {
-        is_mutable_ty(cx, cx.tcx.typeck(pat.hir_id.owner.def_id).pat_ty(pat), pat.span, tys)
+        is_mutable_ty(cx, cx.tcx.typeck(pat.hir_id.owner.def_id).pat_ty(pat), tys)
     } else {
         false
     }
@@ -183,7 +185,7 @@ fn is_mutable_pat(cx: &LateContext<'_>, pat: &hir::Pat<'_>, tys: &mut DefIdSet)
 
 static KNOWN_WRAPPER_TYS: &[Symbol] = &[sym::Rc, sym::Arc];
 
-fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span, tys: &mut DefIdSet) -> bool {
+fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, tys: &mut DefIdSet) -> bool {
     match *ty.kind() {
         // primitive types are never mutable
         ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false,
@@ -192,12 +194,12 @@ fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span, tys: &m
                 || KNOWN_WRAPPER_TYS
                     .iter()
                     .any(|&sym| cx.tcx.is_diagnostic_item(sym, adt.did()))
-                    && substs.types().any(|ty| is_mutable_ty(cx, ty, span, tys))
+                    && substs.types().any(|ty| is_mutable_ty(cx, ty, tys))
         },
-        ty::Tuple(substs) => substs.iter().any(|ty| is_mutable_ty(cx, ty, span, tys)),
-        ty::Array(ty, _) | ty::Slice(ty) => is_mutable_ty(cx, ty, span, tys),
+        ty::Tuple(substs) => substs.iter().any(|ty| is_mutable_ty(cx, ty, tys)),
+        ty::Array(ty, _) | ty::Slice(ty) => is_mutable_ty(cx, ty, tys),
         ty::RawPtr(ty::TypeAndMut { ty, mutbl }) | ty::Ref(_, ty, mutbl) => {
-            mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, span, tys)
+            mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, tys)
         },
         // calling something constitutes a side effect, so return true on all callables
         // also never calls need not be used, so return true for them, too
@@ -225,12 +227,7 @@ fn mutates_static<'tcx>(cx: &LateContext<'tcx>, body: &'tcx hir::Body<'_>) -> bo
                 let mut tys = DefIdSet::default();
                 for arg in args {
                     if cx.tcx.has_typeck_results(arg.hir_id.owner.to_def_id())
-                        && is_mutable_ty(
-                            cx,
-                            cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg),
-                            arg.span,
-                            &mut tys,
-                        )
+                        && is_mutable_ty(cx, cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg), &mut tys)
                         && is_mutated_static(arg)
                     {
                         return ControlFlow::Break(());
@@ -243,12 +240,7 @@ fn mutates_static<'tcx>(cx: &LateContext<'tcx>, body: &'tcx hir::Body<'_>) -> bo
                 let mut tys = DefIdSet::default();
                 for arg in std::iter::once(receiver).chain(args.iter()) {
                     if cx.tcx.has_typeck_results(arg.hir_id.owner.to_def_id())
-                        && is_mutable_ty(
-                            cx,
-                            cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg),
-                            arg.span,
-                            &mut tys,
-                        )
+                        && is_mutable_ty(cx, cx.tcx.typeck(arg.hir_id.owner.def_id).expr_ty(arg), &mut tys)
                         && is_mutated_static(arg)
                     {
                         return ControlFlow::Break(());
diff --git a/clippy_lints/src/functions/result.rs b/clippy_lints/src/functions/result.rs
index 5c63fb2acb1..f7e30b051a6 100644
--- a/clippy_lints/src/functions/result.rs
+++ b/clippy_lints/src/functions/result.rs
@@ -2,12 +2,12 @@ use rustc_errors::Diagnostic;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::{self, Adt, Ty};
 use rustc_span::{sym, Span};
 
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
 use clippy_utils::trait_ref_of_method;
-use clippy_utils::ty::{approx_ty_size, is_type_diagnostic_item};
+use clippy_utils::ty::{approx_ty_size, is_type_diagnostic_item, AdtVariantInfo};
 
 use super::{RESULT_LARGE_ERR, RESULT_UNIT_ERR};
 
@@ -84,17 +84,57 @@ fn check_result_unit_err(cx: &LateContext<'_>, err_ty: Ty<'_>, fn_header_span: S
 }
 
 fn check_result_large_err<'tcx>(cx: &LateContext<'tcx>, err_ty: Ty<'tcx>, hir_ty_span: Span, large_err_threshold: u64) {
-    let ty_size = approx_ty_size(cx, err_ty);
-    if ty_size >= large_err_threshold {
-        span_lint_and_then(
-            cx,
-            RESULT_LARGE_ERR,
-            hir_ty_span,
-            "the `Err`-variant returned from this function is very large",
-            |diag: &mut Diagnostic| {
-                diag.span_label(hir_ty_span, format!("the `Err`-variant is at least {ty_size} bytes"));
-                diag.help(format!("try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`"));
-            },
-        );
+    if_chain! {
+        if let Adt(adt, subst) = err_ty.kind();
+        if let Some(local_def_id) = err_ty.ty_adt_def().expect("already checked this is adt").did().as_local();
+        if let Some(hir::Node::Item(item)) = cx
+            .tcx
+            .hir()
+            .find_by_def_id(local_def_id);
+        if let hir::ItemKind::Enum(ref def, _) = item.kind;
+        then {
+            let variants_size = AdtVariantInfo::new(cx, *adt, subst);
+            if variants_size[0].size >= large_err_threshold {
+                span_lint_and_then(
+                    cx,
+                    RESULT_LARGE_ERR,
+                    hir_ty_span,
+                    "the `Err`-variant returned from this function is very large",
+                    |diag| {
+                        diag.span_label(
+                            def.variants[variants_size[0].ind].span,
+                            format!("the largest variant contains at least {} bytes", variants_size[0].size),
+                        );
+
+                        for variant in &variants_size[1..] {
+                            if variant.size >= large_err_threshold {
+                                let variant_def = &def.variants[variant.ind];
+                                diag.span_label(
+                                    variant_def.span,
+                                    format!("the variant `{}` contains at least {} bytes", variant_def.ident, variant.size),
+                                );
+                            }
+                        }
+
+                        diag.help(format!("try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`"));
+                    }
+                );
+            }
+        }
+        else {
+            let ty_size = approx_ty_size(cx, err_ty);
+            if ty_size >= large_err_threshold {
+                span_lint_and_then(
+                    cx,
+                    RESULT_LARGE_ERR,
+                    hir_ty_span,
+                    "the `Err`-variant returned from this function is very large",
+                    |diag: &mut Diagnostic| {
+                        diag.span_label(hir_ty_span, format!("the `Err`-variant is at least {ty_size} bytes"));
+                        diag.help(format!("try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`"));
+                    },
+                );
+            }
+        }
     }
 }
diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs
index 94e06cf704b..64a4a3fa741 100644
--- a/clippy_lints/src/implicit_hasher.rs
+++ b/clippy_lints/src/implicit_hasher.rs
@@ -66,8 +66,8 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         use rustc_span::BytePos;
 
-        fn suggestion<'tcx>(
-            cx: &LateContext<'tcx>,
+        fn suggestion(
+            cx: &LateContext<'_>,
             diag: &mut Diagnostic,
             generics_span: Span,
             generics_suggestion_span: Span,
diff --git a/clippy_lints/src/index_refutable_slice.rs b/clippy_lints/src/index_refutable_slice.rs
index c7b5badaae5..0d5099bde6d 100644
--- a/clippy_lints/src/index_refutable_slice.rs
+++ b/clippy_lints/src/index_refutable_slice.rs
@@ -207,8 +207,8 @@ impl SliceLintInformation {
     }
 }
 
-fn filter_lintable_slices<'a, 'tcx>(
-    cx: &'a LateContext<'tcx>,
+fn filter_lintable_slices<'tcx>(
+    cx: &LateContext<'tcx>,
     slice_lint_info: FxIndexMap<hir::HirId, SliceLintInformation>,
     max_suggested_slice: u64,
     scope: &'tcx hir::Expr<'tcx>,
diff --git a/clippy_lints/src/indexing_slicing.rs b/clippy_lints/src/indexing_slicing.rs
index af40a5a8187..4cd7dff4cfd 100644
--- a/clippy_lints/src/indexing_slicing.rs
+++ b/clippy_lints/src/indexing_slicing.rs
@@ -171,11 +171,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexingSlicing {
 
 /// Returns a tuple of options with the start and end (exclusive) values of
 /// the range. If the start or end is not constant, None is returned.
-fn to_const_range<'tcx>(
-    cx: &LateContext<'tcx>,
-    range: higher::Range<'_>,
-    array_size: u128,
-) -> (Option<u128>, Option<u128>) {
+fn to_const_range(cx: &LateContext<'_>, range: higher::Range<'_>, array_size: u128) -> (Option<u128>, Option<u128>) {
     let s = range
         .start
         .map(|expr| constant(cx, cx.typeck_results(), expr).map(|(c, _)| c));
diff --git a/clippy_lints/src/instant_subtraction.rs b/clippy_lints/src/instant_subtraction.rs
new file mode 100644
index 00000000000..60754b224fc
--- /dev/null
+++ b/clippy_lints/src/instant_subtraction.rs
@@ -0,0 +1,184 @@
+use clippy_utils::{
+    diagnostics::{self, span_lint_and_sugg},
+    meets_msrv, msrvs, source,
+    sugg::Sugg,
+    ty,
+};
+use rustc_errors::Applicability;
+use rustc_hir::{BinOpKind, Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_semver::RustcVersion;
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::{source_map::Spanned, sym};
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Lints subtraction between `Instant::now()` and another `Instant`.
+    ///
+    /// ### Why is this bad?
+    /// It is easy to accidentally write `prev_instant - Instant::now()`, which will always be 0ns
+    /// as `Instant` subtraction saturates.
+    ///
+    /// `prev_instant.elapsed()` also more clearly signals intention.
+    ///
+    /// ### Example
+    /// ```rust
+    /// use std::time::Instant;
+    /// let prev_instant = Instant::now();
+    /// let duration = Instant::now() - prev_instant;
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// use std::time::Instant;
+    /// let prev_instant = Instant::now();
+    /// let duration = prev_instant.elapsed();
+    /// ```
+    #[clippy::version = "1.65.0"]
+    pub MANUAL_INSTANT_ELAPSED,
+    pedantic,
+    "subtraction between `Instant::now()` and previous `Instant`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Lints subtraction between an [`Instant`] and a [`Duration`].
+    ///
+    /// ### Why is this bad?
+    /// Unchecked subtraction could cause underflow on certain platforms, leading to
+    /// unintentional panics.
+    ///
+    /// ### Example
+    /// ```rust
+    /// # use std::time::{Instant, Duration};
+    /// let time_passed = Instant::now() - Duration::from_secs(5);
+    /// ```
+    ///
+    /// Use instead:
+    /// ```rust
+    /// # use std::time::{Instant, Duration};
+    /// let time_passed = Instant::now().checked_sub(Duration::from_secs(5));
+    /// ```
+    ///
+    /// [`Duration`]: std::time::Duration
+    /// [`Instant::now()`]: std::time::Instant::now;
+    #[clippy::version = "1.65.0"]
+    pub UNCHECKED_DURATION_SUBTRACTION,
+    suspicious,
+    "finds unchecked subtraction of a 'Duration' from an 'Instant'"
+}
+
+pub struct InstantSubtraction {
+    msrv: Option<RustcVersion>,
+}
+
+impl InstantSubtraction {
+    #[must_use]
+    pub fn new(msrv: Option<RustcVersion>) -> Self {
+        Self { msrv }
+    }
+}
+
+impl_lint_pass!(InstantSubtraction => [MANUAL_INSTANT_ELAPSED, UNCHECKED_DURATION_SUBTRACTION]);
+
+impl LateLintPass<'_> for InstantSubtraction {
+    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
+        if let ExprKind::Binary(
+            Spanned {
+                node: BinOpKind::Sub, ..
+            },
+            lhs,
+            rhs,
+        ) = expr.kind
+        {
+            if_chain! {
+                if is_instant_now_call(cx, lhs);
+
+                if is_an_instant(cx, rhs);
+                if let Some(sugg) = Sugg::hir_opt(cx, rhs);
+
+                then {
+                    print_manual_instant_elapsed_sugg(cx, expr, sugg)
+                } else {
+                    if_chain! {
+                        if !expr.span.from_expansion();
+                        if meets_msrv(self.msrv, msrvs::TRY_FROM);
+
+                        if is_an_instant(cx, lhs);
+                        if is_a_duration(cx, rhs);
+
+                        then {
+                            print_unchecked_duration_subtraction_sugg(cx, lhs, rhs, expr)
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    extract_msrv_attr!(LateContext);
+}
+
+fn is_instant_now_call(cx: &LateContext<'_>, expr_block: &'_ Expr<'_>) -> bool {
+    if let ExprKind::Call(fn_expr, []) = expr_block.kind
+        && let Some(fn_id) = clippy_utils::path_def_id(cx, fn_expr)
+        && clippy_utils::match_def_path(cx, fn_id, &clippy_utils::paths::INSTANT_NOW)
+    {
+        true
+    } else {
+        false
+    }
+}
+
+fn is_an_instant(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    let expr_ty = cx.typeck_results().expr_ty(expr);
+
+    match expr_ty.kind() {
+        rustc_middle::ty::Adt(def, _) => clippy_utils::match_def_path(cx, def.did(), &clippy_utils::paths::INSTANT),
+        _ => false,
+    }
+}
+
+fn is_a_duration(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    let expr_ty = cx.typeck_results().expr_ty(expr);
+    ty::is_type_diagnostic_item(cx, expr_ty, sym::Duration)
+}
+
+fn print_manual_instant_elapsed_sugg(cx: &LateContext<'_>, expr: &Expr<'_>, sugg: Sugg<'_>) {
+    span_lint_and_sugg(
+        cx,
+        MANUAL_INSTANT_ELAPSED,
+        expr.span,
+        "manual implementation of `Instant::elapsed`",
+        "try",
+        format!("{}.elapsed()", sugg.maybe_par()),
+        Applicability::MachineApplicable,
+    );
+}
+
+fn print_unchecked_duration_subtraction_sugg(
+    cx: &LateContext<'_>,
+    left_expr: &Expr<'_>,
+    right_expr: &Expr<'_>,
+    expr: &Expr<'_>,
+) {
+    let mut applicability = Applicability::MachineApplicable;
+
+    let left_expr =
+        source::snippet_with_applicability(cx, left_expr.span, "std::time::Instant::now()", &mut applicability);
+    let right_expr = source::snippet_with_applicability(
+        cx,
+        right_expr.span,
+        "std::time::Duration::from_secs(1)",
+        &mut applicability,
+    );
+
+    diagnostics::span_lint_and_sugg(
+        cx,
+        UNCHECKED_DURATION_SUBTRACTION,
+        expr.span,
+        "unchecked subtraction of a 'Duration' from an 'Instant'",
+        "try",
+        format!("{left_expr}.checked_sub({right_expr}).unwrap()"),
+        applicability,
+    );
+}
diff --git a/clippy_lints/src/int_plus_one.rs b/clippy_lints/src/int_plus_one.rs
index f793abdfda3..1b14e525d9a 100644
--- a/clippy_lints/src/int_plus_one.rs
+++ b/clippy_lints/src/int_plus_one.rs
@@ -63,58 +63,54 @@ impl IntPlusOne {
     fn check_binop(cx: &EarlyContext<'_>, binop: BinOpKind, lhs: &Expr, rhs: &Expr) -> Option<String> {
         match (binop, &lhs.kind, &rhs.kind) {
             // case where `x - 1 >= ...` or `-1 + x >= ...`
-            (BinOpKind::Ge, &ExprKind::Binary(ref lhskind, ref lhslhs, ref lhsrhs), _) => {
+            (BinOpKind::Ge, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) => {
                 match (lhskind.node, &lhslhs.kind, &lhsrhs.kind) {
                     // `-1 + x`
-                    (BinOpKind::Add, &ExprKind::Lit(lit), _) if Self::check_lit(lit, -1) => {
+                    (BinOpKind::Add, ExprKind::Lit(lit), _) if Self::check_lit(*lit, -1) => {
                         Self::generate_recommendation(cx, binop, lhsrhs, rhs, Side::Lhs)
                     },
                     // `x - 1`
-                    (BinOpKind::Sub, _, &ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
+                    (BinOpKind::Sub, _, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => {
                         Self::generate_recommendation(cx, binop, lhslhs, rhs, Side::Lhs)
                     },
                     _ => None,
                 }
             },
             // case where `... >= y + 1` or `... >= 1 + y`
-            (BinOpKind::Ge, _, &ExprKind::Binary(ref rhskind, ref rhslhs, ref rhsrhs))
-                if rhskind.node == BinOpKind::Add =>
-            {
+            (BinOpKind::Ge, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) if rhskind.node == BinOpKind::Add => {
                 match (&rhslhs.kind, &rhsrhs.kind) {
                     // `y + 1` and `1 + y`
-                    (&ExprKind::Lit(lit), _) if Self::check_lit(lit, 1) => {
+                    (ExprKind::Lit(lit), _) if Self::check_lit(*lit, 1) => {
                         Self::generate_recommendation(cx, binop, rhsrhs, lhs, Side::Rhs)
                     },
-                    (_, &ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
+                    (_, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => {
                         Self::generate_recommendation(cx, binop, rhslhs, lhs, Side::Rhs)
                     },
                     _ => None,
                 }
             },
             // case where `x + 1 <= ...` or `1 + x <= ...`
-            (BinOpKind::Le, &ExprKind::Binary(ref lhskind, ref lhslhs, ref lhsrhs), _)
-                if lhskind.node == BinOpKind::Add =>
-            {
+            (BinOpKind::Le, ExprKind::Binary(lhskind, lhslhs, lhsrhs), _) if lhskind.node == BinOpKind::Add => {
                 match (&lhslhs.kind, &lhsrhs.kind) {
                     // `1 + x` and `x + 1`
-                    (&ExprKind::Lit(lit), _) if Self::check_lit(lit, 1) => {
+                    (ExprKind::Lit(lit), _) if Self::check_lit(*lit, 1) => {
                         Self::generate_recommendation(cx, binop, lhsrhs, rhs, Side::Lhs)
                     },
-                    (_, &ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
+                    (_, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => {
                         Self::generate_recommendation(cx, binop, lhslhs, rhs, Side::Lhs)
                     },
                     _ => None,
                 }
             },
             // case where `... >= y - 1` or `... >= -1 + y`
-            (BinOpKind::Le, _, &ExprKind::Binary(ref rhskind, ref rhslhs, ref rhsrhs)) => {
+            (BinOpKind::Le, _, ExprKind::Binary(rhskind, rhslhs, rhsrhs)) => {
                 match (rhskind.node, &rhslhs.kind, &rhsrhs.kind) {
                     // `-1 + y`
-                    (BinOpKind::Add, &ExprKind::Lit(lit), _) if Self::check_lit(lit, -1) => {
+                    (BinOpKind::Add, ExprKind::Lit(lit), _) if Self::check_lit(*lit, -1) => {
                         Self::generate_recommendation(cx, binop, rhsrhs, lhs, Side::Rhs)
                     },
                     // `y - 1`
-                    (BinOpKind::Sub, _, &ExprKind::Lit(lit)) if Self::check_lit(lit, 1) => {
+                    (BinOpKind::Sub, _, ExprKind::Lit(lit)) if Self::check_lit(*lit, 1) => {
                         Self::generate_recommendation(cx, binop, rhslhs, lhs, Side::Rhs)
                     },
                     _ => None,
diff --git a/clippy_lints/src/invalid_upcast_comparisons.rs b/clippy_lints/src/invalid_upcast_comparisons.rs
index 0ef77e03de9..6ea637412d5 100644
--- a/clippy_lints/src/invalid_upcast_comparisons.rs
+++ b/clippy_lints/src/invalid_upcast_comparisons.rs
@@ -38,7 +38,7 @@ declare_clippy_lint! {
 
 declare_lint_pass!(InvalidUpcastComparisons => [INVALID_UPCAST_COMPARISONS]);
 
-fn numeric_cast_precast_bounds<'a>(cx: &LateContext<'_>, expr: &'a Expr<'_>) -> Option<(FullInt, FullInt)> {
+fn numeric_cast_precast_bounds(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<(FullInt, FullInt)> {
     if let ExprKind::Cast(cast_exp, _) = expr.kind {
         let pre_cast_ty = cx.typeck_results().expr_ty(cast_exp);
         let cast_ty = cx.typeck_results().expr_ty(expr);
diff --git a/clippy_lints/src/large_enum_variant.rs b/clippy_lints/src/large_enum_variant.rs
index 06e95728549..b18456ee523 100644
--- a/clippy_lints/src/large_enum_variant.rs
+++ b/clippy_lints/src/large_enum_variant.rs
@@ -1,12 +1,15 @@
 //! lint when there is a large size difference between variants on an enum
 
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{diagnostics::span_lint_and_then, ty::approx_ty_size, ty::is_copy};
+use clippy_utils::{
+    diagnostics::span_lint_and_then,
+    ty::{approx_ty_size, is_copy, AdtVariantInfo},
+};
 use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty::{Adt, AdtDef, GenericArg, List, Ty};
+use rustc_middle::ty::{Adt, Ty};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::Span;
 
@@ -72,49 +75,6 @@ impl LargeEnumVariant {
     }
 }
 
-struct FieldInfo {
-    ind: usize,
-    size: u64,
-}
-
-struct VariantInfo {
-    ind: usize,
-    size: u64,
-    fields_size: Vec<FieldInfo>,
-}
-
-fn variants_size<'tcx>(
-    cx: &LateContext<'tcx>,
-    adt: AdtDef<'tcx>,
-    subst: &'tcx List<GenericArg<'tcx>>,
-) -> Vec<VariantInfo> {
-    let mut variants_size = adt
-        .variants()
-        .iter()
-        .enumerate()
-        .map(|(i, variant)| {
-            let mut fields_size = variant
-                .fields
-                .iter()
-                .enumerate()
-                .map(|(i, f)| FieldInfo {
-                    ind: i,
-                    size: approx_ty_size(cx, f.ty(cx.tcx, subst)),
-                })
-                .collect::<Vec<_>>();
-            fields_size.sort_by(|a, b| (a.size.cmp(&b.size)));
-
-            VariantInfo {
-                ind: i,
-                size: fields_size.iter().map(|info| info.size).sum(),
-                fields_size,
-            }
-        })
-        .collect::<Vec<_>>();
-    variants_size.sort_by(|a, b| (b.size.cmp(&a.size)));
-    variants_size
-}
-
 impl_lint_pass!(LargeEnumVariant => [LARGE_ENUM_VARIANT]);
 
 impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
@@ -130,7 +90,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
             if adt.variants().len() <= 1 {
                 return;
             }
-            let variants_size = variants_size(cx, *adt, subst);
+            let variants_size = AdtVariantInfo::new(cx, *adt, subst);
 
             let mut difference = variants_size[0].size - variants_size[1].size;
             if difference > self.maximum_size_difference_allowed {
@@ -173,16 +133,16 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
                                 .fields_size
                                 .iter()
                                 .rev()
-                                .map_while(|val| {
+                                .map_while(|&(ind, size)| {
                                     if difference > self.maximum_size_difference_allowed {
-                                        difference = difference.saturating_sub(val.size);
+                                        difference = difference.saturating_sub(size);
                                         Some((
-                                            fields[val.ind].ty.span,
+                                            fields[ind].ty.span,
                                             format!(
                                                 "Box<{}>",
                                                 snippet_with_applicability(
                                                     cx,
-                                                    fields[val.ind].ty.span,
+                                                    fields[ind].ty.span,
                                                     "..",
                                                     &mut applicability
                                                 )
diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs
index b0cba40c27a..4c133c06a15 100644
--- a/clippy_lints/src/len_zero.rs
+++ b/clippy_lints/src/len_zero.rs
@@ -366,8 +366,7 @@ fn check_for_is_empty<'tcx>(
 }
 
 fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>, op: &str, compare_to: u32) {
-    if let (&ExprKind::MethodCall(method_path, receiver, args, _), &ExprKind::Lit(ref lit)) = (&method.kind, &lit.kind)
-    {
+    if let (&ExprKind::MethodCall(method_path, receiver, args, _), ExprKind::Lit(lit)) = (&method.kind, &lit.kind) {
         // check if we are in an is_empty() method
         if let Some(name) = get_item_name(cx, method) {
             if name.as_str() == "is_empty" {
diff --git a/clippy_lints/src/let_underscore.rs b/clippy_lints/src/let_underscore.rs
index b7798b1c1d7..61f87b91400 100644
--- a/clippy_lints/src/let_underscore.rs
+++ b/clippy_lints/src/let_underscore.rs
@@ -1,13 +1,11 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::ty::{is_must_use_ty, is_type_diagnostic_item, match_type};
+use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type};
 use clippy_utils::{is_must_use_func_call, paths};
-use if_chain::if_chain;
 use rustc_hir::{Local, PatKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::subst::GenericArgKind;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::{sym, Symbol};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -30,13 +28,14 @@ declare_clippy_lint! {
     #[clippy::version = "1.42.0"]
     pub LET_UNDERSCORE_MUST_USE,
     restriction,
-    "non-binding let on a `#[must_use]` expression"
+    "non-binding `let` on a `#[must_use]` expression"
 }
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for `let _ = sync_lock`.
-    /// This supports `mutex` and `rwlock` in `std::sync` and `parking_lot`.
+    /// Checks for `let _ = sync_lock`. This supports `mutex` and `rwlock` in
+    /// `parking_lot`. For `std` locks see the `rustc` lint
+    /// [`let_underscore_lock`](https://doc.rust-lang.org/nightly/rustc/lints/listing/deny-by-default.html#let-underscore-lock)
     ///
     /// ### Why is this bad?
     /// This statement immediately drops the lock instead of
@@ -57,50 +56,41 @@ declare_clippy_lint! {
     #[clippy::version = "1.43.0"]
     pub LET_UNDERSCORE_LOCK,
     correctness,
-    "non-binding let on a synchronization lock"
+    "non-binding `let` on a synchronization lock"
 }
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for `let _ = <expr>`
-    /// where expr has a type that implements `Drop`
+    /// Checks for `let _ = <expr>` where the resulting type of expr implements `Future`
     ///
     /// ### Why is this bad?
-    /// This statement immediately drops the initializer
-    /// expression instead of extending its lifetime to the end of the scope, which
-    /// is often not intended. To extend the expression's lifetime to the end of the
-    /// scope, use an underscore-prefixed name instead (i.e. _var). If you want to
-    /// explicitly drop the expression, `std::mem::drop` conveys your intention
-    /// better and is less error-prone.
+    /// Futures must be polled for work to be done. The original intention was most likely to await the future
+    /// and ignore the resulting value.
     ///
     /// ### Example
     /// ```rust
-    /// # struct DroppableItem;
-    /// {
-    ///     let _ = DroppableItem;
-    ///     //                   ^ dropped here
-    ///     /* more code */
+    /// async fn foo() -> Result<(), ()> {
+    ///     Ok(())
     /// }
+    /// let _ = foo();
     /// ```
     ///
     /// Use instead:
     /// ```rust
-    /// # struct DroppableItem;
-    /// {
-    ///     let _droppable = DroppableItem;
-    ///     /* more code */
-    ///     // dropped at end of scope
+    /// # async fn context() {
+    /// async fn foo() -> Result<(), ()> {
+    ///     Ok(())
     /// }
+    /// let _ = foo().await;
+    /// # }
     /// ```
-    #[clippy::version = "1.50.0"]
-    pub LET_UNDERSCORE_DROP,
-    pedantic,
-    "non-binding let on a type that implements `Drop`"
+    #[clippy::version = "1.66"]
+    pub LET_UNDERSCORE_FUTURE,
+    suspicious,
+    "non-binding `let` on a future"
 }
 
-declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_MUST_USE, LET_UNDERSCORE_LOCK, LET_UNDERSCORE_DROP]);
-
-const SYNC_GUARD_SYMS: [Symbol; 3] = [sym::MutexGuard, sym::RwLockReadGuard, sym::RwLockWriteGuard];
+declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_MUST_USE, LET_UNDERSCORE_LOCK, LET_UNDERSCORE_FUTURE]);
 
 const SYNC_GUARD_PATHS: [&[&str]; 3] = [
     &paths::PARKING_LOT_MUTEX_GUARD,
@@ -110,64 +100,53 @@ const SYNC_GUARD_PATHS: [&[&str]; 3] = [
 
 impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
     fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) {
-        if in_external_macro(cx.tcx.sess, local.span) {
-            return;
-        }
-
-        if_chain! {
-            if let PatKind::Wild = local.pat.kind;
-            if let Some(init) = local.init;
-            then {
-                let init_ty = cx.typeck_results().expr_ty(init);
-                let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() {
-                    GenericArgKind::Type(inner_ty) => {
-                        SYNC_GUARD_SYMS
-                            .iter()
-                            .any(|&sym| is_type_diagnostic_item(cx, inner_ty, sym))
-                            || SYNC_GUARD_PATHS.iter().any(|path| match_type(cx, inner_ty, path))
-                    },
-
-                    GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
-                });
-                if contains_sync_guard {
-                    span_lint_and_help(
-                        cx,
-                        LET_UNDERSCORE_LOCK,
-                        local.span,
-                        "non-binding let on a synchronization lock",
-                        None,
-                        "consider using an underscore-prefixed named \
-                            binding or dropping explicitly with `std::mem::drop`",
-                    );
-                } else if init_ty.needs_drop(cx.tcx, cx.param_env) {
-                    span_lint_and_help(
-                        cx,
-                        LET_UNDERSCORE_DROP,
-                        local.span,
-                        "non-binding `let` on a type that implements `Drop`",
-                        None,
-                        "consider using an underscore-prefixed named \
+        if !in_external_macro(cx.tcx.sess, local.span)
+            && let PatKind::Wild = local.pat.kind
+            && let Some(init) = local.init
+        {
+            let init_ty = cx.typeck_results().expr_ty(init);
+            let contains_sync_guard = init_ty.walk().any(|inner| match inner.unpack() {
+                GenericArgKind::Type(inner_ty) => SYNC_GUARD_PATHS.iter().any(|path| match_type(cx, inner_ty, path)),
+                GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => false,
+            });
+            if contains_sync_guard {
+                span_lint_and_help(
+                    cx,
+                    LET_UNDERSCORE_LOCK,
+                    local.span,
+                    "non-binding `let` on a synchronization lock",
+                    None,
+                    "consider using an underscore-prefixed named \
                             binding or dropping explicitly with `std::mem::drop`",
-                    );
-                } else if is_must_use_ty(cx, cx.typeck_results().expr_ty(init)) {
-                    span_lint_and_help(
-                        cx,
-                        LET_UNDERSCORE_MUST_USE,
-                        local.span,
-                        "non-binding let on an expression with `#[must_use]` type",
-                        None,
-                        "consider explicitly using expression value",
-                    );
-                } else if is_must_use_func_call(cx, init) {
-                    span_lint_and_help(
-                        cx,
-                        LET_UNDERSCORE_MUST_USE,
-                        local.span,
-                        "non-binding let on a result of a `#[must_use]` function",
-                        None,
-                        "consider explicitly using function result",
-                    );
-                }
+                );
+            } else if let Some(future_trait_def_id) = cx.tcx.lang_items().future_trait()
+                && implements_trait(cx, cx.typeck_results().expr_ty(init), future_trait_def_id, &[]) {
+                span_lint_and_help(
+                    cx,
+                    LET_UNDERSCORE_FUTURE,
+                    local.span,
+                    "non-binding `let` on a future",
+                    None,
+                    "consider awaiting the future or dropping explicitly with `std::mem::drop`"
+                );
+            } else if is_must_use_ty(cx, cx.typeck_results().expr_ty(init)) {
+                span_lint_and_help(
+                    cx,
+                    LET_UNDERSCORE_MUST_USE,
+                    local.span,
+                    "non-binding `let` on an expression with `#[must_use]` type",
+                    None,
+                    "consider explicitly using expression value",
+                );
+            } else if is_must_use_func_call(cx, init) {
+                span_lint_and_help(
+                    cx,
+                    LET_UNDERSCORE_MUST_USE,
+                    local.span,
+                    "non-binding `let` on a result of a `#[must_use]` function",
+                    None,
+                    "consider explicitly using function result",
+                );
             }
         }
     }
diff --git a/clippy_lints/src/lib.register_all.rs b/clippy_lints/src/lib.register_all.rs
deleted file mode 100644
index c455e1561b7..00000000000
--- a/clippy_lints/src/lib.register_all.rs
+++ /dev/null
@@ -1,368 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::all", Some("clippy_all"), vec![
-    LintId::of(almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE),
-    LintId::of(approx_const::APPROX_CONSTANT),
-    LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
-    LintId::of(async_yields_async::ASYNC_YIELDS_ASYNC),
-    LintId::of(attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
-    LintId::of(attrs::DEPRECATED_CFG_ATTR),
-    LintId::of(attrs::DEPRECATED_SEMVER),
-    LintId::of(attrs::MISMATCHED_TARGET_OS),
-    LintId::of(attrs::USELESS_ATTRIBUTE),
-    LintId::of(await_holding_invalid::AWAIT_HOLDING_INVALID_TYPE),
-    LintId::of(await_holding_invalid::AWAIT_HOLDING_LOCK),
-    LintId::of(await_holding_invalid::AWAIT_HOLDING_REFCELL_REF),
-    LintId::of(blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
-    LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
-    LintId::of(bool_to_int_with_if::BOOL_TO_INT_WITH_IF),
-    LintId::of(booleans::NONMINIMAL_BOOL),
-    LintId::of(booleans::OVERLY_COMPLEX_BOOL_EXPR),
-    LintId::of(borrow_deref_ref::BORROW_DEREF_REF),
-    LintId::of(box_default::BOX_DEFAULT),
-    LintId::of(casts::CAST_ABS_TO_UNSIGNED),
-    LintId::of(casts::CAST_ENUM_CONSTRUCTOR),
-    LintId::of(casts::CAST_ENUM_TRUNCATION),
-    LintId::of(casts::CAST_NAN_TO_INT),
-    LintId::of(casts::CAST_REF_TO_MUT),
-    LintId::of(casts::CAST_SLICE_DIFFERENT_SIZES),
-    LintId::of(casts::CAST_SLICE_FROM_RAW_PARTS),
-    LintId::of(casts::CHAR_LIT_AS_U8),
-    LintId::of(casts::FN_TO_NUMERIC_CAST),
-    LintId::of(casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION),
-    LintId::of(casts::UNNECESSARY_CAST),
-    LintId::of(collapsible_if::COLLAPSIBLE_ELSE_IF),
-    LintId::of(collapsible_if::COLLAPSIBLE_IF),
-    LintId::of(comparison_chain::COMPARISON_CHAIN),
-    LintId::of(copies::IFS_SAME_COND),
-    LintId::of(copies::IF_SAME_THEN_ELSE),
-    LintId::of(crate_in_macro_def::CRATE_IN_MACRO_DEF),
-    LintId::of(default::FIELD_REASSIGN_WITH_DEFAULT),
-    LintId::of(default_instead_of_iter_empty::DEFAULT_INSTEAD_OF_ITER_EMPTY),
-    LintId::of(dereference::EXPLICIT_AUTO_DEREF),
-    LintId::of(dereference::NEEDLESS_BORROW),
-    LintId::of(derivable_impls::DERIVABLE_IMPLS),
-    LintId::of(derive::DERIVE_HASH_XOR_EQ),
-    LintId::of(derive::DERIVE_ORD_XOR_PARTIAL_ORD),
-    LintId::of(disallowed_macros::DISALLOWED_MACROS),
-    LintId::of(disallowed_methods::DISALLOWED_METHODS),
-    LintId::of(disallowed_names::DISALLOWED_NAMES),
-    LintId::of(disallowed_types::DISALLOWED_TYPES),
-    LintId::of(doc::MISSING_SAFETY_DOC),
-    LintId::of(doc::NEEDLESS_DOCTEST_MAIN),
-    LintId::of(double_parens::DOUBLE_PARENS),
-    LintId::of(drop_forget_ref::DROP_COPY),
-    LintId::of(drop_forget_ref::DROP_NON_DROP),
-    LintId::of(drop_forget_ref::DROP_REF),
-    LintId::of(drop_forget_ref::FORGET_COPY),
-    LintId::of(drop_forget_ref::FORGET_NON_DROP),
-    LintId::of(drop_forget_ref::FORGET_REF),
-    LintId::of(drop_forget_ref::UNDROPPED_MANUALLY_DROPS),
-    LintId::of(duplicate_mod::DUPLICATE_MOD),
-    LintId::of(entry::MAP_ENTRY),
-    LintId::of(enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT),
-    LintId::of(enum_variants::ENUM_VARIANT_NAMES),
-    LintId::of(enum_variants::MODULE_INCEPTION),
-    LintId::of(escape::BOXED_LOCAL),
-    LintId::of(eta_reduction::REDUNDANT_CLOSURE),
-    LintId::of(explicit_write::EXPLICIT_WRITE),
-    LintId::of(float_literal::EXCESSIVE_PRECISION),
-    LintId::of(format::USELESS_FORMAT),
-    LintId::of(format_args::FORMAT_IN_FORMAT_ARGS),
-    LintId::of(format_args::TO_STRING_IN_FORMAT_ARGS),
-    LintId::of(format_args::UNUSED_FORMAT_SPECS),
-    LintId::of(format_impl::PRINT_IN_FORMAT_IMPL),
-    LintId::of(format_impl::RECURSIVE_FORMAT_IMPL),
-    LintId::of(formatting::POSSIBLE_MISSING_COMMA),
-    LintId::of(formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING),
-    LintId::of(formatting::SUSPICIOUS_ELSE_FORMATTING),
-    LintId::of(formatting::SUSPICIOUS_UNARY_OP_FORMATTING),
-    LintId::of(from_over_into::FROM_OVER_INTO),
-    LintId::of(from_str_radix_10::FROM_STR_RADIX_10),
-    LintId::of(functions::DOUBLE_MUST_USE),
-    LintId::of(functions::MUST_USE_UNIT),
-    LintId::of(functions::NOT_UNSAFE_PTR_ARG_DEREF),
-    LintId::of(functions::RESULT_LARGE_ERR),
-    LintId::of(functions::RESULT_UNIT_ERR),
-    LintId::of(functions::TOO_MANY_ARGUMENTS),
-    LintId::of(if_let_mutex::IF_LET_MUTEX),
-    LintId::of(implicit_saturating_add::IMPLICIT_SATURATING_ADD),
-    LintId::of(implicit_saturating_sub::IMPLICIT_SATURATING_SUB),
-    LintId::of(indexing_slicing::OUT_OF_BOUNDS_INDEXING),
-    LintId::of(infinite_iter::INFINITE_ITER),
-    LintId::of(inherent_to_string::INHERENT_TO_STRING),
-    LintId::of(inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY),
-    LintId::of(init_numbered_fields::INIT_NUMBERED_FIELDS),
-    LintId::of(inline_fn_without_body::INLINE_FN_WITHOUT_BODY),
-    LintId::of(int_plus_one::INT_PLUS_ONE),
-    LintId::of(invalid_utf8_in_unchecked::INVALID_UTF8_IN_UNCHECKED),
-    LintId::of(large_const_arrays::LARGE_CONST_ARRAYS),
-    LintId::of(large_enum_variant::LARGE_ENUM_VARIANT),
-    LintId::of(len_zero::COMPARISON_TO_EMPTY),
-    LintId::of(len_zero::LEN_WITHOUT_IS_EMPTY),
-    LintId::of(len_zero::LEN_ZERO),
-    LintId::of(let_underscore::LET_UNDERSCORE_LOCK),
-    LintId::of(lifetimes::EXTRA_UNUSED_LIFETIMES),
-    LintId::of(lifetimes::NEEDLESS_LIFETIMES),
-    LintId::of(literal_representation::INCONSISTENT_DIGIT_GROUPING),
-    LintId::of(literal_representation::MISTYPED_LITERAL_SUFFIXES),
-    LintId::of(literal_representation::UNUSUAL_BYTE_GROUPINGS),
-    LintId::of(loops::EMPTY_LOOP),
-    LintId::of(loops::EXPLICIT_COUNTER_LOOP),
-    LintId::of(loops::FOR_KV_MAP),
-    LintId::of(loops::ITER_NEXT_LOOP),
-    LintId::of(loops::MANUAL_FIND),
-    LintId::of(loops::MANUAL_FLATTEN),
-    LintId::of(loops::MANUAL_MEMCPY),
-    LintId::of(loops::MISSING_SPIN_LOOP),
-    LintId::of(loops::MUT_RANGE_BOUND),
-    LintId::of(loops::NEEDLESS_COLLECT),
-    LintId::of(loops::NEEDLESS_RANGE_LOOP),
-    LintId::of(loops::NEVER_LOOP),
-    LintId::of(loops::SAME_ITEM_PUSH),
-    LintId::of(loops::SINGLE_ELEMENT_LOOP),
-    LintId::of(loops::WHILE_IMMUTABLE_CONDITION),
-    LintId::of(loops::WHILE_LET_LOOP),
-    LintId::of(loops::WHILE_LET_ON_ITERATOR),
-    LintId::of(main_recursion::MAIN_RECURSION),
-    LintId::of(manual_async_fn::MANUAL_ASYNC_FN),
-    LintId::of(manual_bits::MANUAL_BITS),
-    LintId::of(manual_clamp::MANUAL_CLAMP),
-    LintId::of(manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE),
-    LintId::of(manual_rem_euclid::MANUAL_REM_EUCLID),
-    LintId::of(manual_retain::MANUAL_RETAIN),
-    LintId::of(manual_strip::MANUAL_STRIP),
-    LintId::of(map_unit_fn::OPTION_MAP_UNIT_FN),
-    LintId::of(map_unit_fn::RESULT_MAP_UNIT_FN),
-    LintId::of(match_result_ok::MATCH_RESULT_OK),
-    LintId::of(matches::COLLAPSIBLE_MATCH),
-    LintId::of(matches::INFALLIBLE_DESTRUCTURING_MATCH),
-    LintId::of(matches::MANUAL_FILTER),
-    LintId::of(matches::MANUAL_MAP),
-    LintId::of(matches::MANUAL_UNWRAP_OR),
-    LintId::of(matches::MATCH_AS_REF),
-    LintId::of(matches::MATCH_LIKE_MATCHES_MACRO),
-    LintId::of(matches::MATCH_OVERLAPPING_ARM),
-    LintId::of(matches::MATCH_REF_PATS),
-    LintId::of(matches::MATCH_SINGLE_BINDING),
-    LintId::of(matches::MATCH_STR_CASE_MISMATCH),
-    LintId::of(matches::NEEDLESS_MATCH),
-    LintId::of(matches::REDUNDANT_PATTERN_MATCHING),
-    LintId::of(matches::SINGLE_MATCH),
-    LintId::of(matches::WILDCARD_IN_OR_PATTERNS),
-    LintId::of(mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
-    LintId::of(mem_replace::MEM_REPLACE_WITH_DEFAULT),
-    LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
-    LintId::of(methods::BIND_INSTEAD_OF_MAP),
-    LintId::of(methods::BYTES_COUNT_TO_LEN),
-    LintId::of(methods::BYTES_NTH),
-    LintId::of(methods::CHARS_LAST_CMP),
-    LintId::of(methods::CHARS_NEXT_CMP),
-    LintId::of(methods::CLONE_DOUBLE_REF),
-    LintId::of(methods::CLONE_ON_COPY),
-    LintId::of(methods::COLLAPSIBLE_STR_REPLACE),
-    LintId::of(methods::ERR_EXPECT),
-    LintId::of(methods::EXPECT_FUN_CALL),
-    LintId::of(methods::EXTEND_WITH_DRAIN),
-    LintId::of(methods::FILTER_MAP_IDENTITY),
-    LintId::of(methods::FILTER_NEXT),
-    LintId::of(methods::FLAT_MAP_IDENTITY),
-    LintId::of(methods::GET_FIRST),
-    LintId::of(methods::GET_LAST_WITH_LEN),
-    LintId::of(methods::INSPECT_FOR_EACH),
-    LintId::of(methods::INTO_ITER_ON_REF),
-    LintId::of(methods::IS_DIGIT_ASCII_RADIX),
-    LintId::of(methods::ITERATOR_STEP_BY_ZERO),
-    LintId::of(methods::ITER_CLONED_COLLECT),
-    LintId::of(methods::ITER_COUNT),
-    LintId::of(methods::ITER_KV_MAP),
-    LintId::of(methods::ITER_NEXT_SLICE),
-    LintId::of(methods::ITER_NTH),
-    LintId::of(methods::ITER_NTH_ZERO),
-    LintId::of(methods::ITER_OVEREAGER_CLONED),
-    LintId::of(methods::ITER_SKIP_NEXT),
-    LintId::of(methods::MANUAL_FILTER_MAP),
-    LintId::of(methods::MANUAL_FIND_MAP),
-    LintId::of(methods::MANUAL_SATURATING_ARITHMETIC),
-    LintId::of(methods::MANUAL_SPLIT_ONCE),
-    LintId::of(methods::MANUAL_STR_REPEAT),
-    LintId::of(methods::MAP_CLONE),
-    LintId::of(methods::MAP_COLLECT_RESULT_UNIT),
-    LintId::of(methods::MAP_FLATTEN),
-    LintId::of(methods::MAP_IDENTITY),
-    LintId::of(methods::MUT_MUTEX_LOCK),
-    LintId::of(methods::NEEDLESS_OPTION_AS_DEREF),
-    LintId::of(methods::NEEDLESS_OPTION_TAKE),
-    LintId::of(methods::NEEDLESS_SPLITN),
-    LintId::of(methods::NEW_RET_NO_SELF),
-    LintId::of(methods::NONSENSICAL_OPEN_OPTIONS),
-    LintId::of(methods::NO_EFFECT_REPLACE),
-    LintId::of(methods::OBFUSCATED_IF_ELSE),
-    LintId::of(methods::OK_EXPECT),
-    LintId::of(methods::OPTION_AS_REF_DEREF),
-    LintId::of(methods::OPTION_FILTER_MAP),
-    LintId::of(methods::OPTION_MAP_OR_NONE),
-    LintId::of(methods::OR_FUN_CALL),
-    LintId::of(methods::OR_THEN_UNWRAP),
-    LintId::of(methods::RANGE_ZIP_WITH_LEN),
-    LintId::of(methods::REPEAT_ONCE),
-    LintId::of(methods::RESULT_MAP_OR_INTO_OPTION),
-    LintId::of(methods::SEARCH_IS_SOME),
-    LintId::of(methods::SHOULD_IMPLEMENT_TRAIT),
-    LintId::of(methods::SINGLE_CHAR_ADD_STR),
-    LintId::of(methods::SINGLE_CHAR_PATTERN),
-    LintId::of(methods::SKIP_WHILE_NEXT),
-    LintId::of(methods::STRING_EXTEND_CHARS),
-    LintId::of(methods::SUSPICIOUS_MAP),
-    LintId::of(methods::SUSPICIOUS_SPLITN),
-    LintId::of(methods::SUSPICIOUS_TO_OWNED),
-    LintId::of(methods::UNINIT_ASSUMED_INIT),
-    LintId::of(methods::UNIT_HASH),
-    LintId::of(methods::UNNECESSARY_FILTER_MAP),
-    LintId::of(methods::UNNECESSARY_FIND_MAP),
-    LintId::of(methods::UNNECESSARY_FOLD),
-    LintId::of(methods::UNNECESSARY_LAZY_EVALUATIONS),
-    LintId::of(methods::UNNECESSARY_SORT_BY),
-    LintId::of(methods::UNNECESSARY_TO_OWNED),
-    LintId::of(methods::UNWRAP_OR_ELSE_DEFAULT),
-    LintId::of(methods::USELESS_ASREF),
-    LintId::of(methods::VEC_RESIZE_TO_ZERO),
-    LintId::of(methods::WRONG_SELF_CONVENTION),
-    LintId::of(methods::ZST_OFFSET),
-    LintId::of(minmax::MIN_MAX),
-    LintId::of(misc::SHORT_CIRCUIT_STATEMENT),
-    LintId::of(misc::TOPLEVEL_REF_ARG),
-    LintId::of(misc::ZERO_PTR),
-    LintId::of(misc_early::BUILTIN_TYPE_SHADOW),
-    LintId::of(misc_early::DOUBLE_NEG),
-    LintId::of(misc_early::DUPLICATE_UNDERSCORE_ARGUMENT),
-    LintId::of(misc_early::MIXED_CASE_HEX_LITERALS),
-    LintId::of(misc_early::REDUNDANT_PATTERN),
-    LintId::of(misc_early::UNNEEDED_WILDCARD_PATTERN),
-    LintId::of(misc_early::ZERO_PREFIXED_LITERAL),
-    LintId::of(mixed_read_write_in_expression::DIVERGING_SUB_EXPRESSION),
-    LintId::of(multi_assignments::MULTI_ASSIGNMENTS),
-    LintId::of(mut_key::MUTABLE_KEY_TYPE),
-    LintId::of(mut_reference::UNNECESSARY_MUT_PASSED),
-    LintId::of(needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE),
-    LintId::of(needless_bool::BOOL_COMPARISON),
-    LintId::of(needless_bool::NEEDLESS_BOOL),
-    LintId::of(needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
-    LintId::of(needless_late_init::NEEDLESS_LATE_INIT),
-    LintId::of(needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS),
-    LintId::of(needless_question_mark::NEEDLESS_QUESTION_MARK),
-    LintId::of(needless_update::NEEDLESS_UPDATE),
-    LintId::of(neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
-    LintId::of(neg_multiply::NEG_MULTIPLY),
-    LintId::of(new_without_default::NEW_WITHOUT_DEFAULT),
-    LintId::of(no_effect::NO_EFFECT),
-    LintId::of(no_effect::UNNECESSARY_OPERATION),
-    LintId::of(non_copy_const::BORROW_INTERIOR_MUTABLE_CONST),
-    LintId::of(non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST),
-    LintId::of(non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
-    LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
-    LintId::of(octal_escapes::OCTAL_ESCAPES),
-    LintId::of(only_used_in_recursion::ONLY_USED_IN_RECURSION),
-    LintId::of(operators::ABSURD_EXTREME_COMPARISONS),
-    LintId::of(operators::ASSIGN_OP_PATTERN),
-    LintId::of(operators::BAD_BIT_MASK),
-    LintId::of(operators::CMP_NAN),
-    LintId::of(operators::CMP_OWNED),
-    LintId::of(operators::DOUBLE_COMPARISONS),
-    LintId::of(operators::DURATION_SUBSEC),
-    LintId::of(operators::EQ_OP),
-    LintId::of(operators::ERASING_OP),
-    LintId::of(operators::FLOAT_EQUALITY_WITHOUT_ABS),
-    LintId::of(operators::IDENTITY_OP),
-    LintId::of(operators::INEFFECTIVE_BIT_MASK),
-    LintId::of(operators::MISREFACTORED_ASSIGN_OP),
-    LintId::of(operators::MODULO_ONE),
-    LintId::of(operators::OP_REF),
-    LintId::of(operators::PTR_EQ),
-    LintId::of(operators::SELF_ASSIGNMENT),
-    LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),
-    LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
-    LintId::of(partialeq_ne_impl::PARTIALEQ_NE_IMPL),
-    LintId::of(partialeq_to_none::PARTIALEQ_TO_NONE),
-    LintId::of(precedence::PRECEDENCE),
-    LintId::of(ptr::CMP_NULL),
-    LintId::of(ptr::INVALID_NULL_PTR_USAGE),
-    LintId::of(ptr::MUT_FROM_REF),
-    LintId::of(ptr::PTR_ARG),
-    LintId::of(ptr_offset_with_cast::PTR_OFFSET_WITH_CAST),
-    LintId::of(question_mark::QUESTION_MARK),
-    LintId::of(ranges::MANUAL_RANGE_CONTAINS),
-    LintId::of(ranges::REVERSED_EMPTY_RANGES),
-    LintId::of(rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT),
-    LintId::of(read_zero_byte_vec::READ_ZERO_BYTE_VEC),
-    LintId::of(redundant_clone::REDUNDANT_CLONE),
-    LintId::of(redundant_closure_call::REDUNDANT_CLOSURE_CALL),
-    LintId::of(redundant_field_names::REDUNDANT_FIELD_NAMES),
-    LintId::of(redundant_slicing::REDUNDANT_SLICING),
-    LintId::of(redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
-    LintId::of(reference::DEREF_ADDROF),
-    LintId::of(regex::INVALID_REGEX),
-    LintId::of(returns::LET_AND_RETURN),
-    LintId::of(returns::NEEDLESS_RETURN),
-    LintId::of(self_named_constructors::SELF_NAMED_CONSTRUCTORS),
-    LintId::of(serde_api::SERDE_API_MISUSE),
-    LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
-    LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
-    LintId::of(slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
-    LintId::of(strings::STRING_FROM_UTF8_AS_BYTES),
-    LintId::of(strings::TRIM_SPLIT_WHITESPACE),
-    LintId::of(strlen_on_c_strings::STRLEN_ON_C_STRINGS),
-    LintId::of(suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
-    LintId::of(suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
-    LintId::of(swap::ALMOST_SWAPPED),
-    LintId::of(swap::MANUAL_SWAP),
-    LintId::of(swap_ptr_to_ref::SWAP_PTR_TO_REF),
-    LintId::of(tabs_in_doc_comments::TABS_IN_DOC_COMMENTS),
-    LintId::of(temporary_assignment::TEMPORARY_ASSIGNMENT),
-    LintId::of(to_digit_is_some::TO_DIGIT_IS_SOME),
-    LintId::of(transmute::CROSSPOINTER_TRANSMUTE),
-    LintId::of(transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS),
-    LintId::of(transmute::TRANSMUTE_BYTES_TO_STR),
-    LintId::of(transmute::TRANSMUTE_FLOAT_TO_INT),
-    LintId::of(transmute::TRANSMUTE_INT_TO_BOOL),
-    LintId::of(transmute::TRANSMUTE_INT_TO_CHAR),
-    LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT),
-    LintId::of(transmute::TRANSMUTE_NUM_TO_BYTES),
-    LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
-    LintId::of(transmute::TRANSMUTING_NULL),
-    LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
-    LintId::of(transmute::USELESS_TRANSMUTE),
-    LintId::of(transmute::WRONG_TRANSMUTE),
-    LintId::of(types::BORROWED_BOX),
-    LintId::of(types::BOX_COLLECTION),
-    LintId::of(types::REDUNDANT_ALLOCATION),
-    LintId::of(types::TYPE_COMPLEXITY),
-    LintId::of(types::VEC_BOX),
-    LintId::of(unicode::INVISIBLE_CHARACTERS),
-    LintId::of(uninit_vec::UNINIT_VEC),
-    LintId::of(unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
-    LintId::of(unit_types::LET_UNIT_VALUE),
-    LintId::of(unit_types::UNIT_ARG),
-    LintId::of(unit_types::UNIT_CMP),
-    LintId::of(unnamed_address::FN_ADDRESS_COMPARISONS),
-    LintId::of(unnamed_address::VTABLE_ADDRESS_COMPARISONS),
-    LintId::of(unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS),
-    LintId::of(unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
-    LintId::of(unused_io_amount::UNUSED_IO_AMOUNT),
-    LintId::of(unused_unit::UNUSED_UNIT),
-    LintId::of(unwrap::PANICKING_UNWRAP),
-    LintId::of(unwrap::UNNECESSARY_UNWRAP),
-    LintId::of(upper_case_acronyms::UPPER_CASE_ACRONYMS),
-    LintId::of(useless_conversion::USELESS_CONVERSION),
-    LintId::of(vec::USELESS_VEC),
-    LintId::of(vec_init_then_push::VEC_INIT_THEN_PUSH),
-    LintId::of(write::PRINTLN_EMPTY_STRING),
-    LintId::of(write::PRINT_LITERAL),
-    LintId::of(write::PRINT_WITH_NEWLINE),
-    LintId::of(write::WRITELN_EMPTY_STRING),
-    LintId::of(write::WRITE_LITERAL),
-    LintId::of(write::WRITE_WITH_NEWLINE),
-    LintId::of(zero_div_zero::ZERO_DIVIDED_BY_ZERO),
-])
diff --git a/clippy_lints/src/lib.register_cargo.rs b/clippy_lints/src/lib.register_cargo.rs
deleted file mode 100644
index c890523fe5a..00000000000
--- a/clippy_lints/src/lib.register_cargo.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::cargo", Some("clippy_cargo"), vec![
-    LintId::of(cargo::CARGO_COMMON_METADATA),
-    LintId::of(cargo::MULTIPLE_CRATE_VERSIONS),
-    LintId::of(cargo::NEGATIVE_FEATURE_NAMES),
-    LintId::of(cargo::REDUNDANT_FEATURE_NAMES),
-    LintId::of(cargo::WILDCARD_DEPENDENCIES),
-])
diff --git a/clippy_lints/src/lib.register_complexity.rs b/clippy_lints/src/lib.register_complexity.rs
deleted file mode 100644
index 8be9dc4baf1..00000000000
--- a/clippy_lints/src/lib.register_complexity.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec![
-    LintId::of(attrs::DEPRECATED_CFG_ATTR),
-    LintId::of(booleans::NONMINIMAL_BOOL),
-    LintId::of(borrow_deref_ref::BORROW_DEREF_REF),
-    LintId::of(casts::CHAR_LIT_AS_U8),
-    LintId::of(casts::UNNECESSARY_CAST),
-    LintId::of(dereference::EXPLICIT_AUTO_DEREF),
-    LintId::of(derivable_impls::DERIVABLE_IMPLS),
-    LintId::of(double_parens::DOUBLE_PARENS),
-    LintId::of(explicit_write::EXPLICIT_WRITE),
-    LintId::of(format::USELESS_FORMAT),
-    LintId::of(format_args::UNUSED_FORMAT_SPECS),
-    LintId::of(functions::TOO_MANY_ARGUMENTS),
-    LintId::of(int_plus_one::INT_PLUS_ONE),
-    LintId::of(lifetimes::EXTRA_UNUSED_LIFETIMES),
-    LintId::of(lifetimes::NEEDLESS_LIFETIMES),
-    LintId::of(loops::EXPLICIT_COUNTER_LOOP),
-    LintId::of(loops::MANUAL_FIND),
-    LintId::of(loops::MANUAL_FLATTEN),
-    LintId::of(loops::SINGLE_ELEMENT_LOOP),
-    LintId::of(loops::WHILE_LET_LOOP),
-    LintId::of(manual_clamp::MANUAL_CLAMP),
-    LintId::of(manual_rem_euclid::MANUAL_REM_EUCLID),
-    LintId::of(manual_strip::MANUAL_STRIP),
-    LintId::of(map_unit_fn::OPTION_MAP_UNIT_FN),
-    LintId::of(map_unit_fn::RESULT_MAP_UNIT_FN),
-    LintId::of(matches::MANUAL_FILTER),
-    LintId::of(matches::MANUAL_UNWRAP_OR),
-    LintId::of(matches::MATCH_AS_REF),
-    LintId::of(matches::MATCH_SINGLE_BINDING),
-    LintId::of(matches::NEEDLESS_MATCH),
-    LintId::of(matches::WILDCARD_IN_OR_PATTERNS),
-    LintId::of(methods::BIND_INSTEAD_OF_MAP),
-    LintId::of(methods::BYTES_COUNT_TO_LEN),
-    LintId::of(methods::CLONE_ON_COPY),
-    LintId::of(methods::FILTER_MAP_IDENTITY),
-    LintId::of(methods::FILTER_NEXT),
-    LintId::of(methods::FLAT_MAP_IDENTITY),
-    LintId::of(methods::GET_LAST_WITH_LEN),
-    LintId::of(methods::INSPECT_FOR_EACH),
-    LintId::of(methods::ITER_COUNT),
-    LintId::of(methods::ITER_KV_MAP),
-    LintId::of(methods::MANUAL_FILTER_MAP),
-    LintId::of(methods::MANUAL_FIND_MAP),
-    LintId::of(methods::MANUAL_SPLIT_ONCE),
-    LintId::of(methods::MAP_FLATTEN),
-    LintId::of(methods::MAP_IDENTITY),
-    LintId::of(methods::NEEDLESS_OPTION_AS_DEREF),
-    LintId::of(methods::NEEDLESS_OPTION_TAKE),
-    LintId::of(methods::NEEDLESS_SPLITN),
-    LintId::of(methods::OPTION_AS_REF_DEREF),
-    LintId::of(methods::OPTION_FILTER_MAP),
-    LintId::of(methods::OR_THEN_UNWRAP),
-    LintId::of(methods::RANGE_ZIP_WITH_LEN),
-    LintId::of(methods::REPEAT_ONCE),
-    LintId::of(methods::SEARCH_IS_SOME),
-    LintId::of(methods::SKIP_WHILE_NEXT),
-    LintId::of(methods::UNNECESSARY_FILTER_MAP),
-    LintId::of(methods::UNNECESSARY_FIND_MAP),
-    LintId::of(methods::UNNECESSARY_SORT_BY),
-    LintId::of(methods::USELESS_ASREF),
-    LintId::of(misc::SHORT_CIRCUIT_STATEMENT),
-    LintId::of(misc_early::UNNEEDED_WILDCARD_PATTERN),
-    LintId::of(misc_early::ZERO_PREFIXED_LITERAL),
-    LintId::of(mixed_read_write_in_expression::DIVERGING_SUB_EXPRESSION),
-    LintId::of(needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE),
-    LintId::of(needless_bool::BOOL_COMPARISON),
-    LintId::of(needless_bool::NEEDLESS_BOOL),
-    LintId::of(needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
-    LintId::of(needless_question_mark::NEEDLESS_QUESTION_MARK),
-    LintId::of(needless_update::NEEDLESS_UPDATE),
-    LintId::of(neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
-    LintId::of(no_effect::NO_EFFECT),
-    LintId::of(no_effect::UNNECESSARY_OPERATION),
-    LintId::of(only_used_in_recursion::ONLY_USED_IN_RECURSION),
-    LintId::of(operators::DOUBLE_COMPARISONS),
-    LintId::of(operators::DURATION_SUBSEC),
-    LintId::of(operators::IDENTITY_OP),
-    LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
-    LintId::of(partialeq_ne_impl::PARTIALEQ_NE_IMPL),
-    LintId::of(precedence::PRECEDENCE),
-    LintId::of(ptr_offset_with_cast::PTR_OFFSET_WITH_CAST),
-    LintId::of(redundant_closure_call::REDUNDANT_CLOSURE_CALL),
-    LintId::of(redundant_slicing::REDUNDANT_SLICING),
-    LintId::of(reference::DEREF_ADDROF),
-    LintId::of(strings::STRING_FROM_UTF8_AS_BYTES),
-    LintId::of(strlen_on_c_strings::STRLEN_ON_C_STRINGS),
-    LintId::of(swap::MANUAL_SWAP),
-    LintId::of(temporary_assignment::TEMPORARY_ASSIGNMENT),
-    LintId::of(transmute::CROSSPOINTER_TRANSMUTE),
-    LintId::of(transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS),
-    LintId::of(transmute::TRANSMUTE_BYTES_TO_STR),
-    LintId::of(transmute::TRANSMUTE_FLOAT_TO_INT),
-    LintId::of(transmute::TRANSMUTE_INT_TO_BOOL),
-    LintId::of(transmute::TRANSMUTE_INT_TO_CHAR),
-    LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT),
-    LintId::of(transmute::TRANSMUTE_NUM_TO_BYTES),
-    LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
-    LintId::of(transmute::USELESS_TRANSMUTE),
-    LintId::of(types::BORROWED_BOX),
-    LintId::of(types::TYPE_COMPLEXITY),
-    LintId::of(types::VEC_BOX),
-    LintId::of(unit_types::UNIT_ARG),
-    LintId::of(unwrap::UNNECESSARY_UNWRAP),
-    LintId::of(useless_conversion::USELESS_CONVERSION),
-    LintId::of(zero_div_zero::ZERO_DIVIDED_BY_ZERO),
-])
diff --git a/clippy_lints/src/lib.register_correctness.rs b/clippy_lints/src/lib.register_correctness.rs
deleted file mode 100644
index bb94037ec2e..00000000000
--- a/clippy_lints/src/lib.register_correctness.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::correctness", Some("clippy_correctness"), vec![
-    LintId::of(approx_const::APPROX_CONSTANT),
-    LintId::of(async_yields_async::ASYNC_YIELDS_ASYNC),
-    LintId::of(attrs::DEPRECATED_SEMVER),
-    LintId::of(attrs::MISMATCHED_TARGET_OS),
-    LintId::of(attrs::USELESS_ATTRIBUTE),
-    LintId::of(booleans::OVERLY_COMPLEX_BOOL_EXPR),
-    LintId::of(casts::CAST_REF_TO_MUT),
-    LintId::of(casts::CAST_SLICE_DIFFERENT_SIZES),
-    LintId::of(copies::IFS_SAME_COND),
-    LintId::of(copies::IF_SAME_THEN_ELSE),
-    LintId::of(derive::DERIVE_HASH_XOR_EQ),
-    LintId::of(derive::DERIVE_ORD_XOR_PARTIAL_ORD),
-    LintId::of(drop_forget_ref::DROP_COPY),
-    LintId::of(drop_forget_ref::DROP_REF),
-    LintId::of(drop_forget_ref::FORGET_COPY),
-    LintId::of(drop_forget_ref::FORGET_REF),
-    LintId::of(drop_forget_ref::UNDROPPED_MANUALLY_DROPS),
-    LintId::of(enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT),
-    LintId::of(format_impl::RECURSIVE_FORMAT_IMPL),
-    LintId::of(formatting::POSSIBLE_MISSING_COMMA),
-    LintId::of(functions::NOT_UNSAFE_PTR_ARG_DEREF),
-    LintId::of(if_let_mutex::IF_LET_MUTEX),
-    LintId::of(indexing_slicing::OUT_OF_BOUNDS_INDEXING),
-    LintId::of(infinite_iter::INFINITE_ITER),
-    LintId::of(inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY),
-    LintId::of(inline_fn_without_body::INLINE_FN_WITHOUT_BODY),
-    LintId::of(invalid_utf8_in_unchecked::INVALID_UTF8_IN_UNCHECKED),
-    LintId::of(let_underscore::LET_UNDERSCORE_LOCK),
-    LintId::of(literal_representation::MISTYPED_LITERAL_SUFFIXES),
-    LintId::of(loops::ITER_NEXT_LOOP),
-    LintId::of(loops::NEVER_LOOP),
-    LintId::of(loops::WHILE_IMMUTABLE_CONDITION),
-    LintId::of(matches::MATCH_STR_CASE_MISMATCH),
-    LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
-    LintId::of(methods::CLONE_DOUBLE_REF),
-    LintId::of(methods::ITERATOR_STEP_BY_ZERO),
-    LintId::of(methods::NONSENSICAL_OPEN_OPTIONS),
-    LintId::of(methods::SUSPICIOUS_SPLITN),
-    LintId::of(methods::UNINIT_ASSUMED_INIT),
-    LintId::of(methods::UNIT_HASH),
-    LintId::of(methods::VEC_RESIZE_TO_ZERO),
-    LintId::of(methods::ZST_OFFSET),
-    LintId::of(minmax::MIN_MAX),
-    LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
-    LintId::of(operators::ABSURD_EXTREME_COMPARISONS),
-    LintId::of(operators::BAD_BIT_MASK),
-    LintId::of(operators::CMP_NAN),
-    LintId::of(operators::EQ_OP),
-    LintId::of(operators::ERASING_OP),
-    LintId::of(operators::INEFFECTIVE_BIT_MASK),
-    LintId::of(operators::MODULO_ONE),
-    LintId::of(operators::SELF_ASSIGNMENT),
-    LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),
-    LintId::of(ptr::INVALID_NULL_PTR_USAGE),
-    LintId::of(ptr::MUT_FROM_REF),
-    LintId::of(ranges::REVERSED_EMPTY_RANGES),
-    LintId::of(read_zero_byte_vec::READ_ZERO_BYTE_VEC),
-    LintId::of(regex::INVALID_REGEX),
-    LintId::of(serde_api::SERDE_API_MISUSE),
-    LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
-    LintId::of(swap::ALMOST_SWAPPED),
-    LintId::of(transmute::TRANSMUTING_NULL),
-    LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
-    LintId::of(transmute::WRONG_TRANSMUTE),
-    LintId::of(unicode::INVISIBLE_CHARACTERS),
-    LintId::of(uninit_vec::UNINIT_VEC),
-    LintId::of(unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
-    LintId::of(unit_types::UNIT_CMP),
-    LintId::of(unnamed_address::FN_ADDRESS_COMPARISONS),
-    LintId::of(unnamed_address::VTABLE_ADDRESS_COMPARISONS),
-    LintId::of(unused_io_amount::UNUSED_IO_AMOUNT),
-    LintId::of(unwrap::PANICKING_UNWRAP),
-])
diff --git a/clippy_lints/src/lib.register_internal.rs b/clippy_lints/src/lib.register_internal.rs
deleted file mode 100644
index 40c94c6e8d3..00000000000
--- a/clippy_lints/src/lib.register_internal.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::internal", Some("clippy_internal"), vec![
-    LintId::of(utils::internal_lints::clippy_lints_internal::CLIPPY_LINTS_INTERNAL),
-    LintId::of(utils::internal_lints::collapsible_calls::COLLAPSIBLE_SPAN_LINT_CALLS),
-    LintId::of(utils::internal_lints::compiler_lint_functions::COMPILER_LINT_FUNCTIONS),
-    LintId::of(utils::internal_lints::if_chain_style::IF_CHAIN_STYLE),
-    LintId::of(utils::internal_lints::interning_defined_symbol::INTERNING_DEFINED_SYMBOL),
-    LintId::of(utils::internal_lints::interning_defined_symbol::UNNECESSARY_SYMBOL_STR),
-    LintId::of(utils::internal_lints::invalid_paths::INVALID_PATHS),
-    LintId::of(utils::internal_lints::lint_without_lint_pass::DEFAULT_DEPRECATION_REASON),
-    LintId::of(utils::internal_lints::lint_without_lint_pass::DEFAULT_LINT),
-    LintId::of(utils::internal_lints::lint_without_lint_pass::INVALID_CLIPPY_VERSION_ATTRIBUTE),
-    LintId::of(utils::internal_lints::lint_without_lint_pass::LINT_WITHOUT_LINT_PASS),
-    LintId::of(utils::internal_lints::lint_without_lint_pass::MISSING_CLIPPY_VERSION_ATTRIBUTE),
-    LintId::of(utils::internal_lints::msrv_attr_impl::MISSING_MSRV_ATTR_IMPL),
-    LintId::of(utils::internal_lints::outer_expn_data_pass::OUTER_EXPN_EXPN_DATA),
-    LintId::of(utils::internal_lints::produce_ice::PRODUCE_ICE),
-    LintId::of(utils::internal_lints::unnecessary_def_path::UNNECESSARY_DEF_PATH),
-])
diff --git a/clippy_lints/src/lib.register_lints.rs b/clippy_lints/src/lib.register_lints.rs
deleted file mode 100644
index 800e3a87671..00000000000
--- a/clippy_lints/src/lib.register_lints.rs
+++ /dev/null
@@ -1,620 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_lints(&[
-    #[cfg(feature = "internal")]
-    utils::internal_lints::clippy_lints_internal::CLIPPY_LINTS_INTERNAL,
-    #[cfg(feature = "internal")]
-    utils::internal_lints::collapsible_calls::COLLAPSIBLE_SPAN_LINT_CALLS,
-    #[cfg(feature = "internal")]
-    utils::internal_lints::compiler_lint_functions::COMPILER_LINT_FUNCTIONS,
-    #[cfg(feature = "internal")]
-    utils::internal_lints::if_chain_style::IF_CHAIN_STYLE,
-    #[cfg(feature = "internal")]
-    utils::internal_lints::interning_defined_symbol::INTERNING_DEFINED_SYMBOL,
-    #[cfg(feature = "internal")]
-    utils::internal_lints::interning_defined_symbol::UNNECESSARY_SYMBOL_STR,
-    #[cfg(feature = "internal")]
-    utils::internal_lints::invalid_paths::INVALID_PATHS,
-    #[cfg(feature = "internal")]
-    utils::internal_lints::lint_without_lint_pass::DEFAULT_DEPRECATION_REASON,
-    #[cfg(feature = "internal")]
-    utils::internal_lints::lint_without_lint_pass::DEFAULT_LINT,
-    #[cfg(feature = "internal")]
-    utils::internal_lints::lint_without_lint_pass::INVALID_CLIPPY_VERSION_ATTRIBUTE,
-    #[cfg(feature = "internal")]
-    utils::internal_lints::lint_without_lint_pass::LINT_WITHOUT_LINT_PASS,
-    #[cfg(feature = "internal")]
-    utils::internal_lints::lint_without_lint_pass::MISSING_CLIPPY_VERSION_ATTRIBUTE,
-    #[cfg(feature = "internal")]
-    utils::internal_lints::msrv_attr_impl::MISSING_MSRV_ATTR_IMPL,
-    #[cfg(feature = "internal")]
-    utils::internal_lints::outer_expn_data_pass::OUTER_EXPN_EXPN_DATA,
-    #[cfg(feature = "internal")]
-    utils::internal_lints::produce_ice::PRODUCE_ICE,
-    #[cfg(feature = "internal")]
-    utils::internal_lints::unnecessary_def_path::UNNECESSARY_DEF_PATH,
-    almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE,
-    approx_const::APPROX_CONSTANT,
-    as_conversions::AS_CONVERSIONS,
-    asm_syntax::INLINE_ASM_X86_ATT_SYNTAX,
-    asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX,
-    assertions_on_constants::ASSERTIONS_ON_CONSTANTS,
-    assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES,
-    async_yields_async::ASYNC_YIELDS_ASYNC,
-    attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON,
-    attrs::BLANKET_CLIPPY_RESTRICTION_LINTS,
-    attrs::DEPRECATED_CFG_ATTR,
-    attrs::DEPRECATED_SEMVER,
-    attrs::EMPTY_LINE_AFTER_OUTER_ATTR,
-    attrs::INLINE_ALWAYS,
-    attrs::MISMATCHED_TARGET_OS,
-    attrs::USELESS_ATTRIBUTE,
-    await_holding_invalid::AWAIT_HOLDING_INVALID_TYPE,
-    await_holding_invalid::AWAIT_HOLDING_LOCK,
-    await_holding_invalid::AWAIT_HOLDING_REFCELL_REF,
-    blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS,
-    bool_assert_comparison::BOOL_ASSERT_COMPARISON,
-    bool_to_int_with_if::BOOL_TO_INT_WITH_IF,
-    booleans::NONMINIMAL_BOOL,
-    booleans::OVERLY_COMPLEX_BOOL_EXPR,
-    borrow_deref_ref::BORROW_DEREF_REF,
-    box_default::BOX_DEFAULT,
-    cargo::CARGO_COMMON_METADATA,
-    cargo::MULTIPLE_CRATE_VERSIONS,
-    cargo::NEGATIVE_FEATURE_NAMES,
-    cargo::REDUNDANT_FEATURE_NAMES,
-    cargo::WILDCARD_DEPENDENCIES,
-    casts::AS_PTR_CAST_MUT,
-    casts::AS_UNDERSCORE,
-    casts::BORROW_AS_PTR,
-    casts::CAST_ABS_TO_UNSIGNED,
-    casts::CAST_ENUM_CONSTRUCTOR,
-    casts::CAST_ENUM_TRUNCATION,
-    casts::CAST_LOSSLESS,
-    casts::CAST_NAN_TO_INT,
-    casts::CAST_POSSIBLE_TRUNCATION,
-    casts::CAST_POSSIBLE_WRAP,
-    casts::CAST_PRECISION_LOSS,
-    casts::CAST_PTR_ALIGNMENT,
-    casts::CAST_REF_TO_MUT,
-    casts::CAST_SIGN_LOSS,
-    casts::CAST_SLICE_DIFFERENT_SIZES,
-    casts::CAST_SLICE_FROM_RAW_PARTS,
-    casts::CHAR_LIT_AS_U8,
-    casts::FN_TO_NUMERIC_CAST,
-    casts::FN_TO_NUMERIC_CAST_ANY,
-    casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
-    casts::PTR_AS_PTR,
-    casts::UNNECESSARY_CAST,
-    checked_conversions::CHECKED_CONVERSIONS,
-    cognitive_complexity::COGNITIVE_COMPLEXITY,
-    collapsible_if::COLLAPSIBLE_ELSE_IF,
-    collapsible_if::COLLAPSIBLE_IF,
-    comparison_chain::COMPARISON_CHAIN,
-    copies::BRANCHES_SHARING_CODE,
-    copies::IFS_SAME_COND,
-    copies::IF_SAME_THEN_ELSE,
-    copies::SAME_FUNCTIONS_IN_IF_CONDITION,
-    copy_iterator::COPY_ITERATOR,
-    crate_in_macro_def::CRATE_IN_MACRO_DEF,
-    create_dir::CREATE_DIR,
-    dbg_macro::DBG_MACRO,
-    default::DEFAULT_TRAIT_ACCESS,
-    default::FIELD_REASSIGN_WITH_DEFAULT,
-    default_instead_of_iter_empty::DEFAULT_INSTEAD_OF_ITER_EMPTY,
-    default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK,
-    default_union_representation::DEFAULT_UNION_REPRESENTATION,
-    dereference::EXPLICIT_AUTO_DEREF,
-    dereference::EXPLICIT_DEREF_METHODS,
-    dereference::NEEDLESS_BORROW,
-    dereference::REF_BINDING_TO_REFERENCE,
-    derivable_impls::DERIVABLE_IMPLS,
-    derive::DERIVE_HASH_XOR_EQ,
-    derive::DERIVE_ORD_XOR_PARTIAL_ORD,
-    derive::DERIVE_PARTIAL_EQ_WITHOUT_EQ,
-    derive::EXPL_IMPL_CLONE_ON_COPY,
-    derive::UNSAFE_DERIVE_DESERIALIZE,
-    disallowed_macros::DISALLOWED_MACROS,
-    disallowed_methods::DISALLOWED_METHODS,
-    disallowed_names::DISALLOWED_NAMES,
-    disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS,
-    disallowed_types::DISALLOWED_TYPES,
-    doc::DOC_LINK_WITH_QUOTES,
-    doc::DOC_MARKDOWN,
-    doc::MISSING_ERRORS_DOC,
-    doc::MISSING_PANICS_DOC,
-    doc::MISSING_SAFETY_DOC,
-    doc::NEEDLESS_DOCTEST_MAIN,
-    double_parens::DOUBLE_PARENS,
-    drop_forget_ref::DROP_COPY,
-    drop_forget_ref::DROP_NON_DROP,
-    drop_forget_ref::DROP_REF,
-    drop_forget_ref::FORGET_COPY,
-    drop_forget_ref::FORGET_NON_DROP,
-    drop_forget_ref::FORGET_REF,
-    drop_forget_ref::UNDROPPED_MANUALLY_DROPS,
-    duplicate_mod::DUPLICATE_MOD,
-    else_if_without_else::ELSE_IF_WITHOUT_ELSE,
-    empty_drop::EMPTY_DROP,
-    empty_enum::EMPTY_ENUM,
-    empty_structs_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS,
-    entry::MAP_ENTRY,
-    enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT,
-    enum_variants::ENUM_VARIANT_NAMES,
-    enum_variants::MODULE_INCEPTION,
-    enum_variants::MODULE_NAME_REPETITIONS,
-    equatable_if_let::EQUATABLE_IF_LET,
-    escape::BOXED_LOCAL,
-    eta_reduction::REDUNDANT_CLOSURE,
-    eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS,
-    excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS,
-    excessive_bools::STRUCT_EXCESSIVE_BOOLS,
-    exhaustive_items::EXHAUSTIVE_ENUMS,
-    exhaustive_items::EXHAUSTIVE_STRUCTS,
-    exit::EXIT,
-    explicit_write::EXPLICIT_WRITE,
-    fallible_impl_from::FALLIBLE_IMPL_FROM,
-    float_literal::EXCESSIVE_PRECISION,
-    float_literal::LOSSY_FLOAT_LITERAL,
-    floating_point_arithmetic::IMPRECISE_FLOPS,
-    floating_point_arithmetic::SUBOPTIMAL_FLOPS,
-    format::USELESS_FORMAT,
-    format_args::FORMAT_IN_FORMAT_ARGS,
-    format_args::TO_STRING_IN_FORMAT_ARGS,
-    format_args::UNINLINED_FORMAT_ARGS,
-    format_args::UNUSED_FORMAT_SPECS,
-    format_impl::PRINT_IN_FORMAT_IMPL,
-    format_impl::RECURSIVE_FORMAT_IMPL,
-    format_push_string::FORMAT_PUSH_STRING,
-    formatting::POSSIBLE_MISSING_COMMA,
-    formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING,
-    formatting::SUSPICIOUS_ELSE_FORMATTING,
-    formatting::SUSPICIOUS_UNARY_OP_FORMATTING,
-    from_over_into::FROM_OVER_INTO,
-    from_str_radix_10::FROM_STR_RADIX_10,
-    functions::DOUBLE_MUST_USE,
-    functions::MUST_USE_CANDIDATE,
-    functions::MUST_USE_UNIT,
-    functions::NOT_UNSAFE_PTR_ARG_DEREF,
-    functions::RESULT_LARGE_ERR,
-    functions::RESULT_UNIT_ERR,
-    functions::TOO_MANY_ARGUMENTS,
-    functions::TOO_MANY_LINES,
-    future_not_send::FUTURE_NOT_SEND,
-    if_let_mutex::IF_LET_MUTEX,
-    if_not_else::IF_NOT_ELSE,
-    if_then_some_else_none::IF_THEN_SOME_ELSE_NONE,
-    implicit_hasher::IMPLICIT_HASHER,
-    implicit_return::IMPLICIT_RETURN,
-    implicit_saturating_add::IMPLICIT_SATURATING_ADD,
-    implicit_saturating_sub::IMPLICIT_SATURATING_SUB,
-    inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR,
-    index_refutable_slice::INDEX_REFUTABLE_SLICE,
-    indexing_slicing::INDEXING_SLICING,
-    indexing_slicing::OUT_OF_BOUNDS_INDEXING,
-    infinite_iter::INFINITE_ITER,
-    infinite_iter::MAYBE_INFINITE_ITER,
-    inherent_impl::MULTIPLE_INHERENT_IMPL,
-    inherent_to_string::INHERENT_TO_STRING,
-    inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY,
-    init_numbered_fields::INIT_NUMBERED_FIELDS,
-    inline_fn_without_body::INLINE_FN_WITHOUT_BODY,
-    int_plus_one::INT_PLUS_ONE,
-    invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS,
-    invalid_utf8_in_unchecked::INVALID_UTF8_IN_UNCHECKED,
-    items_after_statements::ITEMS_AFTER_STATEMENTS,
-    iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR,
-    large_const_arrays::LARGE_CONST_ARRAYS,
-    large_enum_variant::LARGE_ENUM_VARIANT,
-    large_include_file::LARGE_INCLUDE_FILE,
-    large_stack_arrays::LARGE_STACK_ARRAYS,
-    len_zero::COMPARISON_TO_EMPTY,
-    len_zero::LEN_WITHOUT_IS_EMPTY,
-    len_zero::LEN_ZERO,
-    let_if_seq::USELESS_LET_IF_SEQ,
-    let_underscore::LET_UNDERSCORE_DROP,
-    let_underscore::LET_UNDERSCORE_LOCK,
-    let_underscore::LET_UNDERSCORE_MUST_USE,
-    lifetimes::EXTRA_UNUSED_LIFETIMES,
-    lifetimes::NEEDLESS_LIFETIMES,
-    literal_representation::DECIMAL_LITERAL_REPRESENTATION,
-    literal_representation::INCONSISTENT_DIGIT_GROUPING,
-    literal_representation::LARGE_DIGIT_GROUPS,
-    literal_representation::MISTYPED_LITERAL_SUFFIXES,
-    literal_representation::UNREADABLE_LITERAL,
-    literal_representation::UNUSUAL_BYTE_GROUPINGS,
-    loops::EMPTY_LOOP,
-    loops::EXPLICIT_COUNTER_LOOP,
-    loops::EXPLICIT_INTO_ITER_LOOP,
-    loops::EXPLICIT_ITER_LOOP,
-    loops::FOR_KV_MAP,
-    loops::ITER_NEXT_LOOP,
-    loops::MANUAL_FIND,
-    loops::MANUAL_FLATTEN,
-    loops::MANUAL_MEMCPY,
-    loops::MISSING_SPIN_LOOP,
-    loops::MUT_RANGE_BOUND,
-    loops::NEEDLESS_COLLECT,
-    loops::NEEDLESS_RANGE_LOOP,
-    loops::NEVER_LOOP,
-    loops::SAME_ITEM_PUSH,
-    loops::SINGLE_ELEMENT_LOOP,
-    loops::WHILE_IMMUTABLE_CONDITION,
-    loops::WHILE_LET_LOOP,
-    loops::WHILE_LET_ON_ITERATOR,
-    macro_use::MACRO_USE_IMPORTS,
-    main_recursion::MAIN_RECURSION,
-    manual_assert::MANUAL_ASSERT,
-    manual_async_fn::MANUAL_ASYNC_FN,
-    manual_bits::MANUAL_BITS,
-    manual_clamp::MANUAL_CLAMP,
-    manual_instant_elapsed::MANUAL_INSTANT_ELAPSED,
-    manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE,
-    manual_rem_euclid::MANUAL_REM_EUCLID,
-    manual_retain::MANUAL_RETAIN,
-    manual_string_new::MANUAL_STRING_NEW,
-    manual_strip::MANUAL_STRIP,
-    map_unit_fn::OPTION_MAP_UNIT_FN,
-    map_unit_fn::RESULT_MAP_UNIT_FN,
-    match_result_ok::MATCH_RESULT_OK,
-    matches::COLLAPSIBLE_MATCH,
-    matches::INFALLIBLE_DESTRUCTURING_MATCH,
-    matches::MANUAL_FILTER,
-    matches::MANUAL_MAP,
-    matches::MANUAL_UNWRAP_OR,
-    matches::MATCH_AS_REF,
-    matches::MATCH_BOOL,
-    matches::MATCH_LIKE_MATCHES_MACRO,
-    matches::MATCH_ON_VEC_ITEMS,
-    matches::MATCH_OVERLAPPING_ARM,
-    matches::MATCH_REF_PATS,
-    matches::MATCH_SAME_ARMS,
-    matches::MATCH_SINGLE_BINDING,
-    matches::MATCH_STR_CASE_MISMATCH,
-    matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
-    matches::MATCH_WILD_ERR_ARM,
-    matches::NEEDLESS_MATCH,
-    matches::REDUNDANT_PATTERN_MATCHING,
-    matches::REST_PAT_IN_FULLY_BOUND_STRUCTS,
-    matches::SIGNIFICANT_DROP_IN_SCRUTINEE,
-    matches::SINGLE_MATCH,
-    matches::SINGLE_MATCH_ELSE,
-    matches::TRY_ERR,
-    matches::WILDCARD_ENUM_MATCH_ARM,
-    matches::WILDCARD_IN_OR_PATTERNS,
-    mem_forget::MEM_FORGET,
-    mem_replace::MEM_REPLACE_OPTION_WITH_NONE,
-    mem_replace::MEM_REPLACE_WITH_DEFAULT,
-    mem_replace::MEM_REPLACE_WITH_UNINIT,
-    methods::BIND_INSTEAD_OF_MAP,
-    methods::BYTES_COUNT_TO_LEN,
-    methods::BYTES_NTH,
-    methods::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
-    methods::CHARS_LAST_CMP,
-    methods::CHARS_NEXT_CMP,
-    methods::CLONED_INSTEAD_OF_COPIED,
-    methods::CLONE_DOUBLE_REF,
-    methods::CLONE_ON_COPY,
-    methods::CLONE_ON_REF_PTR,
-    methods::COLLAPSIBLE_STR_REPLACE,
-    methods::ERR_EXPECT,
-    methods::EXPECT_FUN_CALL,
-    methods::EXPECT_USED,
-    methods::EXTEND_WITH_DRAIN,
-    methods::FILETYPE_IS_FILE,
-    methods::FILTER_MAP_IDENTITY,
-    methods::FILTER_MAP_NEXT,
-    methods::FILTER_NEXT,
-    methods::FLAT_MAP_IDENTITY,
-    methods::FLAT_MAP_OPTION,
-    methods::FROM_ITER_INSTEAD_OF_COLLECT,
-    methods::GET_FIRST,
-    methods::GET_LAST_WITH_LEN,
-    methods::GET_UNWRAP,
-    methods::IMPLICIT_CLONE,
-    methods::INEFFICIENT_TO_STRING,
-    methods::INSPECT_FOR_EACH,
-    methods::INTO_ITER_ON_REF,
-    methods::IS_DIGIT_ASCII_RADIX,
-    methods::ITERATOR_STEP_BY_ZERO,
-    methods::ITER_CLONED_COLLECT,
-    methods::ITER_COUNT,
-    methods::ITER_KV_MAP,
-    methods::ITER_NEXT_SLICE,
-    methods::ITER_NTH,
-    methods::ITER_NTH_ZERO,
-    methods::ITER_ON_EMPTY_COLLECTIONS,
-    methods::ITER_ON_SINGLE_ITEMS,
-    methods::ITER_OVEREAGER_CLONED,
-    methods::ITER_SKIP_NEXT,
-    methods::ITER_WITH_DRAIN,
-    methods::MANUAL_FILTER_MAP,
-    methods::MANUAL_FIND_MAP,
-    methods::MANUAL_OK_OR,
-    methods::MANUAL_SATURATING_ARITHMETIC,
-    methods::MANUAL_SPLIT_ONCE,
-    methods::MANUAL_STR_REPEAT,
-    methods::MAP_CLONE,
-    methods::MAP_COLLECT_RESULT_UNIT,
-    methods::MAP_ERR_IGNORE,
-    methods::MAP_FLATTEN,
-    methods::MAP_IDENTITY,
-    methods::MAP_UNWRAP_OR,
-    methods::MUT_MUTEX_LOCK,
-    methods::NAIVE_BYTECOUNT,
-    methods::NEEDLESS_OPTION_AS_DEREF,
-    methods::NEEDLESS_OPTION_TAKE,
-    methods::NEEDLESS_SPLITN,
-    methods::NEW_RET_NO_SELF,
-    methods::NONSENSICAL_OPEN_OPTIONS,
-    methods::NO_EFFECT_REPLACE,
-    methods::OBFUSCATED_IF_ELSE,
-    methods::OK_EXPECT,
-    methods::OPTION_AS_REF_DEREF,
-    methods::OPTION_FILTER_MAP,
-    methods::OPTION_MAP_OR_NONE,
-    methods::OR_FUN_CALL,
-    methods::OR_THEN_UNWRAP,
-    methods::PATH_BUF_PUSH_OVERWRITE,
-    methods::RANGE_ZIP_WITH_LEN,
-    methods::REPEAT_ONCE,
-    methods::RESULT_MAP_OR_INTO_OPTION,
-    methods::SEARCH_IS_SOME,
-    methods::SHOULD_IMPLEMENT_TRAIT,
-    methods::SINGLE_CHAR_ADD_STR,
-    methods::SINGLE_CHAR_PATTERN,
-    methods::SKIP_WHILE_NEXT,
-    methods::STABLE_SORT_PRIMITIVE,
-    methods::STRING_EXTEND_CHARS,
-    methods::SUSPICIOUS_MAP,
-    methods::SUSPICIOUS_SPLITN,
-    methods::SUSPICIOUS_TO_OWNED,
-    methods::UNINIT_ASSUMED_INIT,
-    methods::UNIT_HASH,
-    methods::UNNECESSARY_FILTER_MAP,
-    methods::UNNECESSARY_FIND_MAP,
-    methods::UNNECESSARY_FOLD,
-    methods::UNNECESSARY_JOIN,
-    methods::UNNECESSARY_LAZY_EVALUATIONS,
-    methods::UNNECESSARY_SORT_BY,
-    methods::UNNECESSARY_TO_OWNED,
-    methods::UNWRAP_OR_ELSE_DEFAULT,
-    methods::UNWRAP_USED,
-    methods::USELESS_ASREF,
-    methods::VEC_RESIZE_TO_ZERO,
-    methods::VERBOSE_FILE_READS,
-    methods::WRONG_SELF_CONVENTION,
-    methods::ZST_OFFSET,
-    minmax::MIN_MAX,
-    misc::SHORT_CIRCUIT_STATEMENT,
-    misc::TOPLEVEL_REF_ARG,
-    misc::USED_UNDERSCORE_BINDING,
-    misc::ZERO_PTR,
-    misc_early::BUILTIN_TYPE_SHADOW,
-    misc_early::DOUBLE_NEG,
-    misc_early::DUPLICATE_UNDERSCORE_ARGUMENT,
-    misc_early::MIXED_CASE_HEX_LITERALS,
-    misc_early::REDUNDANT_PATTERN,
-    misc_early::SEPARATED_LITERAL_SUFFIX,
-    misc_early::UNNEEDED_FIELD_PATTERN,
-    misc_early::UNNEEDED_WILDCARD_PATTERN,
-    misc_early::UNSEPARATED_LITERAL_SUFFIX,
-    misc_early::ZERO_PREFIXED_LITERAL,
-    mismatching_type_param_order::MISMATCHING_TYPE_PARAM_ORDER,
-    missing_const_for_fn::MISSING_CONST_FOR_FN,
-    missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS,
-    missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES,
-    missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS,
-    missing_trait_methods::MISSING_TRAIT_METHODS,
-    mixed_read_write_in_expression::DIVERGING_SUB_EXPRESSION,
-    mixed_read_write_in_expression::MIXED_READ_WRITE_IN_EXPRESSION,
-    module_style::MOD_MODULE_FILES,
-    module_style::SELF_NAMED_MODULE_FILES,
-    multi_assignments::MULTI_ASSIGNMENTS,
-    mut_key::MUTABLE_KEY_TYPE,
-    mut_mut::MUT_MUT,
-    mut_reference::UNNECESSARY_MUT_PASSED,
-    mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL,
-    mutex_atomic::MUTEX_ATOMIC,
-    mutex_atomic::MUTEX_INTEGER,
-    needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE,
-    needless_bool::BOOL_COMPARISON,
-    needless_bool::NEEDLESS_BOOL,
-    needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE,
-    needless_continue::NEEDLESS_CONTINUE,
-    needless_for_each::NEEDLESS_FOR_EACH,
-    needless_late_init::NEEDLESS_LATE_INIT,
-    needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS,
-    needless_pass_by_value::NEEDLESS_PASS_BY_VALUE,
-    needless_question_mark::NEEDLESS_QUESTION_MARK,
-    needless_update::NEEDLESS_UPDATE,
-    neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD,
-    neg_multiply::NEG_MULTIPLY,
-    new_without_default::NEW_WITHOUT_DEFAULT,
-    no_effect::NO_EFFECT,
-    no_effect::NO_EFFECT_UNDERSCORE_BINDING,
-    no_effect::UNNECESSARY_OPERATION,
-    non_copy_const::BORROW_INTERIOR_MUTABLE_CONST,
-    non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST,
-    non_expressive_names::JUST_UNDERSCORES_AND_DIGITS,
-    non_expressive_names::MANY_SINGLE_CHAR_NAMES,
-    non_expressive_names::SIMILAR_NAMES,
-    non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS,
-    non_send_fields_in_send_ty::NON_SEND_FIELDS_IN_SEND_TY,
-    nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES,
-    octal_escapes::OCTAL_ESCAPES,
-    only_used_in_recursion::ONLY_USED_IN_RECURSION,
-    operators::ABSURD_EXTREME_COMPARISONS,
-    operators::ARITHMETIC_SIDE_EFFECTS,
-    operators::ASSIGN_OP_PATTERN,
-    operators::BAD_BIT_MASK,
-    operators::CMP_NAN,
-    operators::CMP_OWNED,
-    operators::DOUBLE_COMPARISONS,
-    operators::DURATION_SUBSEC,
-    operators::EQ_OP,
-    operators::ERASING_OP,
-    operators::FLOAT_ARITHMETIC,
-    operators::FLOAT_CMP,
-    operators::FLOAT_CMP_CONST,
-    operators::FLOAT_EQUALITY_WITHOUT_ABS,
-    operators::IDENTITY_OP,
-    operators::INEFFECTIVE_BIT_MASK,
-    operators::INTEGER_ARITHMETIC,
-    operators::INTEGER_DIVISION,
-    operators::MISREFACTORED_ASSIGN_OP,
-    operators::MODULO_ARITHMETIC,
-    operators::MODULO_ONE,
-    operators::NEEDLESS_BITWISE_BOOL,
-    operators::OP_REF,
-    operators::PTR_EQ,
-    operators::SELF_ASSIGNMENT,
-    operators::VERBOSE_BIT_MASK,
-    option_env_unwrap::OPTION_ENV_UNWRAP,
-    option_if_let_else::OPTION_IF_LET_ELSE,
-    overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL,
-    panic_in_result_fn::PANIC_IN_RESULT_FN,
-    panic_unimplemented::PANIC,
-    panic_unimplemented::TODO,
-    panic_unimplemented::UNIMPLEMENTED,
-    panic_unimplemented::UNREACHABLE,
-    partial_pub_fields::PARTIAL_PUB_FIELDS,
-    partialeq_ne_impl::PARTIALEQ_NE_IMPL,
-    partialeq_to_none::PARTIALEQ_TO_NONE,
-    pass_by_ref_or_value::LARGE_TYPES_PASSED_BY_VALUE,
-    pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF,
-    pattern_type_mismatch::PATTERN_TYPE_MISMATCH,
-    precedence::PRECEDENCE,
-    ptr::CMP_NULL,
-    ptr::INVALID_NULL_PTR_USAGE,
-    ptr::MUT_FROM_REF,
-    ptr::PTR_ARG,
-    ptr_offset_with_cast::PTR_OFFSET_WITH_CAST,
-    pub_use::PUB_USE,
-    question_mark::QUESTION_MARK,
-    ranges::MANUAL_RANGE_CONTAINS,
-    ranges::RANGE_MINUS_ONE,
-    ranges::RANGE_PLUS_ONE,
-    ranges::REVERSED_EMPTY_RANGES,
-    rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT,
-    read_zero_byte_vec::READ_ZERO_BYTE_VEC,
-    redundant_clone::REDUNDANT_CLONE,
-    redundant_closure_call::REDUNDANT_CLOSURE_CALL,
-    redundant_else::REDUNDANT_ELSE,
-    redundant_field_names::REDUNDANT_FIELD_NAMES,
-    redundant_pub_crate::REDUNDANT_PUB_CRATE,
-    redundant_slicing::DEREF_BY_SLICING,
-    redundant_slicing::REDUNDANT_SLICING,
-    redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES,
-    ref_option_ref::REF_OPTION_REF,
-    reference::DEREF_ADDROF,
-    regex::INVALID_REGEX,
-    regex::TRIVIAL_REGEX,
-    return_self_not_must_use::RETURN_SELF_NOT_MUST_USE,
-    returns::LET_AND_RETURN,
-    returns::NEEDLESS_RETURN,
-    same_name_method::SAME_NAME_METHOD,
-    self_named_constructors::SELF_NAMED_CONSTRUCTORS,
-    semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED,
-    serde_api::SERDE_API_MISUSE,
-    shadow::SHADOW_REUSE,
-    shadow::SHADOW_SAME,
-    shadow::SHADOW_UNRELATED,
-    single_char_lifetime_names::SINGLE_CHAR_LIFETIME_NAMES,
-    single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS,
-    size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT,
-    slow_vector_initialization::SLOW_VECTOR_INITIALIZATION,
-    std_instead_of_core::ALLOC_INSTEAD_OF_CORE,
-    std_instead_of_core::STD_INSTEAD_OF_ALLOC,
-    std_instead_of_core::STD_INSTEAD_OF_CORE,
-    strings::STRING_ADD,
-    strings::STRING_ADD_ASSIGN,
-    strings::STRING_FROM_UTF8_AS_BYTES,
-    strings::STRING_LIT_AS_BYTES,
-    strings::STRING_SLICE,
-    strings::STRING_TO_STRING,
-    strings::STR_TO_STRING,
-    strings::TRIM_SPLIT_WHITESPACE,
-    strlen_on_c_strings::STRLEN_ON_C_STRINGS,
-    suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS,
-    suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL,
-    suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL,
-    swap::ALMOST_SWAPPED,
-    swap::MANUAL_SWAP,
-    swap_ptr_to_ref::SWAP_PTR_TO_REF,
-    tabs_in_doc_comments::TABS_IN_DOC_COMMENTS,
-    temporary_assignment::TEMPORARY_ASSIGNMENT,
-    to_digit_is_some::TO_DIGIT_IS_SOME,
-    trailing_empty_array::TRAILING_EMPTY_ARRAY,
-    trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS,
-    trait_bounds::TYPE_REPETITION_IN_BOUNDS,
-    transmute::CROSSPOINTER_TRANSMUTE,
-    transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
-    transmute::TRANSMUTE_BYTES_TO_STR,
-    transmute::TRANSMUTE_FLOAT_TO_INT,
-    transmute::TRANSMUTE_INT_TO_BOOL,
-    transmute::TRANSMUTE_INT_TO_CHAR,
-    transmute::TRANSMUTE_INT_TO_FLOAT,
-    transmute::TRANSMUTE_NUM_TO_BYTES,
-    transmute::TRANSMUTE_PTR_TO_PTR,
-    transmute::TRANSMUTE_PTR_TO_REF,
-    transmute::TRANSMUTE_UNDEFINED_REPR,
-    transmute::TRANSMUTING_NULL,
-    transmute::UNSOUND_COLLECTION_TRANSMUTE,
-    transmute::USELESS_TRANSMUTE,
-    transmute::WRONG_TRANSMUTE,
-    types::BORROWED_BOX,
-    types::BOX_COLLECTION,
-    types::LINKEDLIST,
-    types::OPTION_OPTION,
-    types::RC_BUFFER,
-    types::RC_MUTEX,
-    types::REDUNDANT_ALLOCATION,
-    types::TYPE_COMPLEXITY,
-    types::VEC_BOX,
-    undocumented_unsafe_blocks::UNDOCUMENTED_UNSAFE_BLOCKS,
-    unicode::INVISIBLE_CHARACTERS,
-    unicode::NON_ASCII_LITERAL,
-    unicode::UNICODE_NOT_NFC,
-    uninit_vec::UNINIT_VEC,
-    unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD,
-    unit_types::LET_UNIT_VALUE,
-    unit_types::UNIT_ARG,
-    unit_types::UNIT_CMP,
-    unnamed_address::FN_ADDRESS_COMPARISONS,
-    unnamed_address::VTABLE_ADDRESS_COMPARISONS,
-    unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS,
-    unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS,
-    unnecessary_wraps::UNNECESSARY_WRAPS,
-    unnested_or_patterns::UNNESTED_OR_PATTERNS,
-    unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME,
-    unused_async::UNUSED_ASYNC,
-    unused_io_amount::UNUSED_IO_AMOUNT,
-    unused_peekable::UNUSED_PEEKABLE,
-    unused_rounding::UNUSED_ROUNDING,
-    unused_self::UNUSED_SELF,
-    unused_unit::UNUSED_UNIT,
-    unwrap::PANICKING_UNWRAP,
-    unwrap::UNNECESSARY_UNWRAP,
-    unwrap_in_result::UNWRAP_IN_RESULT,
-    upper_case_acronyms::UPPER_CASE_ACRONYMS,
-    use_self::USE_SELF,
-    useless_conversion::USELESS_CONVERSION,
-    vec::USELESS_VEC,
-    vec_init_then_push::VEC_INIT_THEN_PUSH,
-    wildcard_imports::ENUM_GLOB_USE,
-    wildcard_imports::WILDCARD_IMPORTS,
-    write::PRINTLN_EMPTY_STRING,
-    write::PRINT_LITERAL,
-    write::PRINT_STDERR,
-    write::PRINT_STDOUT,
-    write::PRINT_WITH_NEWLINE,
-    write::USE_DEBUG,
-    write::WRITELN_EMPTY_STRING,
-    write::WRITE_LITERAL,
-    write::WRITE_WITH_NEWLINE,
-    zero_div_zero::ZERO_DIVIDED_BY_ZERO,
-    zero_sized_map_values::ZERO_SIZED_MAP_VALUES,
-])
diff --git a/clippy_lints/src/lib.register_nursery.rs b/clippy_lints/src/lib.register_nursery.rs
deleted file mode 100644
index 65616d28d8f..00000000000
--- a/clippy_lints/src/lib.register_nursery.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
-    LintId::of(attrs::EMPTY_LINE_AFTER_OUTER_ATTR),
-    LintId::of(casts::AS_PTR_CAST_MUT),
-    LintId::of(cognitive_complexity::COGNITIVE_COMPLEXITY),
-    LintId::of(copies::BRANCHES_SHARING_CODE),
-    LintId::of(derive::DERIVE_PARTIAL_EQ_WITHOUT_EQ),
-    LintId::of(equatable_if_let::EQUATABLE_IF_LET),
-    LintId::of(fallible_impl_from::FALLIBLE_IMPL_FROM),
-    LintId::of(floating_point_arithmetic::IMPRECISE_FLOPS),
-    LintId::of(floating_point_arithmetic::SUBOPTIMAL_FLOPS),
-    LintId::of(future_not_send::FUTURE_NOT_SEND),
-    LintId::of(index_refutable_slice::INDEX_REFUTABLE_SLICE),
-    LintId::of(let_if_seq::USELESS_LET_IF_SEQ),
-    LintId::of(matches::SIGNIFICANT_DROP_IN_SCRUTINEE),
-    LintId::of(methods::ITER_ON_EMPTY_COLLECTIONS),
-    LintId::of(methods::ITER_ON_SINGLE_ITEMS),
-    LintId::of(methods::ITER_WITH_DRAIN),
-    LintId::of(methods::PATH_BUF_PUSH_OVERWRITE),
-    LintId::of(missing_const_for_fn::MISSING_CONST_FOR_FN),
-    LintId::of(mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL),
-    LintId::of(mutex_atomic::MUTEX_ATOMIC),
-    LintId::of(mutex_atomic::MUTEX_INTEGER),
-    LintId::of(non_send_fields_in_send_ty::NON_SEND_FIELDS_IN_SEND_TY),
-    LintId::of(nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES),
-    LintId::of(option_if_let_else::OPTION_IF_LET_ELSE),
-    LintId::of(redundant_pub_crate::REDUNDANT_PUB_CRATE),
-    LintId::of(regex::TRIVIAL_REGEX),
-    LintId::of(strings::STRING_LIT_AS_BYTES),
-    LintId::of(suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS),
-    LintId::of(trailing_empty_array::TRAILING_EMPTY_ARRAY),
-    LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR),
-    LintId::of(unused_peekable::UNUSED_PEEKABLE),
-    LintId::of(unused_rounding::UNUSED_ROUNDING),
-    LintId::of(use_self::USE_SELF),
-])
diff --git a/clippy_lints/src/lib.register_pedantic.rs b/clippy_lints/src/lib.register_pedantic.rs
deleted file mode 100644
index 44e969585b5..00000000000
--- a/clippy_lints/src/lib.register_pedantic.rs
+++ /dev/null
@@ -1,104 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
-    LintId::of(attrs::INLINE_ALWAYS),
-    LintId::of(casts::BORROW_AS_PTR),
-    LintId::of(casts::CAST_LOSSLESS),
-    LintId::of(casts::CAST_POSSIBLE_TRUNCATION),
-    LintId::of(casts::CAST_POSSIBLE_WRAP),
-    LintId::of(casts::CAST_PRECISION_LOSS),
-    LintId::of(casts::CAST_PTR_ALIGNMENT),
-    LintId::of(casts::CAST_SIGN_LOSS),
-    LintId::of(casts::PTR_AS_PTR),
-    LintId::of(checked_conversions::CHECKED_CONVERSIONS),
-    LintId::of(copies::SAME_FUNCTIONS_IN_IF_CONDITION),
-    LintId::of(copy_iterator::COPY_ITERATOR),
-    LintId::of(default::DEFAULT_TRAIT_ACCESS),
-    LintId::of(dereference::EXPLICIT_DEREF_METHODS),
-    LintId::of(dereference::REF_BINDING_TO_REFERENCE),
-    LintId::of(derive::EXPL_IMPL_CLONE_ON_COPY),
-    LintId::of(derive::UNSAFE_DERIVE_DESERIALIZE),
-    LintId::of(doc::DOC_LINK_WITH_QUOTES),
-    LintId::of(doc::DOC_MARKDOWN),
-    LintId::of(doc::MISSING_ERRORS_DOC),
-    LintId::of(doc::MISSING_PANICS_DOC),
-    LintId::of(empty_enum::EMPTY_ENUM),
-    LintId::of(enum_variants::MODULE_NAME_REPETITIONS),
-    LintId::of(eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS),
-    LintId::of(excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS),
-    LintId::of(excessive_bools::STRUCT_EXCESSIVE_BOOLS),
-    LintId::of(format_args::UNINLINED_FORMAT_ARGS),
-    LintId::of(functions::MUST_USE_CANDIDATE),
-    LintId::of(functions::TOO_MANY_LINES),
-    LintId::of(if_not_else::IF_NOT_ELSE),
-    LintId::of(implicit_hasher::IMPLICIT_HASHER),
-    LintId::of(inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR),
-    LintId::of(infinite_iter::MAYBE_INFINITE_ITER),
-    LintId::of(invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS),
-    LintId::of(items_after_statements::ITEMS_AFTER_STATEMENTS),
-    LintId::of(iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR),
-    LintId::of(large_stack_arrays::LARGE_STACK_ARRAYS),
-    LintId::of(let_underscore::LET_UNDERSCORE_DROP),
-    LintId::of(literal_representation::LARGE_DIGIT_GROUPS),
-    LintId::of(literal_representation::UNREADABLE_LITERAL),
-    LintId::of(loops::EXPLICIT_INTO_ITER_LOOP),
-    LintId::of(loops::EXPLICIT_ITER_LOOP),
-    LintId::of(macro_use::MACRO_USE_IMPORTS),
-    LintId::of(manual_assert::MANUAL_ASSERT),
-    LintId::of(manual_instant_elapsed::MANUAL_INSTANT_ELAPSED),
-    LintId::of(manual_string_new::MANUAL_STRING_NEW),
-    LintId::of(matches::MATCH_BOOL),
-    LintId::of(matches::MATCH_ON_VEC_ITEMS),
-    LintId::of(matches::MATCH_SAME_ARMS),
-    LintId::of(matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS),
-    LintId::of(matches::MATCH_WILD_ERR_ARM),
-    LintId::of(matches::SINGLE_MATCH_ELSE),
-    LintId::of(methods::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS),
-    LintId::of(methods::CLONED_INSTEAD_OF_COPIED),
-    LintId::of(methods::FILTER_MAP_NEXT),
-    LintId::of(methods::FLAT_MAP_OPTION),
-    LintId::of(methods::FROM_ITER_INSTEAD_OF_COLLECT),
-    LintId::of(methods::IMPLICIT_CLONE),
-    LintId::of(methods::INEFFICIENT_TO_STRING),
-    LintId::of(methods::MANUAL_OK_OR),
-    LintId::of(methods::MAP_UNWRAP_OR),
-    LintId::of(methods::NAIVE_BYTECOUNT),
-    LintId::of(methods::STABLE_SORT_PRIMITIVE),
-    LintId::of(methods::UNNECESSARY_JOIN),
-    LintId::of(misc::USED_UNDERSCORE_BINDING),
-    LintId::of(mismatching_type_param_order::MISMATCHING_TYPE_PARAM_ORDER),
-    LintId::of(mut_mut::MUT_MUT),
-    LintId::of(needless_continue::NEEDLESS_CONTINUE),
-    LintId::of(needless_for_each::NEEDLESS_FOR_EACH),
-    LintId::of(needless_pass_by_value::NEEDLESS_PASS_BY_VALUE),
-    LintId::of(no_effect::NO_EFFECT_UNDERSCORE_BINDING),
-    LintId::of(non_expressive_names::MANY_SINGLE_CHAR_NAMES),
-    LintId::of(non_expressive_names::SIMILAR_NAMES),
-    LintId::of(operators::FLOAT_CMP),
-    LintId::of(operators::NEEDLESS_BITWISE_BOOL),
-    LintId::of(operators::VERBOSE_BIT_MASK),
-    LintId::of(pass_by_ref_or_value::LARGE_TYPES_PASSED_BY_VALUE),
-    LintId::of(pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF),
-    LintId::of(ranges::RANGE_MINUS_ONE),
-    LintId::of(ranges::RANGE_PLUS_ONE),
-    LintId::of(redundant_else::REDUNDANT_ELSE),
-    LintId::of(ref_option_ref::REF_OPTION_REF),
-    LintId::of(return_self_not_must_use::RETURN_SELF_NOT_MUST_USE),
-    LintId::of(semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED),
-    LintId::of(strings::STRING_ADD_ASSIGN),
-    LintId::of(trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS),
-    LintId::of(trait_bounds::TYPE_REPETITION_IN_BOUNDS),
-    LintId::of(transmute::TRANSMUTE_PTR_TO_PTR),
-    LintId::of(types::LINKEDLIST),
-    LintId::of(types::OPTION_OPTION),
-    LintId::of(unicode::UNICODE_NOT_NFC),
-    LintId::of(unnecessary_wraps::UNNECESSARY_WRAPS),
-    LintId::of(unnested_or_patterns::UNNESTED_OR_PATTERNS),
-    LintId::of(unused_async::UNUSED_ASYNC),
-    LintId::of(unused_self::UNUSED_SELF),
-    LintId::of(wildcard_imports::ENUM_GLOB_USE),
-    LintId::of(wildcard_imports::WILDCARD_IMPORTS),
-    LintId::of(zero_sized_map_values::ZERO_SIZED_MAP_VALUES),
-])
diff --git a/clippy_lints/src/lib.register_perf.rs b/clippy_lints/src/lib.register_perf.rs
deleted file mode 100644
index 8e927470e02..00000000000
--- a/clippy_lints/src/lib.register_perf.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::perf", Some("clippy_perf"), vec![
-    LintId::of(box_default::BOX_DEFAULT),
-    LintId::of(entry::MAP_ENTRY),
-    LintId::of(escape::BOXED_LOCAL),
-    LintId::of(format_args::FORMAT_IN_FORMAT_ARGS),
-    LintId::of(format_args::TO_STRING_IN_FORMAT_ARGS),
-    LintId::of(functions::RESULT_LARGE_ERR),
-    LintId::of(large_const_arrays::LARGE_CONST_ARRAYS),
-    LintId::of(large_enum_variant::LARGE_ENUM_VARIANT),
-    LintId::of(loops::MANUAL_MEMCPY),
-    LintId::of(loops::MISSING_SPIN_LOOP),
-    LintId::of(loops::NEEDLESS_COLLECT),
-    LintId::of(manual_retain::MANUAL_RETAIN),
-    LintId::of(methods::COLLAPSIBLE_STR_REPLACE),
-    LintId::of(methods::EXPECT_FUN_CALL),
-    LintId::of(methods::EXTEND_WITH_DRAIN),
-    LintId::of(methods::ITER_NTH),
-    LintId::of(methods::ITER_OVEREAGER_CLONED),
-    LintId::of(methods::MANUAL_STR_REPEAT),
-    LintId::of(methods::OR_FUN_CALL),
-    LintId::of(methods::SINGLE_CHAR_PATTERN),
-    LintId::of(methods::UNNECESSARY_TO_OWNED),
-    LintId::of(operators::CMP_OWNED),
-    LintId::of(redundant_clone::REDUNDANT_CLONE),
-    LintId::of(slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
-    LintId::of(types::BOX_COLLECTION),
-    LintId::of(types::REDUNDANT_ALLOCATION),
-    LintId::of(vec::USELESS_VEC),
-    LintId::of(vec_init_then_push::VEC_INIT_THEN_PUSH),
-])
diff --git a/clippy_lints/src/lib.register_restriction.rs b/clippy_lints/src/lib.register_restriction.rs
deleted file mode 100644
index f62d57af5b4..00000000000
--- a/clippy_lints/src/lib.register_restriction.rs
+++ /dev/null
@@ -1,90 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
-    LintId::of(as_conversions::AS_CONVERSIONS),
-    LintId::of(asm_syntax::INLINE_ASM_X86_ATT_SYNTAX),
-    LintId::of(asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX),
-    LintId::of(assertions_on_result_states::ASSERTIONS_ON_RESULT_STATES),
-    LintId::of(attrs::ALLOW_ATTRIBUTES_WITHOUT_REASON),
-    LintId::of(casts::AS_UNDERSCORE),
-    LintId::of(casts::FN_TO_NUMERIC_CAST_ANY),
-    LintId::of(create_dir::CREATE_DIR),
-    LintId::of(dbg_macro::DBG_MACRO),
-    LintId::of(default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK),
-    LintId::of(default_union_representation::DEFAULT_UNION_REPRESENTATION),
-    LintId::of(disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS),
-    LintId::of(else_if_without_else::ELSE_IF_WITHOUT_ELSE),
-    LintId::of(empty_drop::EMPTY_DROP),
-    LintId::of(empty_structs_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS),
-    LintId::of(exhaustive_items::EXHAUSTIVE_ENUMS),
-    LintId::of(exhaustive_items::EXHAUSTIVE_STRUCTS),
-    LintId::of(exit::EXIT),
-    LintId::of(float_literal::LOSSY_FLOAT_LITERAL),
-    LintId::of(format_push_string::FORMAT_PUSH_STRING),
-    LintId::of(if_then_some_else_none::IF_THEN_SOME_ELSE_NONE),
-    LintId::of(implicit_return::IMPLICIT_RETURN),
-    LintId::of(indexing_slicing::INDEXING_SLICING),
-    LintId::of(inherent_impl::MULTIPLE_INHERENT_IMPL),
-    LintId::of(large_include_file::LARGE_INCLUDE_FILE),
-    LintId::of(let_underscore::LET_UNDERSCORE_MUST_USE),
-    LintId::of(literal_representation::DECIMAL_LITERAL_REPRESENTATION),
-    LintId::of(matches::REST_PAT_IN_FULLY_BOUND_STRUCTS),
-    LintId::of(matches::TRY_ERR),
-    LintId::of(matches::WILDCARD_ENUM_MATCH_ARM),
-    LintId::of(mem_forget::MEM_FORGET),
-    LintId::of(methods::CLONE_ON_REF_PTR),
-    LintId::of(methods::EXPECT_USED),
-    LintId::of(methods::FILETYPE_IS_FILE),
-    LintId::of(methods::GET_UNWRAP),
-    LintId::of(methods::MAP_ERR_IGNORE),
-    LintId::of(methods::UNWRAP_USED),
-    LintId::of(methods::VERBOSE_FILE_READS),
-    LintId::of(misc_early::SEPARATED_LITERAL_SUFFIX),
-    LintId::of(misc_early::UNNEEDED_FIELD_PATTERN),
-    LintId::of(misc_early::UNSEPARATED_LITERAL_SUFFIX),
-    LintId::of(missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS),
-    LintId::of(missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES),
-    LintId::of(missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS),
-    LintId::of(missing_trait_methods::MISSING_TRAIT_METHODS),
-    LintId::of(mixed_read_write_in_expression::MIXED_READ_WRITE_IN_EXPRESSION),
-    LintId::of(module_style::MOD_MODULE_FILES),
-    LintId::of(module_style::SELF_NAMED_MODULE_FILES),
-    LintId::of(operators::ARITHMETIC_SIDE_EFFECTS),
-    LintId::of(operators::FLOAT_ARITHMETIC),
-    LintId::of(operators::FLOAT_CMP_CONST),
-    LintId::of(operators::INTEGER_ARITHMETIC),
-    LintId::of(operators::INTEGER_DIVISION),
-    LintId::of(operators::MODULO_ARITHMETIC),
-    LintId::of(panic_in_result_fn::PANIC_IN_RESULT_FN),
-    LintId::of(panic_unimplemented::PANIC),
-    LintId::of(panic_unimplemented::TODO),
-    LintId::of(panic_unimplemented::UNIMPLEMENTED),
-    LintId::of(panic_unimplemented::UNREACHABLE),
-    LintId::of(partial_pub_fields::PARTIAL_PUB_FIELDS),
-    LintId::of(pattern_type_mismatch::PATTERN_TYPE_MISMATCH),
-    LintId::of(pub_use::PUB_USE),
-    LintId::of(redundant_slicing::DEREF_BY_SLICING),
-    LintId::of(same_name_method::SAME_NAME_METHOD),
-    LintId::of(shadow::SHADOW_REUSE),
-    LintId::of(shadow::SHADOW_SAME),
-    LintId::of(shadow::SHADOW_UNRELATED),
-    LintId::of(single_char_lifetime_names::SINGLE_CHAR_LIFETIME_NAMES),
-    LintId::of(std_instead_of_core::ALLOC_INSTEAD_OF_CORE),
-    LintId::of(std_instead_of_core::STD_INSTEAD_OF_ALLOC),
-    LintId::of(std_instead_of_core::STD_INSTEAD_OF_CORE),
-    LintId::of(strings::STRING_ADD),
-    LintId::of(strings::STRING_SLICE),
-    LintId::of(strings::STRING_TO_STRING),
-    LintId::of(strings::STR_TO_STRING),
-    LintId::of(types::RC_BUFFER),
-    LintId::of(types::RC_MUTEX),
-    LintId::of(undocumented_unsafe_blocks::UNDOCUMENTED_UNSAFE_BLOCKS),
-    LintId::of(unicode::NON_ASCII_LITERAL),
-    LintId::of(unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS),
-    LintId::of(unwrap_in_result::UNWRAP_IN_RESULT),
-    LintId::of(write::PRINT_STDERR),
-    LintId::of(write::PRINT_STDOUT),
-    LintId::of(write::USE_DEBUG),
-])
diff --git a/clippy_lints/src/lib.register_style.rs b/clippy_lints/src/lib.register_style.rs
deleted file mode 100644
index 3312f564855..00000000000
--- a/clippy_lints/src/lib.register_style.rs
+++ /dev/null
@@ -1,131 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::style", Some("clippy_style"), vec![
-    LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
-    LintId::of(blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
-    LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
-    LintId::of(bool_to_int_with_if::BOOL_TO_INT_WITH_IF),
-    LintId::of(casts::FN_TO_NUMERIC_CAST),
-    LintId::of(casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION),
-    LintId::of(collapsible_if::COLLAPSIBLE_ELSE_IF),
-    LintId::of(collapsible_if::COLLAPSIBLE_IF),
-    LintId::of(comparison_chain::COMPARISON_CHAIN),
-    LintId::of(default::FIELD_REASSIGN_WITH_DEFAULT),
-    LintId::of(default_instead_of_iter_empty::DEFAULT_INSTEAD_OF_ITER_EMPTY),
-    LintId::of(dereference::NEEDLESS_BORROW),
-    LintId::of(disallowed_macros::DISALLOWED_MACROS),
-    LintId::of(disallowed_methods::DISALLOWED_METHODS),
-    LintId::of(disallowed_names::DISALLOWED_NAMES),
-    LintId::of(disallowed_types::DISALLOWED_TYPES),
-    LintId::of(doc::MISSING_SAFETY_DOC),
-    LintId::of(doc::NEEDLESS_DOCTEST_MAIN),
-    LintId::of(enum_variants::ENUM_VARIANT_NAMES),
-    LintId::of(enum_variants::MODULE_INCEPTION),
-    LintId::of(eta_reduction::REDUNDANT_CLOSURE),
-    LintId::of(float_literal::EXCESSIVE_PRECISION),
-    LintId::of(from_over_into::FROM_OVER_INTO),
-    LintId::of(from_str_radix_10::FROM_STR_RADIX_10),
-    LintId::of(functions::DOUBLE_MUST_USE),
-    LintId::of(functions::MUST_USE_UNIT),
-    LintId::of(functions::RESULT_UNIT_ERR),
-    LintId::of(implicit_saturating_add::IMPLICIT_SATURATING_ADD),
-    LintId::of(implicit_saturating_sub::IMPLICIT_SATURATING_SUB),
-    LintId::of(inherent_to_string::INHERENT_TO_STRING),
-    LintId::of(init_numbered_fields::INIT_NUMBERED_FIELDS),
-    LintId::of(len_zero::COMPARISON_TO_EMPTY),
-    LintId::of(len_zero::LEN_WITHOUT_IS_EMPTY),
-    LintId::of(len_zero::LEN_ZERO),
-    LintId::of(literal_representation::INCONSISTENT_DIGIT_GROUPING),
-    LintId::of(literal_representation::UNUSUAL_BYTE_GROUPINGS),
-    LintId::of(loops::FOR_KV_MAP),
-    LintId::of(loops::NEEDLESS_RANGE_LOOP),
-    LintId::of(loops::SAME_ITEM_PUSH),
-    LintId::of(loops::WHILE_LET_ON_ITERATOR),
-    LintId::of(main_recursion::MAIN_RECURSION),
-    LintId::of(manual_async_fn::MANUAL_ASYNC_FN),
-    LintId::of(manual_bits::MANUAL_BITS),
-    LintId::of(manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE),
-    LintId::of(match_result_ok::MATCH_RESULT_OK),
-    LintId::of(matches::COLLAPSIBLE_MATCH),
-    LintId::of(matches::INFALLIBLE_DESTRUCTURING_MATCH),
-    LintId::of(matches::MANUAL_MAP),
-    LintId::of(matches::MATCH_LIKE_MATCHES_MACRO),
-    LintId::of(matches::MATCH_OVERLAPPING_ARM),
-    LintId::of(matches::MATCH_REF_PATS),
-    LintId::of(matches::REDUNDANT_PATTERN_MATCHING),
-    LintId::of(matches::SINGLE_MATCH),
-    LintId::of(mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
-    LintId::of(mem_replace::MEM_REPLACE_WITH_DEFAULT),
-    LintId::of(methods::BYTES_NTH),
-    LintId::of(methods::CHARS_LAST_CMP),
-    LintId::of(methods::CHARS_NEXT_CMP),
-    LintId::of(methods::ERR_EXPECT),
-    LintId::of(methods::GET_FIRST),
-    LintId::of(methods::INTO_ITER_ON_REF),
-    LintId::of(methods::IS_DIGIT_ASCII_RADIX),
-    LintId::of(methods::ITER_CLONED_COLLECT),
-    LintId::of(methods::ITER_NEXT_SLICE),
-    LintId::of(methods::ITER_NTH_ZERO),
-    LintId::of(methods::ITER_SKIP_NEXT),
-    LintId::of(methods::MANUAL_SATURATING_ARITHMETIC),
-    LintId::of(methods::MAP_CLONE),
-    LintId::of(methods::MAP_COLLECT_RESULT_UNIT),
-    LintId::of(methods::MUT_MUTEX_LOCK),
-    LintId::of(methods::NEW_RET_NO_SELF),
-    LintId::of(methods::OBFUSCATED_IF_ELSE),
-    LintId::of(methods::OK_EXPECT),
-    LintId::of(methods::OPTION_MAP_OR_NONE),
-    LintId::of(methods::RESULT_MAP_OR_INTO_OPTION),
-    LintId::of(methods::SHOULD_IMPLEMENT_TRAIT),
-    LintId::of(methods::SINGLE_CHAR_ADD_STR),
-    LintId::of(methods::STRING_EXTEND_CHARS),
-    LintId::of(methods::UNNECESSARY_FOLD),
-    LintId::of(methods::UNNECESSARY_LAZY_EVALUATIONS),
-    LintId::of(methods::UNWRAP_OR_ELSE_DEFAULT),
-    LintId::of(methods::WRONG_SELF_CONVENTION),
-    LintId::of(misc::TOPLEVEL_REF_ARG),
-    LintId::of(misc::ZERO_PTR),
-    LintId::of(misc_early::BUILTIN_TYPE_SHADOW),
-    LintId::of(misc_early::DOUBLE_NEG),
-    LintId::of(misc_early::DUPLICATE_UNDERSCORE_ARGUMENT),
-    LintId::of(misc_early::MIXED_CASE_HEX_LITERALS),
-    LintId::of(misc_early::REDUNDANT_PATTERN),
-    LintId::of(mut_reference::UNNECESSARY_MUT_PASSED),
-    LintId::of(needless_late_init::NEEDLESS_LATE_INIT),
-    LintId::of(needless_parens_on_range_literals::NEEDLESS_PARENS_ON_RANGE_LITERALS),
-    LintId::of(neg_multiply::NEG_MULTIPLY),
-    LintId::of(new_without_default::NEW_WITHOUT_DEFAULT),
-    LintId::of(non_copy_const::BORROW_INTERIOR_MUTABLE_CONST),
-    LintId::of(non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST),
-    LintId::of(non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
-    LintId::of(operators::ASSIGN_OP_PATTERN),
-    LintId::of(operators::OP_REF),
-    LintId::of(operators::PTR_EQ),
-    LintId::of(partialeq_to_none::PARTIALEQ_TO_NONE),
-    LintId::of(ptr::CMP_NULL),
-    LintId::of(ptr::PTR_ARG),
-    LintId::of(question_mark::QUESTION_MARK),
-    LintId::of(ranges::MANUAL_RANGE_CONTAINS),
-    LintId::of(redundant_field_names::REDUNDANT_FIELD_NAMES),
-    LintId::of(redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
-    LintId::of(returns::LET_AND_RETURN),
-    LintId::of(returns::NEEDLESS_RETURN),
-    LintId::of(self_named_constructors::SELF_NAMED_CONSTRUCTORS),
-    LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
-    LintId::of(strings::TRIM_SPLIT_WHITESPACE),
-    LintId::of(tabs_in_doc_comments::TABS_IN_DOC_COMMENTS),
-    LintId::of(to_digit_is_some::TO_DIGIT_IS_SOME),
-    LintId::of(unit_types::LET_UNIT_VALUE),
-    LintId::of(unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS),
-    LintId::of(unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
-    LintId::of(unused_unit::UNUSED_UNIT),
-    LintId::of(upper_case_acronyms::UPPER_CASE_ACRONYMS),
-    LintId::of(write::PRINTLN_EMPTY_STRING),
-    LintId::of(write::PRINT_LITERAL),
-    LintId::of(write::PRINT_WITH_NEWLINE),
-    LintId::of(write::WRITELN_EMPTY_STRING),
-    LintId::of(write::WRITE_LITERAL),
-    LintId::of(write::WRITE_WITH_NEWLINE),
-])
diff --git a/clippy_lints/src/lib.register_suspicious.rs b/clippy_lints/src/lib.register_suspicious.rs
deleted file mode 100644
index b70c4bb73e5..00000000000
--- a/clippy_lints/src/lib.register_suspicious.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-// This file was generated by `cargo dev update_lints`.
-// Use that command to update this file and do not edit by hand.
-// Manual edits will be overwritten.
-
-store.register_group(true, "clippy::suspicious", Some("clippy_suspicious"), vec![
-    LintId::of(almost_complete_letter_range::ALMOST_COMPLETE_LETTER_RANGE),
-    LintId::of(attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
-    LintId::of(await_holding_invalid::AWAIT_HOLDING_INVALID_TYPE),
-    LintId::of(await_holding_invalid::AWAIT_HOLDING_LOCK),
-    LintId::of(await_holding_invalid::AWAIT_HOLDING_REFCELL_REF),
-    LintId::of(casts::CAST_ABS_TO_UNSIGNED),
-    LintId::of(casts::CAST_ENUM_CONSTRUCTOR),
-    LintId::of(casts::CAST_ENUM_TRUNCATION),
-    LintId::of(casts::CAST_NAN_TO_INT),
-    LintId::of(casts::CAST_SLICE_FROM_RAW_PARTS),
-    LintId::of(crate_in_macro_def::CRATE_IN_MACRO_DEF),
-    LintId::of(drop_forget_ref::DROP_NON_DROP),
-    LintId::of(drop_forget_ref::FORGET_NON_DROP),
-    LintId::of(duplicate_mod::DUPLICATE_MOD),
-    LintId::of(format_impl::PRINT_IN_FORMAT_IMPL),
-    LintId::of(formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING),
-    LintId::of(formatting::SUSPICIOUS_ELSE_FORMATTING),
-    LintId::of(formatting::SUSPICIOUS_UNARY_OP_FORMATTING),
-    LintId::of(loops::EMPTY_LOOP),
-    LintId::of(loops::MUT_RANGE_BOUND),
-    LintId::of(methods::NO_EFFECT_REPLACE),
-    LintId::of(methods::SUSPICIOUS_MAP),
-    LintId::of(methods::SUSPICIOUS_TO_OWNED),
-    LintId::of(multi_assignments::MULTI_ASSIGNMENTS),
-    LintId::of(mut_key::MUTABLE_KEY_TYPE),
-    LintId::of(octal_escapes::OCTAL_ESCAPES),
-    LintId::of(operators::FLOAT_EQUALITY_WITHOUT_ABS),
-    LintId::of(operators::MISREFACTORED_ASSIGN_OP),
-    LintId::of(rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT),
-    LintId::of(suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
-    LintId::of(suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
-    LintId::of(swap_ptr_to_ref::SWAP_PTR_TO_REF),
-])
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 1307096b28d..b481314abed 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -32,8 +32,8 @@ extern crate rustc_driver;
 extern crate rustc_errors;
 extern crate rustc_hir;
 extern crate rustc_hir_analysis;
-extern crate rustc_hir_typeck;
 extern crate rustc_hir_pretty;
+extern crate rustc_hir_typeck;
 extern crate rustc_index;
 extern crate rustc_infer;
 extern crate rustc_lexer;
@@ -47,122 +47,24 @@ extern crate rustc_trait_selection;
 
 #[macro_use]
 extern crate clippy_utils;
+#[macro_use]
+extern crate declare_clippy_lint;
+
+use std::io;
+use std::path::PathBuf;
 
 use clippy_utils::parse_msrv;
 use rustc_data_structures::fx::FxHashSet;
-use rustc_lint::LintId;
+use rustc_lint::{Lint, LintId};
 use rustc_semver::RustcVersion;
 use rustc_session::Session;
 
-/// Macro used to declare a Clippy lint.
-///
-/// Every lint declaration consists of 4 parts:
-///
-/// 1. The documentation, which is used for the website
-/// 2. The `LINT_NAME`. See [lint naming][lint_naming] on lint naming conventions.
-/// 3. The `lint_level`, which is a mapping from *one* of our lint groups to `Allow`, `Warn` or
-///    `Deny`. The lint level here has nothing to do with what lint groups the lint is a part of.
-/// 4. The `description` that contains a short explanation on what's wrong with code where the
-///    lint is triggered.
-///
-/// Currently the categories `style`, `correctness`, `suspicious`, `complexity` and `perf` are
-/// enabled by default. As said in the README.md of this repository, if the lint level mapping
-/// changes, please update README.md.
-///
-/// # Example
-///
-/// ```
-/// #![feature(rustc_private)]
-/// extern crate rustc_session;
-/// use rustc_session::declare_tool_lint;
-/// use clippy_lints::declare_clippy_lint;
-///
-/// declare_clippy_lint! {
-///     /// ### What it does
-///     /// Checks for ... (describe what the lint matches).
-///     ///
-///     /// ### Why is this bad?
-///     /// Supply the reason for linting the code.
-///     ///
-///     /// ### Example
-///     /// ```rust
-///     /// Insert a short example of code that triggers the lint
-///     /// ```
-///     ///
-///     /// Use instead:
-///     /// ```rust
-///     /// Insert a short example of improved code that doesn't trigger the lint
-///     /// ```
-///     pub LINT_NAME,
-///     pedantic,
-///     "description"
-/// }
-/// ```
-/// [lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
-#[macro_export]
-macro_rules! declare_clippy_lint {
-    { $(#[$attr:meta])* pub $name:tt, style, $description:tt } => {
-        declare_tool_lint! {
-            $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
-        }
-    };
-    { $(#[$attr:meta])* pub $name:tt, correctness, $description:tt } => {
-        declare_tool_lint! {
-            $(#[$attr])* pub clippy::$name, Deny, $description, report_in_external_macro: true
-        }
-    };
-    { $(#[$attr:meta])* pub $name:tt, suspicious, $description:tt } => {
-        declare_tool_lint! {
-            $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
-        }
-    };
-    { $(#[$attr:meta])* pub $name:tt, complexity, $description:tt } => {
-        declare_tool_lint! {
-            $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
-        }
-    };
-    { $(#[$attr:meta])* pub $name:tt, perf, $description:tt } => {
-        declare_tool_lint! {
-            $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
-        }
-    };
-    { $(#[$attr:meta])* pub $name:tt, pedantic, $description:tt } => {
-        declare_tool_lint! {
-            $(#[$attr])* pub clippy::$name, Allow, $description, report_in_external_macro: true
-        }
-    };
-    { $(#[$attr:meta])* pub $name:tt, restriction, $description:tt } => {
-        declare_tool_lint! {
-            $(#[$attr])* pub clippy::$name, Allow, $description, report_in_external_macro: true
-        }
-    };
-    { $(#[$attr:meta])* pub $name:tt, cargo, $description:tt } => {
-        declare_tool_lint! {
-            $(#[$attr])* pub clippy::$name, Allow, $description, report_in_external_macro: true
-        }
-    };
-    { $(#[$attr:meta])* pub $name:tt, nursery, $description:tt } => {
-        declare_tool_lint! {
-            $(#[$attr])* pub clippy::$name, Allow, $description, report_in_external_macro: true
-        }
-    };
-    { $(#[$attr:meta])* pub $name:tt, internal, $description:tt } => {
-        declare_tool_lint! {
-            $(#[$attr])* pub clippy::$name, Allow, $description, report_in_external_macro: true
-        }
-    };
-    { $(#[$attr:meta])* pub $name:tt, internal_warn, $description:tt } => {
-        declare_tool_lint! {
-            $(#[$attr])* pub clippy::$name, Warn, $description, report_in_external_macro: true
-        }
-    };
-}
-
 #[cfg(feature = "internal")]
 pub mod deprecated_lints;
 #[cfg_attr(feature = "internal", allow(clippy::missing_clippy_version_attribute))]
 mod utils;
 
+mod declared_lints;
 mod renamed_lints;
 
 // begin lints modules, do not remove this comment, it’s used in `update_lints`
@@ -231,6 +133,7 @@ mod format_impl;
 mod format_push_string;
 mod formatting;
 mod from_over_into;
+mod from_raw_with_void_ptr;
 mod from_str_radix_10;
 mod functions;
 mod future_not_send;
@@ -249,6 +152,7 @@ mod inherent_impl;
 mod inherent_to_string;
 mod init_numbered_fields;
 mod inline_fn_without_body;
+mod instant_subtraction;
 mod int_plus_one;
 mod invalid_upcast_comparisons;
 mod invalid_utf8_in_unchecked;
@@ -270,7 +174,8 @@ mod manual_assert;
 mod manual_async_fn;
 mod manual_bits;
 mod manual_clamp;
-mod manual_instant_elapsed;
+mod manual_is_ascii_check;
+mod manual_let_else;
 mod manual_non_exhaustive;
 mod manual_rem_euclid;
 mod manual_retain;
@@ -365,6 +270,7 @@ mod strings;
 mod strlen_on_c_strings;
 mod suspicious_operation_groupings;
 mod suspicious_trait_impl;
+mod suspicious_xor_used_as_pow;
 mod swap;
 mod swap_ptr_to_ref;
 mod tabs_in_doc_comments;
@@ -404,8 +310,8 @@ mod zero_div_zero;
 mod zero_sized_map_values;
 // end lints modules, do not remove this comment, it’s used in `update_lints`
 
-pub use crate::utils::conf::Conf;
 use crate::utils::conf::{format_error, TryConf};
+pub use crate::utils::conf::{lookup_conf_file, Conf};
 
 /// Register all pre expansion lints
 ///
@@ -462,8 +368,8 @@ fn read_msrv(conf: &Conf, sess: &Session) -> Option<RustcVersion> {
 }
 
 #[doc(hidden)]
-pub fn read_conf(sess: &Session) -> Conf {
-    let file_name = match utils::conf::lookup_conf_file() {
+pub fn read_conf(sess: &Session, path: &io::Result<Option<PathBuf>>) -> Conf {
+    let file_name = match path {
         Ok(Some(path)) => path,
         Ok(None) => return Conf::default(),
         Err(error) => {
@@ -473,7 +379,7 @@ pub fn read_conf(sess: &Session) -> Conf {
         },
     };
 
-    let TryConf { conf, errors, warnings } = utils::conf::read(&file_name);
+    let TryConf { conf, errors, warnings } = utils::conf::read(file_name);
     // all conf errors are non-fatal, we just use the default conf in case of error
     for error in errors {
         sess.err(format!(
@@ -495,31 +401,121 @@ pub fn read_conf(sess: &Session) -> Conf {
     conf
 }
 
+#[derive(Default)]
+struct RegistrationGroups {
+    all: Vec<LintId>,
+    cargo: Vec<LintId>,
+    complexity: Vec<LintId>,
+    correctness: Vec<LintId>,
+    nursery: Vec<LintId>,
+    pedantic: Vec<LintId>,
+    perf: Vec<LintId>,
+    restriction: Vec<LintId>,
+    style: Vec<LintId>,
+    suspicious: Vec<LintId>,
+    #[cfg(feature = "internal")]
+    internal: Vec<LintId>,
+}
+
+impl RegistrationGroups {
+    #[rustfmt::skip]
+    fn register(self, store: &mut rustc_lint::LintStore) {
+        store.register_group(true, "clippy::all", Some("clippy_all"), self.all);
+        store.register_group(true, "clippy::cargo", Some("clippy_cargo"), self.cargo);
+        store.register_group(true, "clippy::complexity", Some("clippy_complexity"), self.complexity);
+        store.register_group(true, "clippy::correctness", Some("clippy_correctness"), self.correctness);
+        store.register_group(true, "clippy::nursery", Some("clippy_nursery"), self.nursery);
+        store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), self.pedantic);
+        store.register_group(true, "clippy::perf", Some("clippy_perf"), self.perf);
+        store.register_group(true, "clippy::restriction", Some("clippy_restriction"), self.restriction);
+        store.register_group(true, "clippy::style", Some("clippy_style"), self.style);
+        store.register_group(true, "clippy::suspicious", Some("clippy_suspicious"), self.suspicious);
+        #[cfg(feature = "internal")]
+        store.register_group(true, "clippy::internal", Some("clippy_internal"), self.internal);
+    }
+}
+
+#[derive(Copy, Clone)]
+pub(crate) enum LintCategory {
+    Cargo,
+    Complexity,
+    Correctness,
+    Nursery,
+    Pedantic,
+    Perf,
+    Restriction,
+    Style,
+    Suspicious,
+    #[cfg(feature = "internal")]
+    Internal,
+}
+#[allow(clippy::enum_glob_use)]
+use LintCategory::*;
+
+impl LintCategory {
+    fn is_all(self) -> bool {
+        matches!(self, Correctness | Suspicious | Style | Complexity | Perf)
+    }
+
+    fn group(self, groups: &mut RegistrationGroups) -> &mut Vec<LintId> {
+        match self {
+            Cargo => &mut groups.cargo,
+            Complexity => &mut groups.complexity,
+            Correctness => &mut groups.correctness,
+            Nursery => &mut groups.nursery,
+            Pedantic => &mut groups.pedantic,
+            Perf => &mut groups.perf,
+            Restriction => &mut groups.restriction,
+            Style => &mut groups.style,
+            Suspicious => &mut groups.suspicious,
+            #[cfg(feature = "internal")]
+            Internal => &mut groups.internal,
+        }
+    }
+}
+
+pub(crate) struct LintInfo {
+    /// Double reference to maintain pointer equality
+    lint: &'static &'static Lint,
+    category: LintCategory,
+    explanation: &'static str,
+}
+
+pub fn explain(name: &str) {
+    let target = format!("clippy::{}", name.to_ascii_uppercase());
+    match declared_lints::LINTS.iter().find(|info| info.lint.name == target) {
+        Some(info) => print!("{}", info.explanation),
+        None => println!("unknown lint: {name}"),
+    }
+}
+
+fn register_categories(store: &mut rustc_lint::LintStore) {
+    let mut groups = RegistrationGroups::default();
+
+    for LintInfo { lint, category, .. } in declared_lints::LINTS {
+        if category.is_all() {
+            groups.all.push(LintId::of(lint));
+        }
+
+        category.group(&mut groups).push(LintId::of(lint));
+    }
+
+    let lints: Vec<&'static Lint> = declared_lints::LINTS.iter().map(|info| *info.lint).collect();
+
+    store.register_lints(&lints);
+    groups.register(store);
+}
+
 /// Register all lints and lint groups with the rustc plugin registry
 ///
 /// Used in `./src/driver.rs`.
 #[expect(clippy::too_many_lines)]
 pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &Conf) {
     register_removed_non_tool_lints(store);
+    register_categories(store);
 
     include!("lib.deprecated.rs");
 
-    include!("lib.register_lints.rs");
-    include!("lib.register_restriction.rs");
-    include!("lib.register_pedantic.rs");
-
-    #[cfg(feature = "internal")]
-    include!("lib.register_internal.rs");
-
-    include!("lib.register_all.rs");
-    include!("lib.register_style.rs");
-    include!("lib.register_complexity.rs");
-    include!("lib.register_correctness.rs");
-    include!("lib.register_suspicious.rs");
-    include!("lib.register_perf.rs");
-    include!("lib.register_cargo.rs");
-    include!("lib.register_nursery.rs");
-
     #[cfg(feature = "internal")]
     {
         if std::env::var("ENABLE_METADATA_COLLECTION").eq(&Ok("1".to_string())) {
@@ -614,6 +610,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
         ))
     });
     store.register_late_pass(move |_| Box::new(matches::Matches::new(msrv)));
+    let matches_for_let_else = conf.matches_for_let_else;
+    store.register_late_pass(move |_| Box::new(manual_let_else::ManualLetElse::new(msrv, matches_for_let_else)));
     store.register_early_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveStruct::new(msrv)));
     store.register_late_pass(move |_| Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(msrv)));
     store.register_late_pass(move |_| Box::new(manual_strip::ManualStrip::new(msrv)));
@@ -735,7 +733,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     let max_trait_bounds = conf.max_trait_bounds;
     store.register_late_pass(move |_| Box::new(trait_bounds::TraitBounds::new(max_trait_bounds)));
     store.register_late_pass(|_| Box::new(comparison_chain::ComparisonChain));
-    store.register_late_pass(|_| Box::new(mut_key::MutableKeyType));
+    let ignore_interior_mutability = conf.ignore_interior_mutability.clone();
+    store.register_late_pass(move |_| Box::new(mut_key::MutableKeyType::new(ignore_interior_mutability.clone())));
     store.register_early_pass(|| Box::new(reference::DerefAddrOf));
     store.register_early_pass(|| Box::new(double_parens::DoubleParens));
     store.register_late_pass(|_| Box::new(format_impl::FormatImpl::new()));
@@ -794,10 +793,10 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|_| Box::new(floating_point_arithmetic::FloatingPointArithmetic));
     store.register_early_pass(|| Box::new(as_conversions::AsConversions));
     store.register_late_pass(|_| Box::new(let_underscore::LetUnderscore));
-    store.register_early_pass(|| Box::new(single_component_path_imports::SingleComponentPathImports));
+    store.register_early_pass(|| Box::<single_component_path_imports::SingleComponentPathImports>::default());
     let max_fn_params_bools = conf.max_fn_params_bools;
     let max_struct_bools = conf.max_struct_bools;
-    store.register_early_pass(move || {
+    store.register_late_pass(move |_| {
         Box::new(excessive_bools::ExcessiveBools::new(
             max_struct_bools,
             max_fn_params_bools,
@@ -879,13 +878,14 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|_| Box::<only_used_in_recursion::OnlyUsedInRecursion>::default());
     let allow_dbg_in_tests = conf.allow_dbg_in_tests;
     store.register_late_pass(move |_| Box::new(dbg_macro::DbgMacro::new(allow_dbg_in_tests)));
+    let allow_print_in_tests = conf.allow_print_in_tests;
+    store.register_late_pass(move |_| Box::new(write::Write::new(allow_print_in_tests)));
     let cargo_ignore_publish = conf.cargo_ignore_publish;
     store.register_late_pass(move |_| {
         Box::new(cargo::Cargo {
             ignore_publish: cargo_ignore_publish,
         })
     });
-    store.register_late_pass(|_| Box::<write::Write>::default());
     store.register_early_pass(|| Box::new(crate_in_macro_def::CrateInMacroDef));
     store.register_early_pass(|| Box::new(empty_structs_with_brackets::EmptyStructsWithBrackets));
     store.register_late_pass(|_| Box::new(unnecessary_owned_empty_strings::UnnecessaryOwnedEmptyStrings));
@@ -908,7 +908,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(move |_| Box::new(operators::Operators::new(verbose_bit_mask_threshold)));
     store.register_late_pass(|_| Box::new(invalid_utf8_in_unchecked::InvalidUtf8InUnchecked));
     store.register_late_pass(|_| Box::<std_instead_of_core::StdReexports>::default());
-    store.register_late_pass(|_| Box::new(manual_instant_elapsed::ManualInstantElapsed));
+    store.register_late_pass(move |_| Box::new(instant_subtraction::InstantSubtraction::new(msrv)));
     store.register_late_pass(|_| Box::new(partialeq_to_none::PartialeqToNone));
     store.register_late_pass(move |_| Box::new(manual_clamp::ManualClamp::new(msrv)));
     store.register_late_pass(|_| Box::new(manual_string_new::ManualStringNew));
@@ -919,6 +919,9 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|_| Box::new(implicit_saturating_add::ImplicitSaturatingAdd));
     store.register_early_pass(|| Box::new(partial_pub_fields::PartialPubFields));
     store.register_late_pass(|_| Box::new(missing_trait_methods::MissingTraitMethods));
+    store.register_late_pass(|_| Box::new(from_raw_with_void_ptr::FromRawWithVoidPtr));
+    store.register_late_pass(|_| Box::new(suspicious_xor_used_as_pow::ConfusingXorAndPow));
+    store.register_late_pass(move |_| Box::new(manual_is_ascii_check::ManualIsAsciiCheck::new(msrv)));
     // add lints here, do not remove this comment, it's used in `new_lint`
 }
 
diff --git a/clippy_lints/src/lifetimes.rs b/clippy_lints/src/lifetimes.rs
index 54c316358a1..0bb9eca1528 100644
--- a/clippy_lints/src/lifetimes.rs
+++ b/clippy_lints/src/lifetimes.rs
@@ -1,4 +1,4 @@
-use clippy_utils::diagnostics::span_lint;
+use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use clippy_utils::trait_ref_of_method;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::intravisit::nested_filter::{self as hir_nested_filter, NestedFilter};
@@ -152,6 +152,7 @@ fn check_fn_inner<'tcx>(
         .params
         .iter()
         .filter(|param| matches!(param.kind, GenericParamKind::Type { .. }));
+
     for typ in types {
         for pred in generics.bounds_for_param(cx.tcx.hir().local_def_id(typ.hir_id)) {
             if pred.origin == PredicateOrigin::WhereClause {
@@ -188,15 +189,30 @@ fn check_fn_inner<'tcx>(
             }
         }
     }
-    if could_use_elision(cx, decl, body, trait_sig, generics.params) {
-        span_lint(
+
+    if let Some(elidable_lts) = could_use_elision(cx, decl, body, trait_sig, generics.params) {
+        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().get_by_def_id(def_id).ident())
+            .map(|ident| ident.to_string())
+            .collect::<Vec<_>>()
+            .join(", ");
+
+        span_lint_and_then(
             cx,
             NEEDLESS_LIFETIMES,
             span.with_hi(decl.output.span().hi()),
-            "explicit lifetimes given in parameter types where they could be elided \
-             (or replaced with `'_` if needed by type declaration)",
+            &format!("the following explicit lifetimes could be elided: {lts}"),
+            |diag| {
+                if let Some(span) = elidable_lts.iter().find_map(|&(_, span)| span) {
+                    diag.span_help(span, "replace with `'_` in generic arguments such as here");
+                }
+            },
         );
     }
+
     if report_extra_lifetimes {
         self::report_extra_lifetimes(cx, decl, generics);
     }
@@ -227,7 +243,7 @@ fn could_use_elision<'tcx>(
     body: Option<BodyId>,
     trait_sig: Option<&[Ident]>,
     named_generics: &'tcx [GenericParam<'_>],
-) -> bool {
+) -> Option<Vec<(LocalDefId, Option<Span>)>> {
     // There are two scenarios where elision works:
     // * no output references, all input references have different LT
     // * output references, exactly one input reference with same LT
@@ -254,7 +270,7 @@ fn could_use_elision<'tcx>(
     }
 
     if input_visitor.abort() || output_visitor.abort() {
-        return false;
+        return None;
     }
 
     let input_lts = input_visitor.lts;
@@ -262,7 +278,7 @@ fn could_use_elision<'tcx>(
 
     if let Some(trait_sig) = trait_sig {
         if explicit_self_type(cx, func, trait_sig.first().copied()) {
-            return false;
+            return None;
         }
     }
 
@@ -271,7 +287,7 @@ fn could_use_elision<'tcx>(
 
         let first_ident = body.params.first().and_then(|param| param.pat.simple_ident());
         if explicit_self_type(cx, func, first_ident) {
-            return false;
+            return None;
         }
 
         let mut checker = BodyLifetimeChecker {
@@ -279,14 +295,14 @@ fn could_use_elision<'tcx>(
         };
         checker.visit_expr(body.value);
         if checker.lifetimes_used_in_body {
-            return false;
+            return None;
         }
     }
 
     // check for lifetimes from higher scopes
     for lt in input_lts.iter().chain(output_lts.iter()) {
         if !allowed_lts.contains(lt) {
-            return false;
+            return None;
         }
     }
 
@@ -302,48 +318,45 @@ fn could_use_elision<'tcx>(
         for lt in input_visitor.nested_elision_site_lts {
             if let RefLt::Named(def_id) = lt {
                 if allowed_lts.contains(&cx.tcx.item_name(def_id.to_def_id())) {
-                    return false;
+                    return None;
                 }
             }
         }
         for lt in output_visitor.nested_elision_site_lts {
             if let RefLt::Named(def_id) = lt {
                 if allowed_lts.contains(&cx.tcx.item_name(def_id.to_def_id())) {
-                    return false;
+                    return None;
                 }
             }
         }
     }
 
-    // no input lifetimes? easy case!
-    if input_lts.is_empty() {
-        false
-    } else if output_lts.is_empty() {
-        // no output lifetimes, check distinctness of input lifetimes
+    // A lifetime can be newly elided if:
+    // - It occurs only once among the inputs.
+    // - If there are multiple input lifetimes, then the newly elided lifetime does not occur among the
+    //   outputs (because eliding such an lifetime would create an ambiguity).
+    let elidable_lts = named_lifetime_occurrences(&input_lts)
+        .into_iter()
+        .filter_map(|(def_id, occurrences)| {
+            if occurrences == 1 && (input_lts.len() == 1 || !output_lts.contains(&RefLt::Named(def_id))) {
+                Some((
+                    def_id,
+                    input_visitor
+                        .lifetime_generic_arg_spans
+                        .get(&def_id)
+                        .or_else(|| output_visitor.lifetime_generic_arg_spans.get(&def_id))
+                        .copied(),
+                ))
+            } else {
+                None
+            }
+        })
+        .collect::<Vec<_>>();
 
-        // only unnamed and static, ok
-        let unnamed_and_static = input_lts.iter().all(|lt| *lt == RefLt::Unnamed || *lt == RefLt::Static);
-        if unnamed_and_static {
-            return false;
-        }
-        // we have no output reference, so we only need all distinct lifetimes
-        input_lts.len() == unique_lifetimes(&input_lts)
+    if elidable_lts.is_empty() {
+        None
     } else {
-        // we have output references, so we need one input reference,
-        // and all output lifetimes must be the same
-        if unique_lifetimes(&output_lts) > 1 {
-            return false;
-        }
-        if input_lts.len() == 1 {
-            match (&input_lts[0], &output_lts[0]) {
-                (&RefLt::Named(n1), &RefLt::Named(n2)) if n1 == n2 => true,
-                (&RefLt::Named(_), &RefLt::Unnamed) => true,
-                _ => false, /* already elided, different named lifetimes
-                             * or something static going on */
-            }
-        } else {
-            false
-        }
+        Some(elidable_lts)
     }
 }
 
@@ -359,16 +372,31 @@ fn allowed_lts_from(tcx: TyCtxt<'_>, named_generics: &[GenericParam<'_>]) -> FxH
     allowed_lts
 }
 
-/// Number of unique lifetimes in the given vector.
+/// Number of times each named lifetime occurs in the given slice. Returns a vector to preserve
+/// relative order.
 #[must_use]
-fn unique_lifetimes(lts: &[RefLt]) -> usize {
-    lts.iter().collect::<FxHashSet<_>>().len()
+fn named_lifetime_occurrences(lts: &[RefLt]) -> Vec<(LocalDefId, usize)> {
+    let mut occurrences = Vec::new();
+    for lt in lts {
+        if let &RefLt::Named(curr_def_id) = lt {
+            if let Some(pair) = occurrences
+                .iter_mut()
+                .find(|(prev_def_id, _)| *prev_def_id == curr_def_id)
+            {
+                pair.1 += 1;
+            } else {
+                occurrences.push((curr_def_id, 1));
+            }
+        }
+    }
+    occurrences
 }
 
 /// A visitor usable for `rustc_front::visit::walk_ty()`.
 struct RefVisitor<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
     lts: Vec<RefLt>,
+    lifetime_generic_arg_spans: FxHashMap<LocalDefId, Span>,
     nested_elision_site_lts: Vec<RefLt>,
     unelided_trait_object_lifetime: bool,
 }
@@ -378,6 +406,7 @@ impl<'a, 'tcx> RefVisitor<'a, 'tcx> {
         Self {
             cx,
             lts: Vec::new(),
+            lifetime_generic_arg_spans: FxHashMap::default(),
             nested_elision_site_lts: Vec::new(),
             unelided_trait_object_lifetime: false,
         }
@@ -467,6 +496,22 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
             _ => walk_ty(self, ty),
         }
     }
+
+    fn visit_generic_arg(&mut self, generic_arg: &'tcx GenericArg<'tcx>) {
+        if let GenericArg::Lifetime(l) = generic_arg
+            && let LifetimeName::Param(def_id, _) = l.name
+        {
+            self.lifetime_generic_arg_spans.entry(def_id).or_insert(l.span);
+        }
+        // Replace with `walk_generic_arg` if/when https://github.com/rust-lang/rust/pull/103692 lands.
+        // walk_generic_arg(self, generic_arg);
+        match generic_arg {
+            GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
+            GenericArg::Type(ty) => self.visit_ty(ty),
+            GenericArg::Const(ct) => self.visit_anon_const(&ct.value),
+            GenericArg::Infer(inf) => self.visit_infer(inf),
+        }
+    }
 }
 
 /// Are any lifetimes mentioned in the `where` clause? If so, we don't try to
diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs
index bcf278d9c83..8e52cac4323 100644
--- a/clippy_lints/src/loops/mod.rs
+++ b/clippy_lints/src/loops/mod.rs
@@ -9,7 +9,6 @@ mod manual_flatten;
 mod manual_memcpy;
 mod missing_spin_loop;
 mod mut_range_bound;
-mod needless_collect;
 mod needless_range_loop;
 mod never_loop;
 mod same_item_push;
@@ -207,28 +206,6 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for functions collecting an iterator when collect
-    /// is not needed.
-    ///
-    /// ### Why is this bad?
-    /// `collect` causes the allocation of a new data structure,
-    /// when this allocation may not be needed.
-    ///
-    /// ### Example
-    /// ```rust
-    /// # let iterator = vec![1].into_iter();
-    /// let len = iterator.clone().collect::<Vec<_>>().len();
-    /// // should be
-    /// let len = iterator.count();
-    /// ```
-    #[clippy::version = "1.30.0"]
-    pub NEEDLESS_COLLECT,
-    perf,
-    "collecting an iterator when collect is not needed"
-}
-
-declare_clippy_lint! {
-    /// ### What it does
     /// Checks `for` loops over slices with an explicit counter
     /// and suggests the use of `.enumerate()`.
     ///
@@ -605,7 +582,6 @@ declare_lint_pass!(Loops => [
     EXPLICIT_INTO_ITER_LOOP,
     ITER_NEXT_LOOP,
     WHILE_LET_LOOP,
-    NEEDLESS_COLLECT,
     EXPLICIT_COUNTER_LOOP,
     EMPTY_LOOP,
     WHILE_LET_ON_ITERATOR,
@@ -667,8 +643,6 @@ impl<'tcx> LateLintPass<'tcx> for Loops {
             while_immutable_condition::check(cx, condition, body);
             missing_spin_loop::check(cx, condition, body);
         }
-
-        needless_collect::check(expr, cx);
     }
 }
 
diff --git a/clippy_lints/src/loops/mut_range_bound.rs b/clippy_lints/src/loops/mut_range_bound.rs
index 91b321c4474..4dae93f6028 100644
--- a/clippy_lints/src/loops/mut_range_bound.rs
+++ b/clippy_lints/src/loops/mut_range_bound.rs
@@ -52,8 +52,8 @@ fn check_for_mutability(cx: &LateContext<'_>, bound: &Expr<'_>) -> Option<HirId>
     None
 }
 
-fn check_for_mutation<'tcx>(
-    cx: &LateContext<'tcx>,
+fn check_for_mutation(
+    cx: &LateContext<'_>,
     body: &Expr<'_>,
     bound_id_start: Option<HirId>,
     bound_id_end: Option<HirId>,
@@ -113,13 +113,7 @@ impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> {
         }
     }
 
-    fn fake_read(
-        &mut self,
-        _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>,
-        _: FakeReadCause,
-        _: HirId,
-    ) {
-    }
+    fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
 }
 
 impl MutatePairDelegate<'_, '_> {
diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs
index 16b00ad6637..14f161f5102 100644
--- a/clippy_lints/src/loops/never_loop.rs
+++ b/clippy_lints/src/loops/never_loop.rs
@@ -4,7 +4,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher::ForLoop;
 use clippy_utils::source::snippet;
 use rustc_errors::Applicability;
-use rustc_hir::{Block, Expr, ExprKind, HirId, InlineAsmOperand, Pat, Stmt, StmtKind};
+use rustc_hir::{Block, Destination, Expr, ExprKind, HirId, InlineAsmOperand, Pat, Stmt, StmtKind};
 use rustc_lint::LateContext;
 use rustc_span::Span;
 use std::iter::{once, Iterator};
@@ -16,7 +16,7 @@ pub(super) fn check(
     span: Span,
     for_loop: Option<&ForLoop<'_>>,
 ) {
-    match never_loop_block(block, loop_id) {
+    match never_loop_block(block, &mut Vec::new(), loop_id) {
         NeverLoopResult::AlwaysBreak => {
             span_lint_and_then(cx, NEVER_LOOP, span, "this loop never actually loops", |diag| {
                 if let Some(ForLoop {
@@ -92,35 +92,34 @@ fn combine_branches(b1: NeverLoopResult, b2: NeverLoopResult) -> NeverLoopResult
     }
 }
 
-fn never_loop_block(block: &Block<'_>, main_loop_id: HirId) -> NeverLoopResult {
-    let mut iter = block
+fn never_loop_block(block: &Block<'_>, ignore_ids: &mut Vec<HirId>, main_loop_id: HirId) -> NeverLoopResult {
+    let iter = block
         .stmts
         .iter()
         .filter_map(stmt_to_expr)
         .chain(block.expr.map(|expr| (expr, None)));
-    never_loop_expr_seq(&mut iter, main_loop_id)
-}
 
-fn never_loop_expr_seq<'a, T: Iterator<Item = (&'a Expr<'a>, Option<&'a Block<'a>>)>>(
-    es: &mut T,
-    main_loop_id: HirId,
-) -> NeverLoopResult {
-    es.map(|(e, els)| {
-        let e = never_loop_expr(e, main_loop_id);
-        els.map_or(e, |els| combine_branches(e, never_loop_block(els, main_loop_id)))
+    iter.map(|(e, els)| {
+        let e = never_loop_expr(e, ignore_ids, main_loop_id);
+        // els is an else block in a let...else binding
+        els.map_or(e, |els| {
+            combine_branches(e, never_loop_block(els, ignore_ids, main_loop_id))
+        })
     })
     .fold(NeverLoopResult::Otherwise, combine_seq)
 }
 
 fn stmt_to_expr<'tcx>(stmt: &Stmt<'tcx>) -> Option<(&'tcx Expr<'tcx>, Option<&'tcx Block<'tcx>>)> {
     match stmt.kind {
-        StmtKind::Semi(e, ..) | StmtKind::Expr(e, ..) => Some((e, None)),
+        StmtKind::Semi(e) | StmtKind::Expr(e) => Some((e, None)),
+        // add the let...else expression (if present)
         StmtKind::Local(local) => local.init.map(|init| (init, local.els)),
         StmtKind::Item(..) => None,
     }
 }
 
-fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
+#[allow(clippy::too_many_lines)]
+fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec<HirId>, main_loop_id: HirId) -> NeverLoopResult {
     match expr.kind {
         ExprKind::Box(e)
         | ExprKind::Unary(_, e)
@@ -129,47 +128,56 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
         | ExprKind::Field(e, _)
         | ExprKind::AddrOf(_, _, e)
         | ExprKind::Repeat(e, _)
-        | ExprKind::DropTemps(e) => never_loop_expr(e, main_loop_id),
-        ExprKind::Let(let_expr) => never_loop_expr(let_expr.init, main_loop_id),
-        ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(&mut es.iter(), main_loop_id),
-        ExprKind::MethodCall(_, receiver, es, _) => {
-            never_loop_expr_all(&mut std::iter::once(receiver).chain(es.iter()), main_loop_id)
-        },
+        | ExprKind::DropTemps(e) => never_loop_expr(e, ignore_ids, main_loop_id),
+        ExprKind::Let(let_expr) => never_loop_expr(let_expr.init, ignore_ids, main_loop_id),
+        ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(&mut es.iter(), ignore_ids, main_loop_id),
+        ExprKind::MethodCall(_, receiver, es, _) => never_loop_expr_all(
+            &mut std::iter::once(receiver).chain(es.iter()),
+            ignore_ids,
+            main_loop_id,
+        ),
         ExprKind::Struct(_, fields, base) => {
-            let fields = never_loop_expr_all(&mut fields.iter().map(|f| f.expr), main_loop_id);
+            let fields = never_loop_expr_all(&mut fields.iter().map(|f| f.expr), ignore_ids, main_loop_id);
             if let Some(base) = base {
-                combine_both(fields, never_loop_expr(base, main_loop_id))
+                combine_both(fields, never_loop_expr(base, ignore_ids, main_loop_id))
             } else {
                 fields
             }
         },
-        ExprKind::Call(e, es) => never_loop_expr_all(&mut once(e).chain(es.iter()), main_loop_id),
+        ExprKind::Call(e, es) => never_loop_expr_all(&mut once(e).chain(es.iter()), ignore_ids, main_loop_id),
         ExprKind::Binary(_, e1, e2)
         | ExprKind::Assign(e1, e2, _)
         | ExprKind::AssignOp(_, e1, e2)
-        | ExprKind::Index(e1, e2) => never_loop_expr_all(&mut [e1, e2].iter().copied(), main_loop_id),
+        | ExprKind::Index(e1, e2) => never_loop_expr_all(&mut [e1, e2].iter().copied(), ignore_ids, main_loop_id),
         ExprKind::Loop(b, _, _, _) => {
             // Break can come from the inner loop so remove them.
-            absorb_break(never_loop_block(b, main_loop_id))
+            absorb_break(never_loop_block(b, ignore_ids, main_loop_id))
         },
         ExprKind::If(e, e2, e3) => {
-            let e1 = never_loop_expr(e, main_loop_id);
-            let e2 = never_loop_expr(e2, main_loop_id);
-            let e3 = e3
-                .as_ref()
-                .map_or(NeverLoopResult::Otherwise, |e| never_loop_expr(e, main_loop_id));
+            let e1 = never_loop_expr(e, ignore_ids, main_loop_id);
+            let e2 = never_loop_expr(e2, ignore_ids, main_loop_id);
+            let e3 = e3.as_ref().map_or(NeverLoopResult::Otherwise, |e| {
+                never_loop_expr(e, ignore_ids, main_loop_id)
+            });
             combine_seq(e1, combine_branches(e2, e3))
         },
         ExprKind::Match(e, arms, _) => {
-            let e = never_loop_expr(e, main_loop_id);
+            let e = never_loop_expr(e, ignore_ids, main_loop_id);
             if arms.is_empty() {
                 e
             } else {
-                let arms = never_loop_expr_branch(&mut arms.iter().map(|a| a.body), main_loop_id);
+                let arms = never_loop_expr_branch(&mut arms.iter().map(|a| a.body), ignore_ids, main_loop_id);
                 combine_seq(e, arms)
             }
         },
-        ExprKind::Block(b, _) => never_loop_block(b, main_loop_id),
+        ExprKind::Block(b, l) => {
+            if l.is_some() {
+                ignore_ids.push(b.hir_id);
+            }
+            let ret = never_loop_block(b, ignore_ids, main_loop_id);
+            ignore_ids.pop();
+            ret
+        },
         ExprKind::Continue(d) => {
             let id = d
                 .target_id
@@ -180,20 +188,32 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
                 NeverLoopResult::AlwaysBreak
             }
         },
+        // checks if break targets a block instead of a loop
+        ExprKind::Break(Destination { target_id: Ok(t), .. }, e) if ignore_ids.contains(&t) => e
+            .map_or(NeverLoopResult::Otherwise, |e| {
+                combine_seq(never_loop_expr(e, ignore_ids, main_loop_id), NeverLoopResult::Otherwise)
+            }),
         ExprKind::Break(_, e) | ExprKind::Ret(e) => e.as_ref().map_or(NeverLoopResult::AlwaysBreak, |e| {
-            combine_seq(never_loop_expr(e, main_loop_id), NeverLoopResult::AlwaysBreak)
+            combine_seq(
+                never_loop_expr(e, ignore_ids, main_loop_id),
+                NeverLoopResult::AlwaysBreak,
+            )
         }),
         ExprKind::InlineAsm(asm) => asm
             .operands
             .iter()
             .map(|(o, _)| match o {
                 InlineAsmOperand::In { expr, .. } | InlineAsmOperand::InOut { expr, .. } => {
-                    never_loop_expr(expr, main_loop_id)
+                    never_loop_expr(expr, ignore_ids, main_loop_id)
                 },
-                InlineAsmOperand::Out { expr, .. } => never_loop_expr_all(&mut expr.iter().copied(), main_loop_id),
-                InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
-                    never_loop_expr_all(&mut once(*in_expr).chain(out_expr.iter().copied()), main_loop_id)
+                InlineAsmOperand::Out { expr, .. } => {
+                    never_loop_expr_all(&mut expr.iter().copied(), ignore_ids, main_loop_id)
                 },
+                InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => never_loop_expr_all(
+                    &mut once(*in_expr).chain(out_expr.iter().copied()),
+                    ignore_ids,
+                    main_loop_id,
+                ),
                 InlineAsmOperand::Const { .. }
                 | InlineAsmOperand::SymFn { .. }
                 | InlineAsmOperand::SymStatic { .. } => NeverLoopResult::Otherwise,
@@ -208,13 +228,21 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
     }
 }
 
-fn never_loop_expr_all<'a, T: Iterator<Item = &'a Expr<'a>>>(es: &mut T, main_loop_id: HirId) -> NeverLoopResult {
-    es.map(|e| never_loop_expr(e, main_loop_id))
+fn never_loop_expr_all<'a, T: Iterator<Item = &'a Expr<'a>>>(
+    es: &mut T,
+    ignore_ids: &mut Vec<HirId>,
+    main_loop_id: HirId,
+) -> NeverLoopResult {
+    es.map(|e| never_loop_expr(e, ignore_ids, main_loop_id))
         .fold(NeverLoopResult::Otherwise, combine_both)
 }
 
-fn never_loop_expr_branch<'a, T: Iterator<Item = &'a Expr<'a>>>(e: &mut T, main_loop_id: HirId) -> NeverLoopResult {
-    e.map(|e| never_loop_expr(e, main_loop_id))
+fn never_loop_expr_branch<'a, T: Iterator<Item = &'a Expr<'a>>>(
+    e: &mut T,
+    ignore_ids: &mut Vec<HirId>,
+    main_loop_id: HirId,
+) -> NeverLoopResult {
+    e.map(|e| never_loop_expr(e, ignore_ids, main_loop_id))
         .fold(NeverLoopResult::AlwaysBreak, combine_branches)
 }
 
diff --git a/clippy_lints/src/manual_instant_elapsed.rs b/clippy_lints/src/manual_instant_elapsed.rs
deleted file mode 100644
index 331cda1db89..00000000000
--- a/clippy_lints/src/manual_instant_elapsed.rs
+++ /dev/null
@@ -1,69 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_sugg;
-use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::source_map::Spanned;
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Lints subtraction between `Instant::now()` and another `Instant`.
-    ///
-    /// ### Why is this bad?
-    /// It is easy to accidentally write `prev_instant - Instant::now()`, which will always be 0ns
-    /// as `Instant` subtraction saturates.
-    ///
-    /// `prev_instant.elapsed()` also more clearly signals intention.
-    ///
-    /// ### Example
-    /// ```rust
-    /// use std::time::Instant;
-    /// let prev_instant = Instant::now();
-    /// let duration = Instant::now() - prev_instant;
-    /// ```
-    /// Use instead:
-    /// ```rust
-    /// use std::time::Instant;
-    /// let prev_instant = Instant::now();
-    /// let duration = prev_instant.elapsed();
-    /// ```
-    #[clippy::version = "1.64.0"]
-    pub MANUAL_INSTANT_ELAPSED,
-    pedantic,
-    "subtraction between `Instant::now()` and previous `Instant`"
-}
-
-declare_lint_pass!(ManualInstantElapsed => [MANUAL_INSTANT_ELAPSED]);
-
-impl LateLintPass<'_> for ManualInstantElapsed {
-    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
-        if let ExprKind::Binary(Spanned {node: BinOpKind::Sub, ..}, lhs, rhs) = expr.kind
-            && check_instant_now_call(cx, lhs)
-            && let ty_resolved = cx.typeck_results().expr_ty(rhs)
-            && let rustc_middle::ty::Adt(def, _) = ty_resolved.kind()
-            && clippy_utils::match_def_path(cx, def.did(), &clippy_utils::paths::INSTANT)
-            && let Some(sugg) = clippy_utils::sugg::Sugg::hir_opt(cx, rhs)
-        {
-            span_lint_and_sugg(
-                cx,
-                MANUAL_INSTANT_ELAPSED,
-                expr.span,
-                "manual implementation of `Instant::elapsed`",
-                "try",
-                format!("{}.elapsed()", sugg.maybe_par()),
-                Applicability::MachineApplicable,
-            );
-        }
-    }
-}
-
-fn check_instant_now_call(cx: &LateContext<'_>, expr_block: &'_ Expr<'_>) -> bool {
-    if let ExprKind::Call(fn_expr, []) = expr_block.kind
-        && let Some(fn_id) = clippy_utils::path_def_id(cx, fn_expr)
-        && clippy_utils::match_def_path(cx, fn_id, &clippy_utils::paths::INSTANT_NOW)
-    {
-        true
-    } else {
-        false
-    }
-}
diff --git a/clippy_lints/src/manual_is_ascii_check.rs b/clippy_lints/src/manual_is_ascii_check.rs
new file mode 100644
index 00000000000..bb8c142f8e4
--- /dev/null
+++ b/clippy_lints/src/manual_is_ascii_check.rs
@@ -0,0 +1,158 @@
+use rustc_ast::LitKind::{Byte, Char};
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind, PatKind, RangeEnd};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_semver::RustcVersion;
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::{def_id::DefId, sym};
+
+use clippy_utils::{
+    diagnostics::span_lint_and_sugg, in_constant, macros::root_macro_call, meets_msrv, msrvs, source::snippet,
+};
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Suggests to use dedicated built-in methods,
+    /// `is_ascii_(lowercase|uppercase|digit)` for checking on corresponding ascii range
+    ///
+    /// ### Why is this bad?
+    /// Using the built-in functions is more readable and makes it
+    /// clear that it's not a specific subset of characters, but all
+    /// ASCII (lowercase|uppercase|digit) characters.
+    /// ### Example
+    /// ```rust
+    /// fn main() {
+    ///     assert!(matches!('x', 'a'..='z'));
+    ///     assert!(matches!(b'X', b'A'..=b'Z'));
+    ///     assert!(matches!('2', '0'..='9'));
+    ///     assert!(matches!('x', 'A'..='Z' | 'a'..='z'));
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// fn main() {
+    ///     assert!('x'.is_ascii_lowercase());
+    ///     assert!(b'X'.is_ascii_uppercase());
+    ///     assert!('2'.is_ascii_digit());
+    ///     assert!('x'.is_ascii_alphabetic());
+    /// }
+    /// ```
+    #[clippy::version = "1.66.0"]
+    pub MANUAL_IS_ASCII_CHECK,
+    style,
+    "use dedicated method to check ascii range"
+}
+impl_lint_pass!(ManualIsAsciiCheck => [MANUAL_IS_ASCII_CHECK]);
+
+pub struct ManualIsAsciiCheck {
+    msrv: Option<RustcVersion>,
+}
+
+impl ManualIsAsciiCheck {
+    #[must_use]
+    pub fn new(msrv: Option<RustcVersion>) -> Self {
+        Self { msrv }
+    }
+}
+
+#[derive(Debug, PartialEq)]
+enum CharRange {
+    /// 'a'..='z' | b'a'..=b'z'
+    LowerChar,
+    /// 'A'..='Z' | b'A'..=b'Z'
+    UpperChar,
+    /// AsciiLower | AsciiUpper
+    FullChar,
+    /// '0..=9'
+    Digit,
+    Otherwise,
+}
+
+impl<'tcx> LateLintPass<'tcx> for ManualIsAsciiCheck {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+        if !meets_msrv(self.msrv, msrvs::IS_ASCII_DIGIT) {
+            return;
+        }
+
+        if in_constant(cx, expr.hir_id) && !meets_msrv(self.msrv, msrvs::IS_ASCII_DIGIT_CONST) {
+            return;
+        }
+
+        let Some(macro_call) = root_macro_call(expr.span) else { return };
+
+        if is_matches_macro(cx, macro_call.def_id) {
+            if let ExprKind::Match(recv, [arm, ..], _) = expr.kind {
+                let range = check_pat(&arm.pat.kind);
+
+                if let Some(sugg) = match range {
+                    CharRange::UpperChar => Some("is_ascii_uppercase"),
+                    CharRange::LowerChar => Some("is_ascii_lowercase"),
+                    CharRange::FullChar => Some("is_ascii_alphabetic"),
+                    CharRange::Digit => Some("is_ascii_digit"),
+                    CharRange::Otherwise => None,
+                } {
+                    let default_snip = "..";
+                    // `snippet_with_applicability` may set applicability to `MaybeIncorrect` for
+                    // macro span, so we check applicability manually by comparing `recv` is not default.
+                    let recv = snippet(cx, recv.span, default_snip);
+
+                    let applicability = if recv == default_snip {
+                        Applicability::HasPlaceholders
+                    } else {
+                        Applicability::MachineApplicable
+                    };
+
+                    span_lint_and_sugg(
+                        cx,
+                        MANUAL_IS_ASCII_CHECK,
+                        macro_call.span,
+                        "manual check for common ascii range",
+                        "try",
+                        format!("{recv}.{sugg}()"),
+                        applicability,
+                    );
+                }
+            }
+        }
+    }
+
+    extract_msrv_attr!(LateContext);
+}
+
+fn check_pat(pat_kind: &PatKind<'_>) -> CharRange {
+    match pat_kind {
+        PatKind::Or(pats) => {
+            let ranges = pats.iter().map(|p| check_pat(&p.kind)).collect::<Vec<_>>();
+
+            if ranges.len() == 2 && ranges.contains(&CharRange::UpperChar) && ranges.contains(&CharRange::LowerChar) {
+                CharRange::FullChar
+            } else {
+                CharRange::Otherwise
+            }
+        },
+        PatKind::Range(Some(start), Some(end), kind) if *kind == RangeEnd::Included => check_range(start, end),
+        _ => CharRange::Otherwise,
+    }
+}
+
+fn check_range(start: &Expr<'_>, end: &Expr<'_>) -> CharRange {
+    if let ExprKind::Lit(start_lit) = &start.kind
+        && let ExprKind::Lit(end_lit) = &end.kind {
+        match (&start_lit.node, &end_lit.node) {
+            (Char('a'), Char('z')) | (Byte(b'a'), Byte(b'z')) => CharRange::LowerChar,
+            (Char('A'), Char('Z')) | (Byte(b'A'), Byte(b'Z')) => CharRange::UpperChar,
+            (Char('0'), Char('9')) | (Byte(b'0'), Byte(b'9')) => CharRange::Digit,
+            _ => CharRange::Otherwise,
+        }
+    } else {
+        CharRange::Otherwise
+    }
+}
+
+fn is_matches_macro(cx: &LateContext<'_>, macro_def_id: DefId) -> bool {
+    if let Some(name) = cx.tcx.get_diagnostic_name(macro_def_id) {
+        return sym::matches_macro == name;
+    }
+
+    false
+}
diff --git a/clippy_lints/src/manual_let_else.rs b/clippy_lints/src/manual_let_else.rs
new file mode 100644
index 00000000000..1846596fa4c
--- /dev/null
+++ b/clippy_lints/src/manual_let_else.rs
@@ -0,0 +1,297 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::higher::IfLetOrMatch;
+use clippy_utils::source::snippet_opt;
+use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::visitors::{for_each_expr, Descend};
+use clippy_utils::{meets_msrv, msrvs, peel_blocks};
+use if_chain::if_chain;
+use rustc_data_structures::fx::FxHashSet;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind, MatchSource, Pat, PatKind, QPath, Stmt, StmtKind};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_middle::lint::in_external_macro;
+use rustc_semver::RustcVersion;
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::symbol::sym;
+use rustc_span::Span;
+use serde::Deserialize;
+use std::ops::ControlFlow;
+
+declare_clippy_lint! {
+    /// ### What it does
+    ///
+    /// Warn of cases where `let...else` could be used
+    ///
+    /// ### Why is this bad?
+    ///
+    /// `let...else` provides a standard construct for this pattern
+    /// that people can easily recognize. It's also more compact.
+    ///
+    /// ### Example
+    ///
+    /// ```rust
+    /// # let w = Some(0);
+    /// let v = if let Some(v) = w { v } else { return };
+    /// ```
+    ///
+    /// Could be written:
+    ///
+    /// ```rust
+    /// # #![feature(let_else)]
+    /// # fn main () {
+    /// # let w = Some(0);
+    /// let Some(v) = w else { return };
+    /// # }
+    /// ```
+    #[clippy::version = "1.67.0"]
+    pub MANUAL_LET_ELSE,
+    pedantic,
+    "manual implementation of a let...else statement"
+}
+
+pub struct ManualLetElse {
+    msrv: Option<RustcVersion>,
+    matches_behaviour: MatchLintBehaviour,
+}
+
+impl ManualLetElse {
+    #[must_use]
+    pub fn new(msrv: Option<RustcVersion>, matches_behaviour: MatchLintBehaviour) -> Self {
+        Self {
+            msrv,
+            matches_behaviour,
+        }
+    }
+}
+
+impl_lint_pass!(ManualLetElse => [MANUAL_LET_ELSE]);
+
+impl<'tcx> LateLintPass<'tcx> for ManualLetElse {
+    fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &'tcx Stmt<'tcx>) {
+        let if_let_or_match = if_chain! {
+            if meets_msrv(self.msrv, msrvs::LET_ELSE);
+            if !in_external_macro(cx.sess(), stmt.span);
+            if let StmtKind::Local(local) = stmt.kind;
+            if let Some(init) = local.init;
+            if local.els.is_none();
+            if local.ty.is_none();
+            if init.span.ctxt() == stmt.span.ctxt();
+            if let Some(if_let_or_match) = IfLetOrMatch::parse(cx, init);
+            then {
+                if_let_or_match
+            } else {
+                return;
+            }
+        };
+
+        match if_let_or_match {
+            IfLetOrMatch::IfLet(if_let_expr, let_pat, if_then, if_else) => if_chain! {
+                if expr_is_simple_identity(let_pat, if_then);
+                if let Some(if_else) = if_else;
+                if expr_diverges(cx, if_else);
+                then {
+                    emit_manual_let_else(cx, stmt.span, if_let_expr, let_pat, if_else);
+                }
+            },
+            IfLetOrMatch::Match(match_expr, arms, source) => {
+                if self.matches_behaviour == MatchLintBehaviour::Never {
+                    return;
+                }
+                if source != MatchSource::Normal {
+                    return;
+                }
+                // Any other number than two arms doesn't (neccessarily)
+                // have a trivial mapping to let else.
+                if arms.len() != 2 {
+                    return;
+                }
+                // Guards don't give us an easy mapping either
+                if arms.iter().any(|arm| arm.guard.is_some()) {
+                    return;
+                }
+                let check_types = self.matches_behaviour == MatchLintBehaviour::WellKnownTypes;
+                let diverging_arm_opt = arms
+                    .iter()
+                    .enumerate()
+                    .find(|(_, arm)| expr_diverges(cx, arm.body) && pat_allowed_for_else(cx, arm.pat, check_types));
+                let Some((idx, diverging_arm)) = diverging_arm_opt else { return; };
+                let pat_arm = &arms[1 - idx];
+                if !expr_is_simple_identity(pat_arm.pat, pat_arm.body) {
+                    return;
+                }
+
+                emit_manual_let_else(cx, stmt.span, match_expr, pat_arm.pat, diverging_arm.body);
+            },
+        }
+    }
+
+    extract_msrv_attr!(LateContext);
+}
+
+fn emit_manual_let_else(cx: &LateContext<'_>, span: Span, expr: &Expr<'_>, pat: &Pat<'_>, else_body: &Expr<'_>) {
+    span_lint_and_then(
+        cx,
+        MANUAL_LET_ELSE,
+        span,
+        "this could be rewritten as `let...else`",
+        |diag| {
+            // This is far from perfect, for example there needs to be:
+            // * mut additions for the bindings
+            // * renamings of the bindings
+            // * unused binding collision detection with existing ones
+            // * putting patterns with at the top level | inside ()
+            // for this to be machine applicable.
+            let app = Applicability::HasPlaceholders;
+
+            if let Some(sn_pat) = snippet_opt(cx, pat.span) &&
+                let Some(sn_expr) = snippet_opt(cx, expr.span) &&
+                let Some(sn_else) = snippet_opt(cx, else_body.span)
+            {
+                let else_bl = if matches!(else_body.kind, ExprKind::Block(..)) {
+                    sn_else
+                } else {
+                    format!("{{ {sn_else} }}")
+                };
+                let sugg = format!("let {sn_pat} = {sn_expr} else {else_bl};");
+                diag.span_suggestion(span, "consider writing", sugg, app);
+            }
+        },
+    );
+}
+
+fn expr_diverges(cx: &LateContext<'_>, expr: &'_ Expr<'_>) -> bool {
+    fn is_never(cx: &LateContext<'_>, expr: &'_ Expr<'_>) -> bool {
+        if let Some(ty) = cx.typeck_results().expr_ty_opt(expr) {
+            return ty.is_never();
+        }
+        false
+    }
+    // We can't just call is_never on expr and be done, because the type system
+    // sometimes coerces the ! type to something different before we can get
+    // our hands on it. So instead, we do a manual search. We do fall back to
+    // is_never in some places when there is no better alternative.
+    for_each_expr(expr, |ex| {
+        match ex.kind {
+            ExprKind::Continue(_) | ExprKind::Break(_, _) | ExprKind::Ret(_) => ControlFlow::Break(()),
+            ExprKind::Call(call, _) => {
+                if is_never(cx, ex) || is_never(cx, call) {
+                    return ControlFlow::Break(());
+                }
+                ControlFlow::Continue(Descend::Yes)
+            },
+            ExprKind::MethodCall(..) => {
+                if is_never(cx, ex) {
+                    return ControlFlow::Break(());
+                }
+                ControlFlow::Continue(Descend::Yes)
+            },
+            ExprKind::If(if_expr, if_then, if_else) => {
+                let else_diverges = if_else.map_or(false, |ex| expr_diverges(cx, ex));
+                let diverges = expr_diverges(cx, if_expr) || (else_diverges && expr_diverges(cx, if_then));
+                if diverges {
+                    return ControlFlow::Break(());
+                }
+                ControlFlow::Continue(Descend::No)
+            },
+            ExprKind::Match(match_expr, match_arms, _) => {
+                let diverges = expr_diverges(cx, match_expr)
+                    || match_arms.iter().all(|arm| {
+                        let guard_diverges = arm.guard.as_ref().map_or(false, |g| expr_diverges(cx, g.body()));
+                        guard_diverges || expr_diverges(cx, arm.body)
+                    });
+                if diverges {
+                    return ControlFlow::Break(());
+                }
+                ControlFlow::Continue(Descend::No)
+            },
+
+            // Don't continue into loops or labeled blocks, as they are breakable,
+            // and we'd have to start checking labels.
+            ExprKind::Block(_, Some(_)) | ExprKind::Loop(..) => ControlFlow::Continue(Descend::No),
+
+            // Default: descend
+            _ => ControlFlow::Continue(Descend::Yes),
+        }
+    })
+    .is_some()
+}
+
+fn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>, check_types: bool) -> bool {
+    // Check whether the pattern contains any bindings, as the
+    // binding might potentially be used in the body.
+    // TODO: only look for *used* bindings.
+    let mut has_bindings = false;
+    pat.each_binding_or_first(&mut |_, _, _, _| has_bindings = true);
+    if has_bindings {
+        return false;
+    }
+
+    // If we shouldn't check the types, exit early.
+    if !check_types {
+        return true;
+    }
+
+    // Check whether any possibly "unknown" patterns are included,
+    // because users might not know which values some enum has.
+    // Well-known enums are excepted, as we assume people know them.
+    // We do a deep check, to be able to disallow Err(En::Foo(_))
+    // for usage of the En::Foo variant, as we disallow En::Foo(_),
+    // but we allow Err(_).
+    let typeck_results = cx.typeck_results();
+    let mut has_disallowed = false;
+    pat.walk_always(|pat| {
+        // Only do the check if the type is "spelled out" in the pattern
+        if !matches!(
+            pat.kind,
+            PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..)
+        ) {
+            return;
+        };
+        let ty = typeck_results.pat_ty(pat);
+        // Option and Result are allowed, everything else isn't.
+        if !(is_type_diagnostic_item(cx, ty, sym::Option) || is_type_diagnostic_item(cx, ty, sym::Result)) {
+            has_disallowed = true;
+        }
+    });
+    !has_disallowed
+}
+
+/// Checks if the passed block is a simple identity referring to bindings created by the pattern
+fn expr_is_simple_identity(pat: &'_ Pat<'_>, expr: &'_ Expr<'_>) -> bool {
+    // We support patterns with multiple bindings and tuples, like:
+    //   let ... = if let (Some(foo), bar) = g() { (foo, bar) } else { ... }
+    let peeled = peel_blocks(expr);
+    let paths = match peeled.kind {
+        ExprKind::Tup(exprs) | ExprKind::Array(exprs) => exprs,
+        ExprKind::Path(_) => std::slice::from_ref(peeled),
+        _ => return false,
+    };
+    let mut pat_bindings = FxHashSet::default();
+    pat.each_binding_or_first(&mut |_ann, _hir_id, _sp, ident| {
+        pat_bindings.insert(ident);
+    });
+    if pat_bindings.len() < paths.len() {
+        return false;
+    }
+    for path in paths {
+        if_chain! {
+            if let ExprKind::Path(QPath::Resolved(_ty, path)) = path.kind;
+            if let [path_seg] = path.segments;
+            then {
+                if !pat_bindings.remove(&path_seg.ident) {
+                    return false;
+                }
+            } else {
+                return false;
+            }
+        }
+    }
+    true
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize)]
+pub enum MatchLintBehaviour {
+    AllTypes,
+    WellKnownTypes,
+    Never,
+}
diff --git a/clippy_lints/src/map_unit_fn.rs b/clippy_lints/src/map_unit_fn.rs
index 32da37a862d..59195d1ae4e 100644
--- a/clippy_lints/src/map_unit_fn.rs
+++ b/clippy_lints/src/map_unit_fn.rs
@@ -119,7 +119,7 @@ fn is_unit_expression(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
 /// semicolons, which causes problems when generating a suggestion. Given an
 /// expression that evaluates to '()' or '!', recursively remove useless braces
 /// and semi-colons until is suitable for including in the suggestion template
-fn reduce_unit_expression<'a>(cx: &LateContext<'_>, expr: &'a hir::Expr<'_>) -> Option<Span> {
+fn reduce_unit_expression(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Span> {
     if !is_unit_expression(cx, expr) {
         return None;
     }
diff --git a/clippy_lints/src/matches/infallible_destructuring_match.rs b/clippy_lints/src/matches/infallible_destructuring_match.rs
index 2472acb6f6e..d18c92caba2 100644
--- a/clippy_lints/src/matches/infallible_destructuring_match.rs
+++ b/clippy_lints/src/matches/infallible_destructuring_match.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::{path_to_local_id, peel_blocks, strip_pat_refs};
 use rustc_errors::Applicability;
-use rustc_hir::{ExprKind, Local, MatchSource, PatKind, QPath};
+use rustc_hir::{ByRef, ExprKind, Local, MatchSource, PatKind, QPath};
 use rustc_lint::LateContext;
 
 use super::INFALLIBLE_DESTRUCTURING_MATCH;
@@ -16,7 +16,7 @@ pub(crate) fn check(cx: &LateContext<'_>, local: &Local<'_>) -> bool {
         if let PatKind::TupleStruct(
             QPath::Resolved(None, variant_name), args, _) = arms[0].pat.kind;
         if args.len() == 1;
-        if let PatKind::Binding(_, arg, ..) = strip_pat_refs(&args[0]).kind;
+        if let PatKind::Binding(binding, arg, ..) = strip_pat_refs(&args[0]).kind;
         let body = peel_blocks(arms[0].body);
         if path_to_local_id(body, arg);
 
@@ -30,8 +30,9 @@ pub(crate) fn check(cx: &LateContext<'_>, local: &Local<'_>) -> bool {
                 Consider using `let`",
                 "try this",
                 format!(
-                    "let {}({}) = {};",
+                    "let {}({}{}) = {};",
                     snippet_with_applicability(cx, variant_name.span, "..", &mut applicability),
+                    if binding.0 == ByRef::Yes { "ref " } else { "" },
                     snippet_with_applicability(cx, local.pat.span, "..", &mut applicability),
                     snippet_with_applicability(cx, target.span, "..", &mut applicability),
                 ),
diff --git a/clippy_lints/src/matches/manual_filter.rs b/clippy_lints/src/matches/manual_filter.rs
index 66ba1f6f9c5..d521a529e0d 100644
--- a/clippy_lints/src/matches/manual_filter.rs
+++ b/clippy_lints/src/matches/manual_filter.rs
@@ -62,7 +62,7 @@ fn peels_blocks_incl_unsafe<'a>(expr: &'a Expr<'a>) -> &'a Expr<'a> {
 //    <expr>
 // }
 // Returns true if <expr> resolves to `Some(x)`, `false` otherwise
-fn is_some_expr<'tcx>(cx: &LateContext<'_>, target: HirId, ctxt: SyntaxContext, expr: &'tcx Expr<'_>) -> bool {
+fn is_some_expr(cx: &LateContext<'_>, target: HirId, ctxt: SyntaxContext, expr: &Expr<'_>) -> bool {
     if let Some(inner_expr) = peels_blocks_incl_unsafe_opt(expr) {
         // there can be not statements in the block as they would be removed when switching to `.filter`
         if let ExprKind::Call(callee, [arg]) = inner_expr.kind {
diff --git a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
index 85269e533a0..f587c69f730 100644
--- a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
+++ b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
@@ -83,8 +83,8 @@ fn set_diagnostic<'tcx>(diag: &mut Diagnostic, cx: &LateContext<'tcx>, expr: &'t
 
 /// If the expression is an `ExprKind::Match`, check if the scrutinee has a significant drop that
 /// may have a surprising lifetime.
-fn has_significant_drop_in_scrutinee<'tcx, 'a>(
-    cx: &'a LateContext<'tcx>,
+fn has_significant_drop_in_scrutinee<'tcx>(
+    cx: &LateContext<'tcx>,
     scrutinee: &'tcx Expr<'tcx>,
     source: MatchSource,
 ) -> Option<(Vec<FoundSigDrop>, &'static str)> {
@@ -226,7 +226,7 @@ impl<'a, 'tcx> SigDropHelper<'a, 'tcx> {
     /// This will try to set the current suggestion (so it can be moved into the suggestions vec
     /// later). If `allow_move_and_clone` is false, the suggestion *won't* be set -- this gives us
     /// an opportunity to look for another type in the chain that will be trivially copyable.
-    /// However, if we are at the the end of the chain, we want to accept whatever is there. (The
+    /// However, if we are at the end of the chain, we want to accept whatever is there. (The
     /// suggestion won't actually be output, but the diagnostic message will be output, so the user
     /// can determine the best way to handle the lint.)
     fn try_setting_current_suggestion(&mut self, expr: &'tcx Expr<'_>, allow_move_and_clone: bool) {
@@ -377,7 +377,7 @@ impl<'a, 'tcx> ArmSigDropHelper<'a, 'tcx> {
     }
 }
 
-fn has_significant_drop_in_arms<'tcx, 'a>(cx: &'a LateContext<'tcx>, arms: &'tcx [Arm<'_>]) -> FxHashSet<Span> {
+fn has_significant_drop_in_arms<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) -> FxHashSet<Span> {
     let mut helper = ArmSigDropHelper::new(cx);
     for arm in arms {
         helper.visit_expr(arm.body);
diff --git a/clippy_lints/src/matches/single_match.rs b/clippy_lints/src/matches/single_match.rs
index e5a15b2e1a1..19b49c44d57 100644
--- a/clippy_lints/src/matches/single_match.rs
+++ b/clippy_lints/src/matches/single_match.rs
@@ -153,7 +153,7 @@ fn pat_in_candidate_enum<'a>(cx: &LateContext<'a>, ty: Ty<'a>, pat: &Pat<'_>) ->
 }
 
 /// Returns `true` if the given type is an enum we know won't be expanded in the future
-fn in_candidate_enum<'a>(cx: &LateContext<'a>, ty: Ty<'_>) -> bool {
+fn in_candidate_enum(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
     // list of candidate `Enum`s we know will never get any more members
     let candidates = [sym::Cow, sym::Option, sym::Result];
 
diff --git a/clippy_lints/src/methods/chars_cmp_with_unwrap.rs b/clippy_lints/src/methods/chars_cmp_with_unwrap.rs
index 7e808760663..27a05337a29 100644
--- a/clippy_lints/src/methods/chars_cmp_with_unwrap.rs
+++ b/clippy_lints/src/methods/chars_cmp_with_unwrap.rs
@@ -9,8 +9,8 @@ use rustc_lint::LateContext;
 use rustc_lint::Lint;
 
 /// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints with `unwrap()`.
-pub(super) fn check<'tcx>(
-    cx: &LateContext<'tcx>,
+pub(super) fn check(
+    cx: &LateContext<'_>,
     info: &crate::methods::BinaryExprInfo<'_>,
     chain_methods: &[&str],
     lint: &'static Lint,
diff --git a/clippy_lints/src/methods/chars_last_cmp.rs b/clippy_lints/src/methods/chars_last_cmp.rs
index 07bbc5ca1bf..2efff4c3c54 100644
--- a/clippy_lints/src/methods/chars_last_cmp.rs
+++ b/clippy_lints/src/methods/chars_last_cmp.rs
@@ -4,7 +4,7 @@ use rustc_lint::LateContext;
 use super::CHARS_LAST_CMP;
 
 /// Checks for the `CHARS_LAST_CMP` lint.
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
+pub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
     if chars_cmp::check(cx, info, &["chars", "last"], CHARS_LAST_CMP, "ends_with") {
         true
     } else {
diff --git a/clippy_lints/src/methods/chars_last_cmp_with_unwrap.rs b/clippy_lints/src/methods/chars_last_cmp_with_unwrap.rs
index c29ee0ec8c8..5b8713f7d79 100644
--- a/clippy_lints/src/methods/chars_last_cmp_with_unwrap.rs
+++ b/clippy_lints/src/methods/chars_last_cmp_with_unwrap.rs
@@ -4,7 +4,7 @@ use rustc_lint::LateContext;
 use super::CHARS_LAST_CMP;
 
 /// Checks for the `CHARS_LAST_CMP` lint with `unwrap()`.
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
+pub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
     if chars_cmp_with_unwrap::check(cx, info, &["chars", "last", "unwrap"], CHARS_LAST_CMP, "ends_with") {
         true
     } else {
diff --git a/clippy_lints/src/methods/chars_next_cmp.rs b/clippy_lints/src/methods/chars_next_cmp.rs
index a6701d8830e..b631fecab97 100644
--- a/clippy_lints/src/methods/chars_next_cmp.rs
+++ b/clippy_lints/src/methods/chars_next_cmp.rs
@@ -3,6 +3,6 @@ use rustc_lint::LateContext;
 use super::CHARS_NEXT_CMP;
 
 /// Checks for the `CHARS_NEXT_CMP` lint.
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
+pub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
     crate::methods::chars_cmp::check(cx, info, &["chars", "next"], CHARS_NEXT_CMP, "starts_with")
 }
diff --git a/clippy_lints/src/methods/chars_next_cmp_with_unwrap.rs b/clippy_lints/src/methods/chars_next_cmp_with_unwrap.rs
index 28ede28e935..caf21d3ff3b 100644
--- a/clippy_lints/src/methods/chars_next_cmp_with_unwrap.rs
+++ b/clippy_lints/src/methods/chars_next_cmp_with_unwrap.rs
@@ -3,6 +3,6 @@ use rustc_lint::LateContext;
 use super::CHARS_NEXT_CMP;
 
 /// Checks for the `CHARS_NEXT_CMP` lint with `unwrap()`.
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
+pub(super) fn check(cx: &LateContext<'_>, info: &crate::methods::BinaryExprInfo<'_>) -> bool {
     crate::methods::chars_cmp_with_unwrap::check(cx, info, &["chars", "next", "unwrap"], CHARS_NEXT_CMP, "starts_with")
 }
diff --git a/clippy_lints/src/methods/collapsible_str_replace.rs b/clippy_lints/src/methods/collapsible_str_replace.rs
index 501646863fe..ac61b437788 100644
--- a/clippy_lints/src/methods/collapsible_str_replace.rs
+++ b/clippy_lints/src/methods/collapsible_str_replace.rs
@@ -23,7 +23,7 @@ pub(super) fn check<'tcx>(
         // If the parent node's `to` argument is the same as the `to` argument
         // of the last replace call in the current chain, don't lint as it was already linted
         if let Some(parent) = get_parent_expr(cx, expr)
-            && let Some(("replace", _, [current_from, current_to], _)) = method_call(parent)
+            && let Some(("replace", _, [current_from, current_to], _, _)) = method_call(parent)
             && eq_expr_value(cx, to, current_to)
             && from_kind == cx.typeck_results().expr_ty(current_from).peel_refs().kind()
         {
@@ -48,7 +48,7 @@ fn collect_replace_calls<'tcx>(
     let mut from_args = VecDeque::new();
 
     let _: Option<()> = for_each_expr(expr, |e| {
-        if let Some(("replace", _, [from, to], _)) = method_call(e) {
+        if let Some(("replace", _, [from, to], _, _)) = method_call(e) {
             if eq_expr_value(cx, to_arg, to) && cx.typeck_results().expr_ty(from).peel_refs().is_char() {
                 methods.push_front(e);
                 from_args.push_front(from);
@@ -78,7 +78,7 @@ fn check_consecutive_replace_calls<'tcx>(
         .collect();
     let app = Applicability::MachineApplicable;
     let earliest_replace_call = replace_methods.methods.front().unwrap();
-    if let Some((_, _, [..], span_lo)) = method_call(earliest_replace_call) {
+    if let Some((_, _, [..], span_lo, _)) = method_call(earliest_replace_call) {
         span_lint_and_sugg(
             cx,
             COLLAPSIBLE_STR_REPLACE,
diff --git a/clippy_lints/src/methods/expect_used.rs b/clippy_lints/src/methods/expect_used.rs
index d59fefa1ddc..cce8f797e98 100644
--- a/clippy_lints/src/methods/expect_used.rs
+++ b/clippy_lints/src/methods/expect_used.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::is_in_test_function;
+use clippy_utils::is_in_cfg_test;
 use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
@@ -18,16 +18,16 @@ pub(super) fn check(
     let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
 
     let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) && !is_err {
-        Some((EXPECT_USED, "an Option", "None", ""))
+        Some((EXPECT_USED, "an `Option`", "None", ""))
     } else if is_type_diagnostic_item(cx, obj_ty, sym::Result) {
-        Some((EXPECT_USED, "a Result", if is_err { "Ok" } else { "Err" }, "an "))
+        Some((EXPECT_USED, "a `Result`", if is_err { "Ok" } else { "Err" }, "an "))
     } else {
         None
     };
 
     let method = if is_err { "expect_err" } else { "expect" };
 
-    if allow_expect_in_tests && is_in_test_function(cx.tcx, expr.hir_id) {
+    if allow_expect_in_tests && is_in_cfg_test(cx.tcx, expr.hir_id) {
         return;
     }
 
@@ -36,7 +36,7 @@ pub(super) fn check(
             cx,
             lint,
             expr.span,
-            &format!("used `{method}()` on `{kind}` value"),
+            &format!("used `{method}()` on {kind} value"),
             None,
             &format!("if this value is {none_prefix}`{none_value}`, it will panic"),
         );
diff --git a/clippy_lints/src/methods/filter_map.rs b/clippy_lints/src/methods/filter_map.rs
index 9719b2f1c51..f888c58a72d 100644
--- a/clippy_lints/src/methods/filter_map.rs
+++ b/clippy_lints/src/methods/filter_map.rs
@@ -17,7 +17,7 @@ use super::MANUAL_FILTER_MAP;
 use super::MANUAL_FIND_MAP;
 use super::OPTION_FILTER_MAP;
 
-fn is_method<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_name: Symbol) -> bool {
+fn is_method(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_name: Symbol) -> bool {
     match &expr.kind {
         hir::ExprKind::Path(QPath::TypeRelative(_, mname)) => mname.ident.name == method_name,
         hir::ExprKind::Path(QPath::Resolved(_, segments)) => {
@@ -46,7 +46,7 @@ fn is_method<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, method_name: Sy
     }
 }
 
-fn is_option_filter_map<'tcx>(cx: &LateContext<'tcx>, filter_arg: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) -> bool {
+fn is_option_filter_map(cx: &LateContext<'_>, filter_arg: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) -> bool {
     is_method(cx, map_arg, sym::unwrap) && is_method(cx, filter_arg, sym!(is_some))
 }
 
@@ -66,8 +66,8 @@ fn is_filter_some_map_unwrap(
 
 /// lint use of `filter().map()` or `find().map()` for `Iterators`
 #[allow(clippy::too_many_arguments)]
-pub(super) fn check<'tcx>(
-    cx: &LateContext<'tcx>,
+pub(super) fn check(
+    cx: &LateContext<'_>,
     expr: &hir::Expr<'_>,
     filter_recv: &hir::Expr<'_>,
     filter_arg: &hir::Expr<'_>,
diff --git a/clippy_lints/src/methods/inefficient_to_string.rs b/clippy_lints/src/methods/inefficient_to_string.rs
index 4f4f543e8a9..d8c821bc9ee 100644
--- a/clippy_lints/src/methods/inefficient_to_string.rs
+++ b/clippy_lints/src/methods/inefficient_to_string.rs
@@ -12,8 +12,8 @@ use rustc_span::symbol::{Symbol, sym};
 use super::INEFFICIENT_TO_STRING;
 
 /// Checks for the `INEFFICIENT_TO_STRING` lint
-pub fn check<'tcx>(
-    cx: &LateContext<'tcx>,
+pub fn check(
+    cx: &LateContext<'_>,
     expr: &hir::Expr<'_>,
     method_name: Symbol,
     receiver: &hir::Expr<'_>,
diff --git a/clippy_lints/src/methods/iter_nth_zero.rs b/clippy_lints/src/methods/iter_nth_zero.rs
index 68d906c3ea3..c830958d5c8 100644
--- a/clippy_lints/src/methods/iter_nth_zero.rs
+++ b/clippy_lints/src/methods/iter_nth_zero.rs
@@ -10,7 +10,7 @@ use rustc_span::sym;
 
 use super::ITER_NTH_ZERO;
 
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
+pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>) {
     if_chain! {
         if is_trait_method(cx, expr, sym::Iterator);
         if let Some((Constant::Int(0), _)) = constant(cx, cx.typeck_results(), arg);
diff --git a/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs b/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
index 4f73b3ec422..70abe4891d9 100644
--- a/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
+++ b/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
@@ -25,7 +25,7 @@ impl IterType {
     }
 }
 
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, method_name: &str, recv: &Expr<'_>) {
+pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: &str, recv: &Expr<'_>) {
     let item = match recv.kind {
         ExprKind::Array([]) => None,
         ExprKind::Array([e]) => Some(e),
diff --git a/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/clippy_lints/src/methods/manual_saturating_arithmetic.rs
index b80541b8647..a7284c64497 100644
--- a/clippy_lints/src/methods/manual_saturating_arithmetic.rs
+++ b/clippy_lints/src/methods/manual_saturating_arithmetic.rs
@@ -67,7 +67,7 @@ enum MinMax {
     Max,
 }
 
-fn is_min_or_max<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>) -> Option<MinMax> {
+fn is_min_or_max(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<MinMax> {
     // `T::max_value()` `T::min_value()` inherent methods
     if_chain! {
         if let hir::ExprKind::Call(func, args) = &expr.kind;
diff --git a/clippy_lints/src/methods/manual_str_repeat.rs b/clippy_lints/src/methods/manual_str_repeat.rs
index 13c47c03a80..a08f7254053 100644
--- a/clippy_lints/src/methods/manual_str_repeat.rs
+++ b/clippy_lints/src/methods/manual_str_repeat.rs
@@ -59,10 +59,8 @@ pub(super) fn check(
         if let ExprKind::Call(repeat_fn, [repeat_arg]) = take_self_arg.kind;
         if is_path_diagnostic_item(cx, repeat_fn, sym::iter_repeat);
         if is_type_lang_item(cx, cx.typeck_results().expr_ty(collect_expr), LangItem::String);
-        if let Some(collect_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id);
         if let Some(take_id) = cx.typeck_results().type_dependent_def_id(take_expr.hir_id);
         if let Some(iter_trait_id) = cx.tcx.get_diagnostic_item(sym::Iterator);
-        if cx.tcx.trait_of_item(collect_id) == Some(iter_trait_id);
         if cx.tcx.trait_of_item(take_id) == Some(iter_trait_id);
         if let Some(repeat_kind) = parse_repeat_arg(cx, repeat_arg);
         let ctxt = collect_expr.span.ctxt();
diff --git a/clippy_lints/src/methods/map_clone.rs b/clippy_lints/src/methods/map_clone.rs
index 7ce14ec080b..6bc783c6d50 100644
--- a/clippy_lints/src/methods/map_clone.rs
+++ b/clippy_lints/src/methods/map_clone.rs
@@ -15,11 +15,11 @@ use rustc_span::{sym, Span};
 
 use super::MAP_CLONE;
 
-pub(super) fn check<'tcx>(
+pub(super) fn check(
     cx: &LateContext<'_>,
     e: &hir::Expr<'_>,
     recv: &hir::Expr<'_>,
-    arg: &'tcx hir::Expr<'_>,
+    arg: &hir::Expr<'_>,
     msrv: Option<RustcVersion>,
 ) {
     if_chain! {
diff --git a/clippy_lints/src/methods/map_collect_result_unit.rs b/clippy_lints/src/methods/map_collect_result_unit.rs
index d420f144eea..a0300d27870 100644
--- a/clippy_lints/src/methods/map_collect_result_unit.rs
+++ b/clippy_lints/src/methods/map_collect_result_unit.rs
@@ -1,5 +1,4 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::is_trait_method;
 use clippy_utils::source::snippet;
 use clippy_utils::ty::is_type_diagnostic_item;
 use if_chain::if_chain;
@@ -11,18 +10,10 @@ use rustc_span::symbol::sym;
 
 use super::MAP_COLLECT_RESULT_UNIT;
 
-pub(super) fn check(
-    cx: &LateContext<'_>,
-    expr: &hir::Expr<'_>,
-    iter: &hir::Expr<'_>,
-    map_fn: &hir::Expr<'_>,
-    collect_recv: &hir::Expr<'_>,
-) {
+pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, iter: &hir::Expr<'_>, map_fn: &hir::Expr<'_>) {
+    // return of collect `Result<(),_>`
+    let collect_ret_ty = cx.typeck_results().expr_ty(expr);
     if_chain! {
-        // called on Iterator
-        if is_trait_method(cx, collect_recv, sym::Iterator);
-        // return of collect `Result<(),_>`
-        let collect_ret_ty = cx.typeck_results().expr_ty(expr);
         if is_type_diagnostic_item(cx, collect_ret_ty, sym::Result);
         if let ty::Adt(_, substs) = collect_ret_ty.kind();
         if let Some(result_t) = substs.types().next();
diff --git a/clippy_lints/src/methods/map_err_ignore.rs b/clippy_lints/src/methods/map_err_ignore.rs
index 1fb6617145e..b773b3e423f 100644
--- a/clippy_lints/src/methods/map_err_ignore.rs
+++ b/clippy_lints/src/methods/map_err_ignore.rs
@@ -6,7 +6,7 @@ use rustc_span::sym;
 
 use super::MAP_ERR_IGNORE;
 
-pub(super) fn check<'tcx>(cx: &LateContext<'_>, e: &Expr<'_>, arg: &'tcx Expr<'_>) {
+pub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, arg: &Expr<'_>) {
     if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
         && let Some(impl_id) = cx.tcx.impl_of_method(method_id)
         && is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id), sym::Result)
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index 8a76ba0b064..38165ab4fb2 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -54,6 +54,7 @@ mod map_flatten;
 mod map_identity;
 mod map_unwrap_or;
 mod mut_mutex_lock;
+mod needless_collect;
 mod needless_option_as_deref;
 mod needless_option_take;
 mod no_effect_replace;
@@ -69,6 +70,8 @@ mod path_buf_push_overwrite;
 mod range_zip_with_len;
 mod repeat_once;
 mod search_is_some;
+mod seek_from_current;
+mod seek_to_start_instead_of_rewind;
 mod single_char_add_str;
 mod single_char_insert_string;
 mod single_char_pattern;
@@ -101,12 +104,11 @@ mod zst_offset;
 use bind_instead_of_map::BindInsteadOfMap;
 use clippy_utils::consts::{constant, Constant};
 use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
-use clippy_utils::ty::{contains_adt_constructor, implements_trait, is_copy, is_type_diagnostic_item};
-use clippy_utils::{contains_return, is_trait_method, iter_input_pats, meets_msrv, msrvs, return_ty};
+use clippy_utils::ty::{contains_ty_adt_constructor_opaque, implements_trait, is_copy, is_type_diagnostic_item};
+use clippy_utils::{contains_return, is_bool, is_trait_method, iter_input_pats, meets_msrv, msrvs, return_ty};
 use if_chain::if_chain;
 use rustc_hir as hir;
-use rustc_hir::def::Res;
-use rustc_hir::{Expr, ExprKind, PrimTy, QPath, TraitItem, TraitItemKind};
+use rustc_hir::{Expr, ExprKind, TraitItem, TraitItemKind};
 use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
@@ -156,9 +158,9 @@ declare_clippy_lint! {
     /// ```
     /// Use instead:
     /// ```rust
-    /// let hello = "hesuo worpd".replace(&['s', 'u', 'p'], "l");
+    /// let hello = "hesuo worpd".replace(['s', 'u', 'p'], "l");
     /// ```
-    #[clippy::version = "1.64.0"]
+    #[clippy::version = "1.65.0"]
     pub COLLAPSIBLE_STR_REPLACE,
     perf,
     "collapse consecutive calls to str::replace (2 or more) into a single call"
@@ -829,32 +831,30 @@ declare_clippy_lint! {
     /// etc. instead.
     ///
     /// ### Why is this bad?
-    /// The function will always be called and potentially
-    /// allocate an object acting as the default.
+    /// The function will always be called. This is only bad if it allocates or
+    /// does some non-trivial amount of work.
     ///
     /// ### Known problems
-    /// If the function has side-effects, not calling it will
-    /// change the semantic of the program, but you shouldn't rely on that anyway.
+    /// If the function has side-effects, not calling it will change the
+    /// semantic of the program, but you shouldn't rely on that.
+    ///
+    /// The lint also cannot figure out whether the function you call is
+    /// actually expensive to call or not.
     ///
     /// ### Example
     /// ```rust
     /// # let foo = Some(String::new());
-    /// foo.unwrap_or(String::new());
+    /// foo.unwrap_or(String::from("empty"));
     /// ```
     ///
     /// Use instead:
     /// ```rust
     /// # let foo = Some(String::new());
-    /// foo.unwrap_or_else(String::new);
-    ///
-    /// // or
-    ///
-    /// # let foo = Some(String::new());
-    /// foo.unwrap_or_default();
+    /// foo.unwrap_or_else(|| String::from("empty"));
     /// ```
     #[clippy::version = "pre 1.29.0"]
     pub OR_FUN_CALL,
-    perf,
+    nursery,
     "using any `*or` method with a function call, which suggests `*or_else`"
 }
 
@@ -1728,7 +1728,7 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for usage of `_.as_ref().map(Deref::deref)` or it's aliases (such as String::as_str).
+    /// Checks for usage of `_.as_ref().map(Deref::deref)` or its aliases (such as String::as_str).
     ///
     /// ### Why is this bad?
     /// Readability, this can be written more concisely as
@@ -2094,8 +2094,7 @@ declare_clippy_lint! {
     /// let s = "Hello world!";
     /// let cow = Cow::Borrowed(s);
     ///
-    /// let data = cow.into_owned();
-    /// assert!(matches!(data, String))
+    /// let _data: String = cow.into_owned();
     /// ```
     #[clippy::version = "1.65.0"]
     pub SUSPICIOUS_TO_OWNED,
@@ -2426,7 +2425,7 @@ declare_clippy_lint! {
     /// ### Known problems
     ///
     /// The type of the resulting iterator might become incompatible with its usage
-    #[clippy::version = "1.64.0"]
+    #[clippy::version = "1.65.0"]
     pub ITER_ON_SINGLE_ITEMS,
     nursery,
     "Iterator for array of length 1"
@@ -2458,7 +2457,7 @@ declare_clippy_lint! {
     /// ### Known problems
     ///
     /// The type of the resulting iterator might become incompatible with its usage
-    #[clippy::version = "1.64.0"]
+    #[clippy::version = "1.65.0"]
     pub ITER_ON_EMPTY_COLLECTIONS,
     nursery,
     "Iterator for empty array"
@@ -3066,6 +3065,102 @@ declare_clippy_lint! {
     "iterating on map using `iter` when `keys` or `values` would do"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    ///
+    /// Checks an argument of `seek` method of `Seek` trait
+    /// and if it start seek from `SeekFrom::Current(0)`, suggests `stream_position` instead.
+    ///
+    /// ### Why is this bad?
+    ///
+    /// Readability. Use dedicated method.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,no_run
+    /// use std::fs::File;
+    /// use std::io::{self, Write, Seek, SeekFrom};
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let mut f = File::create("foo.txt")?;
+    ///     f.write_all(b"Hello")?;
+    ///     eprintln!("Written {} bytes", f.seek(SeekFrom::Current(0))?);
+    ///
+    ///     Ok(())
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust,no_run
+    /// use std::fs::File;
+    /// use std::io::{self, Write, Seek, SeekFrom};
+    ///
+    /// fn main() -> io::Result<()> {
+    ///     let mut f = File::create("foo.txt")?;
+    ///     f.write_all(b"Hello")?;
+    ///     eprintln!("Written {} bytes", f.stream_position()?);
+    ///
+    ///     Ok(())
+    /// }
+    /// ```
+    #[clippy::version = "1.66.0"]
+    pub SEEK_FROM_CURRENT,
+    complexity,
+    "use dedicated method for seek from current position"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    ///
+    /// Checks for jumps to the start of a stream that implements `Seek`
+    /// and uses the `seek` method providing `Start` as parameter.
+    ///
+    /// ### Why is this bad?
+    ///
+    /// Readability. There is a specific method that was implemented for
+    /// this exact scenario.
+    ///
+    /// ### Example
+    /// ```rust
+    /// # use std::io;
+    /// fn foo<T: io::Seek>(t: &mut T) {
+    ///     t.seek(io::SeekFrom::Start(0));
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// # use std::io;
+    /// fn foo<T: io::Seek>(t: &mut T) {
+    ///     t.rewind();
+    /// }
+    /// ```
+    #[clippy::version = "1.66.0"]
+    pub SEEK_TO_START_INSTEAD_OF_REWIND,
+    complexity,
+    "jumping to the start of stream using `seek` method"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for functions collecting an iterator when collect
+    /// is not needed.
+    ///
+    /// ### Why is this bad?
+    /// `collect` causes the allocation of a new data structure,
+    /// when this allocation may not be needed.
+    ///
+    /// ### Example
+    /// ```rust
+    /// # let iterator = vec![1].into_iter();
+    /// let len = iterator.clone().collect::<Vec<_>>().len();
+    /// // should be
+    /// let len = iterator.count();
+    /// ```
+    #[clippy::version = "1.30.0"]
+    pub NEEDLESS_COLLECT,
+    nursery,
+    "collecting an iterator when collect is not needed"
+}
+
 pub struct Methods {
     avoid_breaking_exported_api: bool,
     msrv: Option<RustcVersion>,
@@ -3190,16 +3285,19 @@ impl_lint_pass!(Methods => [
     VEC_RESIZE_TO_ZERO,
     VERBOSE_FILE_READS,
     ITER_KV_MAP,
+    SEEK_FROM_CURRENT,
+    SEEK_TO_START_INSTEAD_OF_REWIND,
+    NEEDLESS_COLLECT,
 ]);
 
 /// Extracts a method call name, args, and `Span` of the method name.
 fn method_call<'tcx>(
     recv: &'tcx hir::Expr<'tcx>,
-) -> Option<(&'tcx str, &'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], Span)> {
-    if let ExprKind::MethodCall(path, receiver, args, _) = recv.kind {
+) -> Option<(&'tcx str, &'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], Span, Span)> {
+    if let ExprKind::MethodCall(path, receiver, args, call_span) = recv.kind {
         if !args.iter().any(|e| e.span.from_expansion()) && !receiver.span.from_expansion() {
             let name = path.ident.name.as_str();
-            return Some((name, receiver, args, path.ident.span));
+            return Some((name, receiver, args, path.ident.span, call_span));
         }
     }
     None
@@ -3316,36 +3414,10 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
         if let hir::ImplItemKind::Fn(_, _) = impl_item.kind {
             let ret_ty = return_ty(cx, impl_item.hir_id());
 
-            // walk the return type and check for Self (this does not check associated types)
-            if let Some(self_adt) = self_ty.ty_adt_def() {
-                if contains_adt_constructor(ret_ty, self_adt) {
-                    return;
-                }
-            } else if ret_ty.contains(self_ty) {
+            if contains_ty_adt_constructor_opaque(cx, ret_ty, self_ty) {
                 return;
             }
 
-            // if return type is impl trait, check the associated types
-            if let ty::Opaque(def_id, _) = *ret_ty.kind() {
-                // one of the associated types must be Self
-                for &(predicate, _span) in cx.tcx.explicit_item_bounds(def_id) {
-                    if let ty::PredicateKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
-                        let assoc_ty = match projection_predicate.term.unpack() {
-                            ty::TermKind::Ty(ty) => ty,
-                            ty::TermKind::Const(_c) => continue,
-                        };
-                        // walk the associated type and check for Self
-                        if let Some(self_adt) = self_ty.ty_adt_def() {
-                            if contains_adt_constructor(assoc_ty, self_adt) {
-                                return;
-                            }
-                        } else if assoc_ty.contains(self_ty) {
-                            return;
-                        }
-                    }
-                }
-            }
-
             if name == "new" && ret_ty != self_ty {
                 span_lint(
                     cx,
@@ -3411,7 +3483,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
 impl Methods {
     #[allow(clippy::too_many_lines)]
     fn check_methods<'tcx>(&self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if let Some((name, recv, args, span)) = method_call(expr) {
+        if let Some((name, recv, args, span, call_span)) = method_call(expr) {
             match (name, args) {
                 ("add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub", [_arg]) => {
                     zst_offset::check(cx, expr, recv);
@@ -3430,28 +3502,31 @@ impl Methods {
                 ("as_ref", []) => useless_asref::check(cx, expr, "as_ref", recv),
                 ("assume_init", []) => uninit_assumed_init::check(cx, expr, recv),
                 ("cloned", []) => cloned_instead_of_copied::check(cx, expr, recv, span, self.msrv),
-                ("collect", []) => match method_call(recv) {
-                    Some((name @ ("cloned" | "copied"), recv2, [], _)) => {
-                        iter_cloned_collect::check(cx, name, expr, recv2);
-                    },
-                    Some(("map", m_recv, [m_arg], _)) => {
-                        map_collect_result_unit::check(cx, expr, m_recv, m_arg, recv);
-                    },
-                    Some(("take", take_self_arg, [take_arg], _)) => {
-                        if meets_msrv(self.msrv, msrvs::STR_REPEAT) {
-                            manual_str_repeat::check(cx, expr, recv, take_self_arg, take_arg);
-                        }
-                    },
-                    _ => {},
+                ("collect", []) if is_trait_method(cx, expr, sym::Iterator) => {
+                    needless_collect::check(cx, span, expr, recv, call_span);
+                    match method_call(recv) {
+                        Some((name @ ("cloned" | "copied"), recv2, [], _, _)) => {
+                            iter_cloned_collect::check(cx, name, expr, recv2);
+                        },
+                        Some(("map", m_recv, [m_arg], _, _)) => {
+                            map_collect_result_unit::check(cx, expr, m_recv, m_arg);
+                        },
+                        Some(("take", take_self_arg, [take_arg], _, _)) => {
+                            if meets_msrv(self.msrv, msrvs::STR_REPEAT) {
+                                manual_str_repeat::check(cx, expr, recv, take_self_arg, take_arg);
+                            }
+                        },
+                        _ => {},
+                    }
                 },
                 ("count", []) if is_trait_method(cx, expr, sym::Iterator) => match method_call(recv) {
-                    Some(("cloned", recv2, [], _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, true, false),
-                    Some((name2 @ ("into_iter" | "iter" | "iter_mut"), recv2, [], _)) => {
+                    Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, true, false),
+                    Some((name2 @ ("into_iter" | "iter" | "iter_mut"), recv2, [], _, _)) => {
                         iter_count::check(cx, expr, recv2, name2);
                     },
-                    Some(("map", _, [arg], _)) => suspicious_map::check(cx, expr, recv, arg),
-                    Some(("filter", recv2, [arg], _)) => bytecount::check(cx, expr, recv2, arg),
-                    Some(("bytes", recv2, [], _)) => bytes_count_to_len::check(cx, expr, recv, recv2),
+                    Some(("map", _, [arg], _, _)) => suspicious_map::check(cx, expr, recv, arg),
+                    Some(("filter", recv2, [arg], _, _)) => bytecount::check(cx, expr, recv2, arg),
+                    Some(("bytes", recv2, [], _, _)) => bytes_count_to_len::check(cx, expr, recv, recv2),
                     _ => {},
                 },
                 ("drain", [arg]) => {
@@ -3463,8 +3538,8 @@ impl Methods {
                     }
                 },
                 ("expect", [_]) => match method_call(recv) {
-                    Some(("ok", recv, [], _)) => ok_expect::check(cx, expr, recv),
-                    Some(("err", recv, [], err_span)) => err_expect::check(cx, expr, recv, self.msrv, span, err_span),
+                    Some(("ok", recv, [], _, _)) => ok_expect::check(cx, expr, recv),
+                    Some(("err", recv, [], err_span, _)) => err_expect::check(cx, expr, recv, self.msrv, span, err_span),
                     _ => expect_used::check(cx, expr, recv, false, self.allow_expect_in_tests),
                 },
                 ("expect_err", [_]) => expect_used::check(cx, expr, recv, true, self.allow_expect_in_tests),
@@ -3484,13 +3559,13 @@ impl Methods {
                     flat_map_option::check(cx, expr, arg, span);
                 },
                 ("flatten", []) => match method_call(recv) {
-                    Some(("map", recv, [map_arg], map_span)) => map_flatten::check(cx, expr, recv, map_arg, map_span),
-                    Some(("cloned", recv2, [], _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, true),
+                    Some(("map", recv, [map_arg], map_span, _)) => map_flatten::check(cx, expr, recv, map_arg, map_span),
+                    Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, true),
                     _ => {},
                 },
                 ("fold", [init, acc]) => unnecessary_fold::check(cx, expr, init, acc, span),
                 ("for_each", [_]) => {
-                    if let Some(("inspect", _, [_], span2)) = method_call(recv) {
+                    if let Some(("inspect", _, [_], span2, _)) = method_call(recv) {
                         inspect_for_each::check(cx, expr, span2);
                     }
                 },
@@ -3510,12 +3585,12 @@ impl Methods {
                     iter_on_single_or_empty_collections::check(cx, expr, name, recv);
                 },
                 ("join", [join_arg]) => {
-                    if let Some(("collect", _, _, span)) = method_call(recv) {
+                    if let Some(("collect", _, _, span, _)) = method_call(recv) {
                         unnecessary_join::check(cx, expr, recv, join_arg, span);
                     }
                 },
                 ("last", []) | ("skip", [_]) => {
-                    if let Some((name2, recv2, args2, _span2)) = method_call(recv) {
+                    if let Some((name2, recv2, args2, _span2, _)) = method_call(recv) {
                         if let ("cloned", []) = (name2, args2) {
                             iter_overeager_cloned::check(cx, expr, recv, recv2, false, false);
                         }
@@ -3527,13 +3602,13 @@ impl Methods {
                 (name @ ("map" | "map_err"), [m_arg]) => {
                     if name == "map" {
                         map_clone::check(cx, expr, recv, m_arg, self.msrv);
-                        if let Some((map_name @ ("iter" | "into_iter"), recv2, _, _)) = method_call(recv) {
+                        if let Some((map_name @ ("iter" | "into_iter"), recv2, _, _, _)) = method_call(recv) {
                             iter_kv_map::check(cx, map_name, expr, recv2, m_arg);
                         }
                     } else {
                         map_err_ignore::check(cx, expr, m_arg);
                     }
-                    if let Some((name, recv2, args, span2)) = method_call(recv) {
+                    if let Some((name, recv2, args, span2,_)) = method_call(recv) {
                         match (name, args) {
                             ("as_mut", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, true, self.msrv),
                             ("as_ref", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, false, self.msrv),
@@ -3553,7 +3628,7 @@ impl Methods {
                     manual_ok_or::check(cx, expr, recv, def, map);
                 },
                 ("next", []) => {
-                    if let Some((name2, recv2, args2, _)) = method_call(recv) {
+                    if let Some((name2, recv2, args2, _, _)) = method_call(recv) {
                         match (name2, args2) {
                             ("cloned", []) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, false),
                             ("filter", [arg]) => filter_next::check(cx, expr, recv2, arg),
@@ -3566,10 +3641,10 @@ impl Methods {
                     }
                 },
                 ("nth", [n_arg]) => match method_call(recv) {
-                    Some(("bytes", recv2, [], _)) => bytes_nth::check(cx, expr, recv2, n_arg),
-                    Some(("cloned", recv2, [], _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, false),
-                    Some(("iter", recv2, [], _)) => iter_nth::check(cx, expr, recv2, recv, n_arg, false),
-                    Some(("iter_mut", recv2, [], _)) => iter_nth::check(cx, expr, recv2, recv, n_arg, true),
+                    Some(("bytes", recv2, [], _, _)) => bytes_nth::check(cx, expr, recv2, n_arg),
+                    Some(("cloned", recv2, [], _, _)) => iter_overeager_cloned::check(cx, expr, recv, recv2, false, false),
+                    Some(("iter", recv2, [], _, _)) => iter_nth::check(cx, expr, recv2, recv, n_arg, false),
+                    Some(("iter_mut", recv2, [], _, _)) => iter_nth::check(cx, expr, recv2, recv, n_arg, true),
                     _ => iter_nth_zero::check(cx, expr, recv, n_arg),
                 },
                 ("ok_or_else", [arg]) => unnecessary_lazy_eval::check(cx, expr, recv, arg, "ok_or"),
@@ -3604,6 +3679,14 @@ impl Methods {
                 ("resize", [count_arg, default_arg]) => {
                     vec_resize_to_zero::check(cx, expr, count_arg, default_arg, span);
                 },
+                ("seek", [arg]) => {
+                    if meets_msrv(self.msrv, msrvs::SEEK_FROM_CURRENT) {
+                        seek_from_current::check(cx, expr, recv, arg);
+                    }
+                    if meets_msrv(self.msrv, msrvs::SEEK_REWIND) {
+                        seek_to_start_instead_of_rewind::check(cx, expr, recv, arg, span);
+                    }
+                },
                 ("sort", []) => {
                     stable_sort_primitive::check(cx, expr, recv);
                 },
@@ -3626,7 +3709,7 @@ impl Methods {
                 },
                 ("step_by", [arg]) => iterator_step_by_zero::check(cx, expr, arg),
                 ("take", [_arg]) => {
-                    if let Some((name2, recv2, args2, _span2)) = method_call(recv) {
+                    if let Some((name2, recv2, args2, _span2, _)) = method_call(recv) {
                         if let ("cloned", []) = (name2, args2) {
                             iter_overeager_cloned::check(cx, expr, recv, recv2, false, false);
                         }
@@ -3649,13 +3732,13 @@ impl Methods {
                 },
                 ("unwrap", []) => {
                     match method_call(recv) {
-                        Some(("get", recv, [get_arg], _)) => {
+                        Some(("get", recv, [get_arg], _, _)) => {
                             get_unwrap::check(cx, expr, recv, get_arg, false);
                         },
-                        Some(("get_mut", recv, [get_arg], _)) => {
+                        Some(("get_mut", recv, [get_arg], _, _)) => {
                             get_unwrap::check(cx, expr, recv, get_arg, true);
                         },
-                        Some(("or", recv, [or_arg], or_span)) => {
+                        Some(("or", recv, [or_arg], or_span, _)) => {
                             or_then_unwrap::check(cx, expr, recv, or_arg, or_span);
                         },
                         _ => {},
@@ -3664,19 +3747,19 @@ impl Methods {
                 },
                 ("unwrap_err", []) => unwrap_used::check(cx, expr, recv, true, self.allow_unwrap_in_tests),
                 ("unwrap_or", [u_arg]) => match method_call(recv) {
-                    Some((arith @ ("checked_add" | "checked_sub" | "checked_mul"), lhs, [rhs], _)) => {
+                    Some((arith @ ("checked_add" | "checked_sub" | "checked_mul"), lhs, [rhs], _, _)) => {
                         manual_saturating_arithmetic::check(cx, expr, lhs, rhs, u_arg, &arith["checked_".len()..]);
                     },
-                    Some(("map", m_recv, [m_arg], span)) => {
+                    Some(("map", m_recv, [m_arg], span, _)) => {
                         option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span);
                     },
-                    Some(("then_some", t_recv, [t_arg], _)) => {
+                    Some(("then_some", t_recv, [t_arg], _, _)) => {
                         obfuscated_if_else::check(cx, expr, t_recv, t_arg, u_arg);
                     },
                     _ => {},
                 },
                 ("unwrap_or_else", [u_arg]) => match method_call(recv) {
-                    Some(("map", recv, [map_arg], _))
+                    Some(("map", recv, [map_arg], _, _))
                         if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, self.msrv) => {},
                     _ => {
                         unwrap_or_else_default::check(cx, expr, recv, u_arg);
@@ -3697,7 +3780,7 @@ impl Methods {
 }
 
 fn check_is_some_is_none(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, is_some: bool) {
-    if let Some((name @ ("find" | "position" | "rposition"), f_recv, [arg], span)) = method_call(recv) {
+    if let Some((name @ ("find" | "position" | "rposition"), f_recv, [arg], span, _)) = method_call(recv) {
         search_is_some::check(cx, expr, name, is_some, f_recv, arg, recv, span);
     }
 }
@@ -3906,14 +3989,6 @@ impl OutType {
     }
 }
 
-fn is_bool(ty: &hir::Ty<'_>) -> bool {
-    if let hir::TyKind::Path(QPath::Resolved(_, path)) = ty.kind {
-        matches!(path.res, Res::PrimTy(PrimTy::Bool))
-    } else {
-        false
-    }
-}
-
 fn fn_header_equals(expected: hir::FnHeader, actual: hir::FnHeader) -> bool {
     expected.constness == actual.constness
         && expected.unsafety == actual.unsafety
diff --git a/clippy_lints/src/loops/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs
index 66f9e28596e..b088e642e0e 100644
--- a/clippy_lints/src/loops/needless_collect.rs
+++ b/clippy_lints/src/methods/needless_collect.rs
@@ -3,94 +3,99 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
 use clippy_utils::higher;
 use clippy_utils::source::{snippet, snippet_with_applicability};
 use clippy_utils::sugg::Sugg;
-use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{can_move_expr_to_closure, is_trait_method, path_to_local, path_to_local_id, CaptureKind};
-use if_chain::if_chain;
+use clippy_utils::ty::{is_type_diagnostic_item, make_normalized_projection, make_projection};
+use clippy_utils::{
+    can_move_expr_to_closure, get_enclosing_block, get_parent_node, is_trait_method, path_to_local, path_to_local_id,
+    CaptureKind,
+};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Applicability, MultiSpan};
 use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
-use rustc_hir::{Block, Expr, ExprKind, HirId, HirIdSet, Local, Mutability, Node, PatKind, Stmt, StmtKind};
+use rustc_hir::{
+    BindingAnnotation, Block, Expr, ExprKind, HirId, HirIdSet, Local, Mutability, Node, PatKind, Stmt, StmtKind,
+};
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
-use rustc_middle::ty::subst::GenericArgKind;
-use rustc_middle::ty::{self, Ty};
-use rustc_span::sym;
-use rustc_span::Span;
+use rustc_middle::ty::{self, AssocKind, EarlyBinder, GenericArg, GenericArgKind, Ty};
+use rustc_span::symbol::Ident;
+use rustc_span::{sym, Span, Symbol};
 
 const NEEDLESS_COLLECT_MSG: &str = "avoid using `collect()` when not needed";
 
-pub(super) fn check<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) {
-    check_needless_collect_direct_usage(expr, cx);
-    check_needless_collect_indirect_usage(expr, cx);
-}
-fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) {
-    if_chain! {
-        if let ExprKind::MethodCall(method, receiver, args, _) = expr.kind;
-        if let ExprKind::MethodCall(chain_method, ..) = receiver.kind;
-        if chain_method.ident.name == sym!(collect) && is_trait_method(cx, receiver, sym::Iterator);
-        then {
-            let ty = cx.typeck_results().expr_ty(receiver);
-            let mut applicability = Applicability::MaybeIncorrect;
-            let is_empty_sugg = "next().is_none()".to_string();
-            let method_name = method.ident.name.as_str();
-            let sugg = if is_type_diagnostic_item(cx, ty, sym::Vec) ||
-                        is_type_diagnostic_item(cx, ty, sym::VecDeque) ||
-                        is_type_diagnostic_item(cx, ty, sym::LinkedList) ||
-                        is_type_diagnostic_item(cx, ty, sym::BinaryHeap) {
-                match method_name {
-                    "len" => "count()".to_string(),
-                    "is_empty" => is_empty_sugg,
-                    "contains" => {
-                        let contains_arg = snippet_with_applicability(cx, args[0].span, "??", &mut applicability);
-                        let (arg, pred) = contains_arg
-                            .strip_prefix('&')
-                            .map_or(("&x", &*contains_arg), |s| ("x", s));
-                        format!("any(|{arg}| x == {pred})")
-                    }
-                    _ => return,
-                }
-            }
-            else if is_type_diagnostic_item(cx, ty, sym::BTreeMap) ||
-                is_type_diagnostic_item(cx, ty, sym::HashMap) {
-                match method_name {
-                    "is_empty" => is_empty_sugg,
-                    _ => return,
-                }
-            }
-            else {
-                return;
-            };
-            span_lint_and_sugg(
-                cx,
-                NEEDLESS_COLLECT,
-                chain_method.ident.span.with_hi(expr.span.hi()),
-                NEEDLESS_COLLECT_MSG,
-                "replace with",
-                sugg,
-                applicability,
-            );
-        }
-    }
-}
+pub(super) fn check<'tcx>(
+    cx: &LateContext<'tcx>,
+    name_span: Span,
+    collect_expr: &'tcx Expr<'_>,
+    iter_expr: &'tcx Expr<'tcx>,
+    call_span: Span,
+) {
+    if let Some(parent) = get_parent_node(cx.tcx, collect_expr.hir_id) {
+        match parent {
+            Node::Expr(parent) => {
+                if let ExprKind::MethodCall(name, _, args @ ([] | [_]), _) = parent.kind {
+                    let mut app = Applicability::MachineApplicable;
+                    let name = name.ident.as_str();
+                    let collect_ty = cx.typeck_results().expr_ty(collect_expr);
 
-fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateContext<'tcx>) {
-    if let ExprKind::Block(block, _) = expr.kind {
-        for stmt in block.stmts {
-            if_chain! {
-                if let StmtKind::Local(local) = stmt.kind;
-                if let PatKind::Binding(_, id, ..) = local.pat.kind;
-                if let Some(init_expr) = local.init;
-                if let ExprKind::MethodCall(method_name, iter_source, [], ..) = init_expr.kind;
-                if method_name.ident.name == sym!(collect) && is_trait_method(cx, init_expr, sym::Iterator);
-                let ty = cx.typeck_results().expr_ty(init_expr);
-                if is_type_diagnostic_item(cx, ty, sym::Vec) ||
-                    is_type_diagnostic_item(cx, ty, sym::VecDeque) ||
-                    is_type_diagnostic_item(cx, ty, sym::BinaryHeap) ||
-                    is_type_diagnostic_item(cx, ty, sym::LinkedList);
-                let iter_ty = cx.typeck_results().expr_ty(iter_source);
-                if let Some(iter_calls) = detect_iter_and_into_iters(block, id, cx, get_captured_ids(cx, iter_ty));
-                if let [iter_call] = &*iter_calls;
-                then {
+                    let sugg: String = match name {
+                        "len" => {
+                            if let Some(adt) = collect_ty.ty_adt_def()
+                                && matches!(
+                                    cx.tcx.get_diagnostic_name(adt.did()),
+                                    Some(sym::Vec | sym::VecDeque | sym::LinkedList | sym::BinaryHeap)
+                                )
+                            {
+                                "count()".into()
+                            } else {
+                                return;
+                            }
+                        },
+                        "is_empty"
+                            if is_is_empty_sig(cx, parent.hir_id)
+                                && iterates_same_ty(cx, cx.typeck_results().expr_ty(iter_expr), collect_ty) =>
+                        {
+                            "next().is_none()".into()
+                        },
+                        "contains" => {
+                            if is_contains_sig(cx, parent.hir_id, iter_expr)
+                                && let Some(arg) = args.first()
+                            {
+                                let (span, prefix) = if let ExprKind::AddrOf(_, _, arg) = arg.kind {
+                                    (arg.span, "")
+                                } else {
+                                    (arg.span, "*")
+                                };
+                                let snip = snippet_with_applicability(cx, span, "??", &mut app);
+                                format!("any(|x| x == {prefix}{snip})")
+                            } else {
+                                return;
+                            }
+                        },
+                        _ => return,
+                    };
+
+                    span_lint_and_sugg(
+                        cx,
+                        NEEDLESS_COLLECT,
+                        call_span.with_hi(parent.span.hi()),
+                        NEEDLESS_COLLECT_MSG,
+                        "replace with",
+                        sugg,
+                        app,
+                    );
+                }
+            },
+            Node::Local(l) => {
+                if let PatKind::Binding(BindingAnnotation::NONE | BindingAnnotation::MUT, id, _, None)
+                    = l.pat.kind
+                    && let ty = cx.typeck_results().expr_ty(collect_expr)
+                    && [sym::Vec, sym::VecDeque, sym::BinaryHeap, sym::LinkedList].into_iter()
+                        .any(|item| is_type_diagnostic_item(cx, ty, item))
+                    && let iter_ty = cx.typeck_results().expr_ty(iter_expr)
+                    && let Some(block) = get_enclosing_block(cx, l.hir_id)
+                    && let Some(iter_calls) = detect_iter_and_into_iters(block, id, cx, get_captured_ids(cx, iter_ty))
+                    && let [iter_call] = &*iter_calls
+                {
                     let mut used_count_visitor = UsedCountVisitor {
                         cx,
                         id,
@@ -102,20 +107,20 @@ fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCo
                     }
 
                     // Suggest replacing iter_call with iter_replacement, and removing stmt
-                    let mut span = MultiSpan::from_span(method_name.ident.span);
+                    let mut span = MultiSpan::from_span(name_span);
                     span.push_span_label(iter_call.span, "the iterator could be used here instead");
                     span_lint_hir_and_then(
                         cx,
                         super::NEEDLESS_COLLECT,
-                        init_expr.hir_id,
+                        collect_expr.hir_id,
                         span,
                         NEEDLESS_COLLECT_MSG,
                         |diag| {
-                            let iter_replacement = format!("{}{}", Sugg::hir(cx, iter_source, ".."), iter_call.get_iter_method(cx));
+                            let iter_replacement = format!("{}{}", Sugg::hir(cx, iter_expr, ".."), iter_call.get_iter_method(cx));
                             diag.multipart_suggestion(
                                 iter_call.get_suggestion_text(),
                                 vec![
-                                    (stmt.span, String::new()),
+                                    (l.span, String::new()),
                                     (iter_call.span, iter_replacement)
                                 ],
                                 Applicability::MaybeIncorrect,
@@ -123,11 +128,61 @@ fn check_needless_collect_indirect_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCo
                         },
                     );
                 }
-            }
+            },
+            _ => (),
         }
     }
 }
 
+/// Checks if the given method call matches the expected signature of `([&[mut]] self) -> bool`
+fn is_is_empty_sig(cx: &LateContext<'_>, call_id: HirId) -> bool {
+    cx.typeck_results().type_dependent_def_id(call_id).map_or(false, |id| {
+        let sig = cx.tcx.fn_sig(id).skip_binder();
+        sig.inputs().len() == 1 && sig.output().is_bool()
+    })
+}
+
+/// Checks if `<iter_ty as Iterator>::Item` is the same as `<collect_ty as IntoIter>::Item`
+fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty: Ty<'tcx>) -> bool {
+    let item = Symbol::intern("Item");
+    if let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator)
+        && let Some(into_iter_trait) = cx.tcx.get_diagnostic_item(sym::IntoIterator)
+        && let Some(iter_item_ty) = make_normalized_projection(cx.tcx, cx.param_env, iter_trait, item, [iter_ty])
+        && let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, item, [collect_ty])
+        && let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions(
+            cx.param_env,
+            cx.tcx.mk_projection(into_iter_item_proj.item_def_id, into_iter_item_proj.substs)
+        )
+    {
+        iter_item_ty == into_iter_item_ty
+    } else {
+        false
+    }
+}
+
+/// Checks if the given method call matches the expected signature of
+/// `([&[mut]] self, &<iter_ty as Iterator>::Item) -> bool`
+fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -> bool {
+    let typeck = cx.typeck_results();
+    if let Some(id) = typeck.type_dependent_def_id(call_id)
+        && let sig = cx.tcx.fn_sig(id)
+        && sig.skip_binder().output().is_bool()
+        && let [_, search_ty] = *sig.skip_binder().inputs()
+        && let ty::Ref(_, search_ty, Mutability::Not) = *cx.tcx.erase_late_bound_regions(sig.rebind(search_ty)).kind()
+        && let Some(iter_trait) = cx.tcx.get_diagnostic_item(sym::Iterator)
+        && let Some(iter_item) = cx.tcx
+            .associated_items(iter_trait)
+            .find_by_name_and_kind(cx.tcx, Ident::with_dummy_span(Symbol::intern("Item")), AssocKind::Type, iter_trait)
+        && let substs = cx.tcx.mk_substs([GenericArg::from(typeck.expr_ty_adjusted(iter_expr))].into_iter())
+        && let proj_ty = cx.tcx.mk_projection(iter_item.def_id, substs)
+        && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty)
+    {
+        item_ty == EarlyBinder(search_ty).subst(cx.tcx, cx.typeck_results().node_substs(call_id))
+    } else {
+        false
+    }
+}
+
 struct IterFunction {
     func: IterFunctionKind,
     span: Span,
diff --git a/clippy_lints/src/methods/option_as_ref_deref.rs b/clippy_lints/src/methods/option_as_ref_deref.rs
index 742483e6b2e..e6eb64bcbde 100644
--- a/clippy_lints/src/methods/option_as_ref_deref.rs
+++ b/clippy_lints/src/methods/option_as_ref_deref.rs
@@ -13,8 +13,8 @@ use rustc_span::sym;
 use super::OPTION_AS_REF_DEREF;
 
 /// lint use of `_.as_ref().map(Deref::deref)` for `Option`s
-pub(super) fn check<'tcx>(
-    cx: &LateContext<'tcx>,
+pub(super) fn check(
+    cx: &LateContext<'_>,
     expr: &hir::Expr<'_>,
     as_ref_recv: &hir::Expr<'_>,
     map_arg: &hir::Expr<'_>,
diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs
index 991d3dd538b..4460f38fcc1 100644
--- a/clippy_lints/src/methods/or_fun_call.rs
+++ b/clippy_lints/src/methods/or_fun_call.rs
@@ -83,6 +83,8 @@ pub(super) fn check<'tcx>(
         method_span: Span,
         self_expr: &hir::Expr<'_>,
         arg: &'tcx hir::Expr<'_>,
+        // `Some` if fn has second argument
+        second_arg: Option<&hir::Expr<'_>>,
         span: Span,
         // None if lambda is required
         fun_span: Option<Span>,
@@ -109,30 +111,40 @@ pub(super) fn check<'tcx>(
             if poss.contains(&name);
 
             then {
-                let macro_expanded_snipped;
-                let sugg: Cow<'_, str> = {
+                let sugg = {
                     let (snippet_span, use_lambda) = match (fn_has_arguments, fun_span) {
                         (false, Some(fun_span)) => (fun_span, false),
                         _ => (arg.span, true),
                     };
-                    let snippet = {
-                        let not_macro_argument_snippet = snippet_with_macro_callsite(cx, snippet_span, "..");
-                        if not_macro_argument_snippet == "vec![]" {
-                            macro_expanded_snipped = snippet(cx, snippet_span, "..");
+
+                    let format_span = |span: Span| {
+                        let not_macro_argument_snippet = snippet_with_macro_callsite(cx, span, "..");
+                        let snip = if not_macro_argument_snippet == "vec![]" {
+                            let macro_expanded_snipped = snippet(cx, snippet_span, "..");
                             match macro_expanded_snipped.strip_prefix("$crate::vec::") {
-                                Some(stripped) => Cow::from(stripped),
+                                Some(stripped) => Cow::Owned(stripped.to_owned()),
                                 None => macro_expanded_snipped,
                             }
                         } else {
                             not_macro_argument_snippet
-                        }
+                        };
+
+                        snip.to_string()
                     };
 
-                    if use_lambda {
+                    let snip = format_span(snippet_span);
+                    let snip = if use_lambda {
                         let l_arg = if fn_has_arguments { "_" } else { "" };
-                        format!("|{l_arg}| {snippet}").into()
+                        format!("|{l_arg}| {snip}")
                     } else {
-                        snippet
+                        snip
+                    };
+
+                    if let Some(f) = second_arg {
+                        let f = format_span(f.span);
+                        format!("{snip}, {f}")
+                    } else {
+                        snip
                     }
                 };
                 let span_replace_word = method_span.with_hi(span.hi());
@@ -149,8 +161,8 @@ pub(super) fn check<'tcx>(
         }
     }
 
-    if let [arg] = args {
-        let inner_arg = if let hir::ExprKind::Block(
+    let extract_inner_arg = |arg: &'tcx hir::Expr<'_>| {
+        if let hir::ExprKind::Block(
             hir::Block {
                 stmts: [],
                 expr: Some(expr),
@@ -162,19 +174,32 @@ pub(super) fn check<'tcx>(
             expr
         } else {
             arg
-        };
+        }
+    };
+
+    if let [arg] = args {
+        let inner_arg = extract_inner_arg(arg);
         match inner_arg.kind {
             hir::ExprKind::Call(fun, or_args) => {
                 let or_has_args = !or_args.is_empty();
                 if !check_unwrap_or_default(cx, name, fun, arg, or_has_args, expr.span, method_span) {
                     let fun_span = if or_has_args { None } else { Some(fun.span) };
-                    check_general_case(cx, name, method_span, receiver, arg, expr.span, fun_span);
+                    check_general_case(cx, name, method_span, receiver, arg, None, expr.span, fun_span);
                 }
             },
             hir::ExprKind::Index(..) | hir::ExprKind::MethodCall(..) => {
-                check_general_case(cx, name, method_span, receiver, arg, expr.span, None);
+                check_general_case(cx, name, method_span, receiver, arg, None, expr.span, None);
             },
             _ => (),
         }
     }
+
+    // `map_or` takes two arguments
+    if let [arg, lambda] = args {
+        let inner_arg = extract_inner_arg(arg);
+        if let hir::ExprKind::Call(fun, or_args) = inner_arg.kind {
+            let fun_span = if or_args.is_empty() { Some(fun.span) } else { None };
+            check_general_case(cx, name, method_span, receiver, arg, Some(lambda), expr.span, fun_span);
+        }
+    }
 }
diff --git a/clippy_lints/src/methods/seek_from_current.rs b/clippy_lints/src/methods/seek_from_current.rs
new file mode 100644
index 00000000000..361a3082f94
--- /dev/null
+++ b/clippy_lints/src/methods/seek_from_current.rs
@@ -0,0 +1,48 @@
+use rustc_ast::ast::{LitIntType, LitKind};
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+
+use clippy_utils::{
+    diagnostics::span_lint_and_sugg, get_trait_def_id, match_def_path, paths, source::snippet_with_applicability,
+    ty::implements_trait,
+};
+
+use super::SEEK_FROM_CURRENT;
+
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'tcx Expr<'_>, arg: &'tcx Expr<'_>) {
+    let ty = cx.typeck_results().expr_ty(recv);
+
+    if let Some(def_id) = get_trait_def_id(cx, &paths::STD_IO_SEEK) {
+        if implements_trait(cx, ty, def_id, &[]) && arg_is_seek_from_current(cx, arg) {
+            let mut applicability = Applicability::MachineApplicable;
+            let snip = snippet_with_applicability(cx, recv.span, "..", &mut applicability);
+
+            span_lint_and_sugg(
+                cx,
+                SEEK_FROM_CURRENT,
+                expr.span,
+                "using `SeekFrom::Current` to start from current position",
+                "replace with",
+                format!("{snip}.stream_position()"),
+                applicability,
+            );
+        }
+    }
+}
+
+fn arg_is_seek_from_current<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool {
+    if let ExprKind::Call(f, args) = expr.kind &&
+        let ExprKind::Path(ref path) = f.kind &&
+        let Some(def_id) = cx.qpath_res(path, f.hir_id).opt_def_id() &&
+        match_def_path(cx, def_id, &paths::STD_IO_SEEK_FROM_CURRENT) {
+        // check if argument of `SeekFrom::Current` is `0`
+        if args.len() == 1 &&
+            let ExprKind::Lit(ref lit) = args[0].kind &&
+            let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node {
+            return true
+        }
+    }
+
+    false
+}
diff --git a/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs b/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs
new file mode 100644
index 00000000000..7e3bed1e41a
--- /dev/null
+++ b/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs
@@ -0,0 +1,45 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::ty::implements_trait;
+use clippy_utils::{get_trait_def_id, match_def_path, paths};
+use rustc_ast::ast::{LitIntType, LitKind};
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_span::Span;
+
+use super::SEEK_TO_START_INSTEAD_OF_REWIND;
+
+pub(super) fn check<'tcx>(
+    cx: &LateContext<'tcx>,
+    expr: &'tcx Expr<'_>,
+    recv: &'tcx Expr<'_>,
+    arg: &'tcx Expr<'_>,
+    name_span: Span,
+) {
+    // Get receiver type
+    let ty = cx.typeck_results().expr_ty(recv).peel_refs();
+
+    if let Some(seek_trait_id) = get_trait_def_id(cx, &paths::STD_IO_SEEK) &&
+        implements_trait(cx, ty, seek_trait_id, &[]) &&
+        let ExprKind::Call(func, args1) = arg.kind &&
+        let ExprKind::Path(ref path) = func.kind &&
+        let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id() &&
+        match_def_path(cx, def_id, &paths::STD_IO_SEEKFROM_START) &&
+        args1.len() == 1 &&
+        let ExprKind::Lit(ref lit) = args1[0].kind &&
+        let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node
+    {
+        let method_call_span = expr.span.with_lo(name_span.lo());
+        span_lint_and_then(
+            cx,
+            SEEK_TO_START_INSTEAD_OF_REWIND,
+            method_call_span,
+            "used `seek` to go to the start of the stream",
+            |diag| {
+                let app = Applicability::MachineApplicable;
+
+                diag.span_suggestion(method_call_span, "replace with", "rewind()", app);
+            },
+        );
+    }
+}
diff --git a/clippy_lints/src/methods/string_extend_chars.rs b/clippy_lints/src/methods/string_extend_chars.rs
index 6f4cec546e9..f35d81cee8e 100644
--- a/clippy_lints/src/methods/string_extend_chars.rs
+++ b/clippy_lints/src/methods/string_extend_chars.rs
@@ -18,7 +18,11 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
         let target = &arglists[0].0;
         let self_ty = cx.typeck_results().expr_ty(target).peel_refs();
         let ref_str = if *self_ty.kind() == ty::Str {
-            ""
+            if matches!(target.kind, hir::ExprKind::Index(..)) {
+                "&"
+            } else {
+                ""
+            }
         } else if is_type_lang_item(cx, self_ty, hir::LangItem::String) {
             "&"
         } else {
diff --git a/clippy_lints/src/methods/suspicious_map.rs b/clippy_lints/src/methods/suspicious_map.rs
index 851cdf54455..2ac0786b37b 100644
--- a/clippy_lints/src/methods/suspicious_map.rs
+++ b/clippy_lints/src/methods/suspicious_map.rs
@@ -8,7 +8,7 @@ use rustc_span::sym;
 
 use super::SUSPICIOUS_MAP;
 
-pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, count_recv: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) {
+pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, count_recv: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) {
     if_chain! {
         if is_trait_method(cx, count_recv, sym::Iterator);
         let closure = expr_or_init(cx, map_arg);
diff --git a/clippy_lints/src/methods/unnecessary_join.rs b/clippy_lints/src/methods/unnecessary_join.rs
index c9b87bc6bf2..087e1e4343b 100644
--- a/clippy_lints/src/methods/unnecessary_join.rs
+++ b/clippy_lints/src/methods/unnecessary_join.rs
@@ -31,7 +31,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 UNNECESSARY_JOIN,
                 span.with_hi(expr.span.hi()),
-                r#"called `.collect<Vec<String>>().join("")` on an iterator"#,
+                r#"called `.collect::<Vec<String>>().join("")` on an iterator"#,
                 "try using",
                 "collect::<String>()".to_owned(),
                 applicability,
diff --git a/clippy_lints/src/methods/unwrap_used.rs b/clippy_lints/src/methods/unwrap_used.rs
index ee17f2d7889..90983f249cd 100644
--- a/clippy_lints/src/methods/unwrap_used.rs
+++ b/clippy_lints/src/methods/unwrap_used.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{is_in_test_function, is_lint_allowed};
+use clippy_utils::{is_in_cfg_test, is_lint_allowed};
 use rustc_hir as hir;
 use rustc_lint::LateContext;
 use rustc_span::sym;
@@ -18,16 +18,16 @@ pub(super) fn check(
     let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
 
     let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) && !is_err {
-        Some((UNWRAP_USED, "an Option", "None", ""))
+        Some((UNWRAP_USED, "an `Option`", "None", ""))
     } else if is_type_diagnostic_item(cx, obj_ty, sym::Result) {
-        Some((UNWRAP_USED, "a Result", if is_err { "Ok" } else { "Err" }, "an "))
+        Some((UNWRAP_USED, "a `Result`", if is_err { "Ok" } else { "Err" }, "an "))
     } else {
         None
     };
 
     let method_suffix = if is_err { "_err" } else { "" };
 
-    if allow_unwrap_in_tests && is_in_test_function(cx.tcx, expr.hir_id) {
+    if allow_unwrap_in_tests && is_in_cfg_test(cx.tcx, expr.hir_id) {
         return;
     }
 
@@ -45,7 +45,7 @@ pub(super) fn check(
             cx,
             lint,
             expr.span,
-            &format!("used `unwrap{method_suffix}()` on `{kind}` value"),
+            &format!("used `unwrap{method_suffix}()` on {kind} value"),
             None,
             &help,
         );
diff --git a/clippy_lints/src/missing_enforced_import_rename.rs b/clippy_lints/src/missing_enforced_import_rename.rs
index 872679f25ab..4712846939e 100644
--- a/clippy_lints/src/missing_enforced_import_rename.rs
+++ b/clippy_lints/src/missing_enforced_import_rename.rs
@@ -59,7 +59,7 @@ impl LateLintPass<'_> for ImportRename {
     fn check_crate(&mut self, cx: &LateContext<'_>) {
         for Rename { path, rename } in &self.conf_renames {
             let segs = path.split("::").collect::<Vec<_>>();
-            if let Res::Def(_, id) = clippy_utils::def_path_res(cx, &segs, None) {
+            for id in clippy_utils::def_path_def_ids(cx, &segs) {
                 self.renames.insert(id, Symbol::intern(rename));
             }
         }
diff --git a/clippy_lints/src/mixed_read_write_in_expression.rs b/clippy_lints/src/mixed_read_write_in_expression.rs
index 6752976348f..321fa4b7f99 100644
--- a/clippy_lints/src/mixed_read_write_in_expression.rs
+++ b/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -218,7 +218,7 @@ enum StopEarly {
     Stop,
 }
 
-fn check_expr<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, expr: &'tcx Expr<'_>) -> StopEarly {
+fn check_expr<'tcx>(vis: &mut ReadVisitor<'_, 'tcx>, expr: &'tcx Expr<'_>) -> StopEarly {
     if expr.hir_id == vis.last_expr.hir_id {
         return StopEarly::KeepGoing;
     }
@@ -265,7 +265,7 @@ fn check_expr<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, expr: &'tcx Expr<'_>) -
     StopEarly::KeepGoing
 }
 
-fn check_stmt<'a, 'tcx>(vis: &mut ReadVisitor<'a, 'tcx>, stmt: &'tcx Stmt<'_>) -> StopEarly {
+fn check_stmt<'tcx>(vis: &mut ReadVisitor<'_, 'tcx>, stmt: &'tcx Stmt<'_>) -> StopEarly {
     match stmt.kind {
         StmtKind::Expr(expr) | StmtKind::Semi(expr) => check_expr(vis, expr),
         // If the declaration is of a local variable, check its initializer
diff --git a/clippy_lints/src/mut_key.rs b/clippy_lints/src/mut_key.rs
index 4b62dcdffe2..a651020ca65 100644
--- a/clippy_lints/src/mut_key.rs
+++ b/clippy_lints/src/mut_key.rs
@@ -1,10 +1,11 @@
 use clippy_utils::diagnostics::span_lint;
-use clippy_utils::trait_ref_of_method;
+use clippy_utils::{def_path_def_ids, trait_ref_of_method};
+use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::TypeVisitable;
 use rustc_middle::ty::{Adt, Array, Ref, Slice, Tuple, Ty};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::Span;
 use rustc_span::symbol::sym;
 use std::iter;
@@ -78,26 +79,44 @@ declare_clippy_lint! {
     "Check for mutable `Map`/`Set` key type"
 }
 
-declare_lint_pass!(MutableKeyType => [ MUTABLE_KEY_TYPE ]);
+#[derive(Clone)]
+pub struct MutableKeyType {
+    ignore_interior_mutability: Vec<String>,
+    ignore_mut_def_ids: FxHashSet<hir::def_id::DefId>,
+}
+
+impl_lint_pass!(MutableKeyType => [ MUTABLE_KEY_TYPE ]);
 
 impl<'tcx> LateLintPass<'tcx> for MutableKeyType {
+    fn check_crate(&mut self, cx: &LateContext<'tcx>) {
+        self.ignore_mut_def_ids.clear();
+        let mut path = Vec::new();
+        for ty in &self.ignore_interior_mutability {
+            path.extend(ty.split("::"));
+            for id in def_path_def_ids(cx, &path[..]) {
+                self.ignore_mut_def_ids.insert(id);
+            }
+            path.clear();
+        }
+    }
+
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'tcx>) {
         if let hir::ItemKind::Fn(ref sig, ..) = item.kind {
-            check_sig(cx, item.hir_id(), sig.decl);
+            self.check_sig(cx, item.hir_id(), sig.decl);
         }
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::ImplItem<'tcx>) {
         if let hir::ImplItemKind::Fn(ref sig, ..) = item.kind {
             if trait_ref_of_method(cx, item.owner_id.def_id).is_none() {
-                check_sig(cx, item.hir_id(), sig.decl);
+                self.check_sig(cx, item.hir_id(), sig.decl);
             }
         }
     }
 
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::TraitItem<'tcx>) {
         if let hir::TraitItemKind::Fn(ref sig, ..) = item.kind {
-            check_sig(cx, item.hir_id(), sig.decl);
+            self.check_sig(cx, item.hir_id(), sig.decl);
         }
     }
 
@@ -105,73 +124,81 @@ impl<'tcx> LateLintPass<'tcx> for MutableKeyType {
         if let hir::PatKind::Wild = local.pat.kind {
             return;
         }
-        check_ty(cx, local.span, cx.typeck_results().pat_ty(local.pat));
+        self.check_ty_(cx, local.span, cx.typeck_results().pat_ty(local.pat));
     }
 }
 
-fn check_sig<'tcx>(cx: &LateContext<'tcx>, item_hir_id: hir::HirId, decl: &hir::FnDecl<'_>) {
-    let fn_def_id = cx.tcx.hir().local_def_id(item_hir_id);
-    let fn_sig = cx.tcx.fn_sig(fn_def_id);
-    for (hir_ty, ty) in iter::zip(decl.inputs, fn_sig.inputs().skip_binder()) {
-        check_ty(cx, hir_ty.span, *ty);
+impl MutableKeyType {
+    pub fn new(ignore_interior_mutability: Vec<String>) -> Self {
+        Self {
+            ignore_interior_mutability,
+            ignore_mut_def_ids: FxHashSet::default(),
+        }
     }
-    check_ty(cx, decl.output.span(), cx.tcx.erase_late_bound_regions(fn_sig.output()));
-}
 
-// We want to lint 1. sets or maps with 2. not immutable key types and 3. no unerased
-// generics (because the compiler cannot ensure immutability for unknown types).
-fn check_ty<'tcx>(cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) {
-    let ty = ty.peel_refs();
-    if let Adt(def, substs) = ty.kind() {
-        let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet]
-            .iter()
-            .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did()));
-        if is_keyed_type && is_interior_mutable_type(cx, substs.type_at(0), span) {
-            span_lint(cx, MUTABLE_KEY_TYPE, span, "mutable key type");
+    fn check_sig(&self, cx: &LateContext<'_>, item_hir_id: hir::HirId, decl: &hir::FnDecl<'_>) {
+        let fn_def_id = cx.tcx.hir().local_def_id(item_hir_id);
+        let fn_sig = cx.tcx.fn_sig(fn_def_id);
+        for (hir_ty, ty) in iter::zip(decl.inputs, fn_sig.inputs().skip_binder()) {
+            self.check_ty_(cx, hir_ty.span, *ty);
         }
+        self.check_ty_(cx, decl.output.span(), cx.tcx.erase_late_bound_regions(fn_sig.output()));
     }
-}
 
-/// Determines if a type contains interior mutability which would affect its implementation of
-/// [`Hash`] or [`Ord`].
-fn is_interior_mutable_type<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, span: Span) -> bool {
-    match *ty.kind() {
-        Ref(_, inner_ty, mutbl) => {
-            mutbl == hir::Mutability::Mut || is_interior_mutable_type(cx, inner_ty, span)
-        }
-        Slice(inner_ty) => is_interior_mutable_type(cx, inner_ty, span),
-        Array(inner_ty, size) => {
-            size.try_eval_usize(cx.tcx, cx.param_env).map_or(true, |u| u != 0)
-                && is_interior_mutable_type(cx, inner_ty, span)
-        }
-        Tuple(fields) => fields.iter().any(|ty| is_interior_mutable_type(cx, ty, span)),
-        Adt(def, substs) => {
-            // Special case for collections in `std` who's impl of `Hash` or `Ord` delegates to
-            // that of their type parameters.  Note: we don't include `HashSet` and `HashMap`
-            // because they have no impl for `Hash` or `Ord`.
-            let is_std_collection = [
-                sym::Option,
-                sym::Result,
-                sym::LinkedList,
-                sym::Vec,
-                sym::VecDeque,
-                sym::BTreeMap,
-                sym::BTreeSet,
-                sym::Rc,
-                sym::Arc,
-            ]
-            .iter()
-            .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did()));
-            let is_box = Some(def.did()) == cx.tcx.lang_items().owned_box();
-            if is_std_collection || is_box {
-                // The type is mutable if any of its type parameters are
-                substs.types().any(|ty| is_interior_mutable_type(cx, ty, span))
-            } else {
-                !ty.has_escaping_bound_vars()
-                    && cx.tcx.layout_of(cx.param_env.and(ty)).is_ok()
-                    && !ty.is_freeze(cx.tcx, cx.param_env)
+    // We want to lint 1. sets or maps with 2. not immutable key types and 3. no unerased
+    // generics (because the compiler cannot ensure immutability for unknown types).
+    fn check_ty_<'tcx>(&self, cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) {
+        let ty = ty.peel_refs();
+        if let Adt(def, substs) = ty.kind() {
+            let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet]
+                .iter()
+                .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did()));
+            if is_keyed_type && self.is_interior_mutable_type(cx, substs.type_at(0)) {
+                span_lint(cx, MUTABLE_KEY_TYPE, span, "mutable key type");
             }
         }
-        _ => false,
+    }
+
+    /// Determines if a type contains interior mutability which would affect its implementation of
+    /// [`Hash`] or [`Ord`].
+    fn is_interior_mutable_type<'tcx>(&self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
+        match *ty.kind() {
+            Ref(_, inner_ty, mutbl) => mutbl == hir::Mutability::Mut || self.is_interior_mutable_type(cx, inner_ty),
+            Slice(inner_ty) => self.is_interior_mutable_type(cx, inner_ty),
+            Array(inner_ty, size) => {
+                size.try_eval_usize(cx.tcx, cx.param_env).map_or(true, |u| u != 0)
+                    && self.is_interior_mutable_type(cx, inner_ty)
+            },
+            Tuple(fields) => fields.iter().any(|ty| self.is_interior_mutable_type(cx, ty)),
+            Adt(def, substs) => {
+                // Special case for collections in `std` who's impl of `Hash` or `Ord` delegates to
+                // that of their type parameters.  Note: we don't include `HashSet` and `HashMap`
+                // because they have no impl for `Hash` or `Ord`.
+                let def_id = def.did();
+                let is_std_collection = [
+                    sym::Option,
+                    sym::Result,
+                    sym::LinkedList,
+                    sym::Vec,
+                    sym::VecDeque,
+                    sym::BTreeMap,
+                    sym::BTreeSet,
+                    sym::Rc,
+                    sym::Arc,
+                ]
+                .iter()
+                .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def_id));
+                let is_box = Some(def_id) == cx.tcx.lang_items().owned_box();
+                if is_std_collection || is_box || self.ignore_mut_def_ids.contains(&def_id) {
+                    // The type is mutable if any of its type parameters are
+                    substs.types().any(|ty| self.is_interior_mutable_type(cx, ty))
+                } else {
+                    !ty.has_escaping_bound_vars()
+                        && cx.tcx.layout_of(cx.param_env.and(ty)).is_ok()
+                        && !ty.is_freeze(cx.tcx, cx.param_env)
+                }
+            },
+            _ => false,
+        }
     }
 }
diff --git a/clippy_lints/src/mut_mut.rs b/clippy_lints/src/mut_mut.rs
index cb16f00047a..bc90e131b7f 100644
--- a/clippy_lints/src/mut_mut.rs
+++ b/clippy_lints/src/mut_mut.rs
@@ -68,13 +68,15 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> {
                     expr.span,
                     "generally you want to avoid `&mut &mut _` if possible",
                 );
-            } else if let ty::Ref(_, _, hir::Mutability::Mut) = self.cx.typeck_results().expr_ty(e).kind() {
-                span_lint(
-                    self.cx,
-                    MUT_MUT,
-                    expr.span,
-                    "this expression mutably borrows a mutable reference. Consider reborrowing",
-                );
+            } else if let ty::Ref(_, ty, hir::Mutability::Mut) = self.cx.typeck_results().expr_ty(e).kind() {
+                if ty.peel_refs().is_sized(self.cx.tcx, self.cx.param_env) {
+                    span_lint(
+                        self.cx,
+                        MUT_MUT,
+                        expr.span,
+                        "this expression mutably borrows a mutable reference. Consider reborrowing",
+                    );
+                }
             }
         }
     }
diff --git a/clippy_lints/src/needless_borrowed_ref.rs b/clippy_lints/src/needless_borrowed_ref.rs
index 10c3ff026b6..498e1408e52 100644
--- a/clippy_lints/src/needless_borrowed_ref.rs
+++ b/clippy_lints/src/needless_borrowed_ref.rs
@@ -36,14 +36,14 @@ declare_clippy_lint! {
 declare_lint_pass!(NeedlessBorrowedRef => [NEEDLESS_BORROWED_REFERENCE]);
 
 impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
-    fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
-        if pat.span.from_expansion() {
+    fn check_pat(&mut self, cx: &LateContext<'tcx>, ref_pat: &'tcx Pat<'_>) {
+        if ref_pat.span.from_expansion() {
             // OK, simple enough, lints doesn't check in macro.
             return;
         }
 
         // Do not lint patterns that are part of an OR `|` pattern, the binding mode must match in all arms
-        for (_, node) in cx.tcx.hir().parent_iter(pat.hir_id) {
+        for (_, node) in cx.tcx.hir().parent_iter(ref_pat.hir_id) {
             let Node::Pat(pat) = node else { break };
 
             if matches!(pat.kind, PatKind::Or(_)) {
@@ -52,20 +52,20 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
         }
 
         // Only lint immutable refs, because `&mut ref T` may be useful.
-        let PatKind::Ref(sub_pat, Mutability::Not) = pat.kind else { return };
+        let PatKind::Ref(pat, Mutability::Not) = ref_pat.kind else { return };
 
-        match sub_pat.kind {
+        match pat.kind {
             // Check sub_pat got a `ref` keyword (excluding `ref mut`).
             PatKind::Binding(BindingAnnotation::REF, _, ident, None) => {
                 span_lint_and_then(
                     cx,
                     NEEDLESS_BORROWED_REFERENCE,
-                    pat.span,
+                    ref_pat.span,
                     "this pattern takes a reference on something that is being dereferenced",
                     |diag| {
                         // `&ref ident`
                         //  ^^^^^
-                        let span = pat.span.until(ident.span);
+                        let span = ref_pat.span.until(ident.span);
                         diag.span_suggestion_verbose(
                             span,
                             "try removing the `&ref` part",
@@ -84,41 +84,71 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
                 }),
                 after,
             ) => {
-                let mut suggestions = Vec::new();
-
-                for element_pat in itertools::chain(before, after) {
-                    if let PatKind::Binding(BindingAnnotation::REF, _, ident, None) = element_pat.kind {
-                        // `&[..., ref ident, ...]`
-                        //         ^^^^
-                        let span = element_pat.span.until(ident.span);
-                        suggestions.push((span, String::new()));
-                    } else {
-                        return;
-                    }
-                }
+                check_subpatterns(
+                    cx,
+                    "dereferencing a slice pattern where every element takes a reference",
+                    ref_pat,
+                    pat,
+                    itertools::chain(before, after),
+                );
+            },
+            PatKind::Tuple(subpatterns, _) | PatKind::TupleStruct(_, subpatterns, _) => {
+                check_subpatterns(
+                    cx,
+                    "dereferencing a tuple pattern where every element takes a reference",
+                    ref_pat,
+                    pat,
+                    subpatterns,
+                );
+            },
+            PatKind::Struct(_, fields, _) => {
+                check_subpatterns(
+                    cx,
+                    "dereferencing a struct pattern where every field's pattern takes a reference",
+                    ref_pat,
+                    pat,
+                    fields.iter().map(|field| field.pat),
+                );
+            },
+            _ => {},
+        }
+    }
+}
 
-                if !suggestions.is_empty() {
-                    span_lint_and_then(
-                        cx,
-                        NEEDLESS_BORROWED_REFERENCE,
-                        pat.span,
-                        "dereferencing a slice pattern where every element takes a reference",
-                        |diag| {
-                            // `&[...]`
-                            //  ^
-                            let span = pat.span.until(sub_pat.span);
-                            suggestions.push((span, String::new()));
+fn check_subpatterns<'tcx>(
+    cx: &LateContext<'tcx>,
+    message: &str,
+    ref_pat: &Pat<'_>,
+    pat: &Pat<'_>,
+    subpatterns: impl IntoIterator<Item = &'tcx Pat<'tcx>>,
+) {
+    let mut suggestions = Vec::new();
 
-                            diag.multipart_suggestion(
-                                "try removing the `&` and `ref` parts",
-                                suggestions,
-                                Applicability::MachineApplicable,
-                            );
-                        },
-                    );
-                }
+    for subpattern in subpatterns {
+        match subpattern.kind {
+            PatKind::Binding(BindingAnnotation::REF, _, ident, None) => {
+                // `ref ident`
+                //  ^^^^
+                let span = subpattern.span.until(ident.span);
+                suggestions.push((span, String::new()));
             },
-            _ => {},
+            PatKind::Wild => {},
+            _ => return,
         }
     }
+
+    if !suggestions.is_empty() {
+        span_lint_and_then(cx, NEEDLESS_BORROWED_REFERENCE, ref_pat.span, message, |diag| {
+            // `&pat`
+            //  ^
+            let span = ref_pat.span.until(pat.span);
+            suggestions.push((span, String::new()));
+
+            diag.multipart_suggestion(
+                "try removing the `&` and `ref` parts",
+                suggestions,
+                Applicability::MachineApplicable,
+            );
+        });
+    }
 }
diff --git a/clippy_lints/src/needless_continue.rs b/clippy_lints/src/needless_continue.rs
index 6f0e755466e..38a75034cd3 100644
--- a/clippy_lints/src/needless_continue.rs
+++ b/clippy_lints/src/needless_continue.rs
@@ -287,7 +287,7 @@ const DROP_ELSE_BLOCK_MSG: &str = "consider dropping the `else` clause";
 
 const DROP_CONTINUE_EXPRESSION_MSG: &str = "consider dropping the `continue` expression";
 
-fn emit_warning<'a>(cx: &EarlyContext<'_>, data: &'a LintData<'_>, header: &str, typ: LintType) {
+fn emit_warning(cx: &EarlyContext<'_>, data: &LintData<'_>, header: &str, typ: LintType) {
     // snip    is the whole *help* message that appears after the warning.
     // message is the warning message.
     // expr    is the expression which the lint warning message refers to.
@@ -313,7 +313,7 @@ fn emit_warning<'a>(cx: &EarlyContext<'_>, data: &'a LintData<'_>, header: &str,
     );
 }
 
-fn suggestion_snippet_for_continue_inside_if<'a>(cx: &EarlyContext<'_>, data: &'a LintData<'_>) -> String {
+fn suggestion_snippet_for_continue_inside_if(cx: &EarlyContext<'_>, data: &LintData<'_>) -> String {
     let cond_code = snippet(cx, data.if_cond.span, "..");
 
     let continue_code = snippet_block(cx, data.if_block.span, "..", Some(data.if_expr.span));
@@ -327,7 +327,7 @@ fn suggestion_snippet_for_continue_inside_if<'a>(cx: &EarlyContext<'_>, data: &'
     )
 }
 
-fn suggestion_snippet_for_continue_inside_else<'a>(cx: &EarlyContext<'_>, data: &'a LintData<'_>) -> String {
+fn suggestion_snippet_for_continue_inside_else(cx: &EarlyContext<'_>, data: &LintData<'_>) -> String {
     let cond_code = snippet(cx, data.if_cond.span, "..");
 
     // Region B
@@ -361,7 +361,7 @@ fn suggestion_snippet_for_continue_inside_else<'a>(cx: &EarlyContext<'_>, data:
     )
 }
 
-fn check_and_warn<'a>(cx: &EarlyContext<'_>, expr: &'a ast::Expr) {
+fn check_and_warn(cx: &EarlyContext<'_>, expr: &ast::Expr) {
     if_chain! {
         if let ast::ExprKind::Loop(loop_block, ..) = &expr.kind;
         if let Some(last_stmt) = loop_block.stmts.last();
diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs
index eeff15bbfb4..55599cd03eb 100644
--- a/clippy_lints/src/needless_pass_by_value.rs
+++ b/clippy_lints/src/needless_pass_by_value.rs
@@ -340,11 +340,5 @@ impl<'tcx> euv::Delegate<'tcx> for MovedVariablesCtxt {
 
     fn mutate(&mut self, _: &euv::PlaceWithHirId<'tcx>, _: HirId) {}
 
-    fn fake_read(
-        &mut self,
-        _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>,
-        _: FakeReadCause,
-        _: HirId,
-    ) {
-    }
+    fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
 }
diff --git a/clippy_lints/src/octal_escapes.rs b/clippy_lints/src/octal_escapes.rs
index 2a7159764e4..ae0a41db918 100644
--- a/clippy_lints/src/octal_escapes.rs
+++ b/clippy_lints/src/octal_escapes.rs
@@ -58,9 +58,9 @@ impl EarlyLintPass for OctalEscapes {
 
         if let ExprKind::Lit(token_lit) = &expr.kind {
             if matches!(token_lit.kind, LitKind::Str) {
-                check_lit(cx, &token_lit, expr.span, true);
+                check_lit(cx, token_lit, expr.span, true);
             } else if matches!(token_lit.kind, LitKind::ByteStr) {
-                check_lit(cx, &token_lit, expr.span, false);
+                check_lit(cx, token_lit, expr.span, false);
             }
         }
     }
diff --git a/clippy_lints/src/operators/arithmetic_side_effects.rs b/clippy_lints/src/operators/arithmetic_side_effects.rs
index 8827daaa3ee..20b82d81a2a 100644
--- a/clippy_lints/src/operators/arithmetic_side_effects.rs
+++ b/clippy_lints/src/operators/arithmetic_side_effects.rs
@@ -1,5 +1,9 @@
 use super::ARITHMETIC_SIDE_EFFECTS;
-use clippy_utils::{consts::constant_simple, diagnostics::span_lint};
+use clippy_utils::{
+    consts::{constant, constant_simple},
+    diagnostics::span_lint,
+    peel_hir_expr_refs,
+};
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
@@ -38,24 +42,6 @@ impl ArithmeticSideEffects {
         }
     }
 
-    /// Assuming that `expr` is a literal integer, checks operators (+=, -=, *, /) in a
-    /// non-constant environment that won't overflow.
-    fn has_valid_op(op: &Spanned<hir::BinOpKind>, expr: &hir::Expr<'_>) -> bool {
-        if let hir::ExprKind::Lit(ref lit) = expr.kind &&
-            let ast::LitKind::Int(value, _) = lit.node
-        {
-            match (&op.node, value) {
-                (hir::BinOpKind::Div | hir::BinOpKind::Rem, 0) => false,
-                (hir::BinOpKind::Add | hir::BinOpKind::Sub, 0)
-                    | (hir::BinOpKind::Div | hir::BinOpKind::Rem, _)
-                    | (hir::BinOpKind::Mul, 0 | 1) => true,
-                _ => false,
-            }
-        } else {
-            false
-        }
-    }
-
     /// Checks if the given `expr` has any of the inner `allowed` elements.
     fn is_allowed_ty(&self, ty: Ty<'_>) -> bool {
         self.allowed
@@ -74,15 +60,14 @@ impl ArithmeticSideEffects {
         self.expr_span = Some(expr.span);
     }
 
-    /// If `expr` does not match any variant of `LiteralIntegerTy`, returns `None`.
-    fn literal_integer<'expr, 'tcx>(expr: &'expr hir::Expr<'tcx>) -> Option<LiteralIntegerTy<'expr, 'tcx>> {
-        if matches!(expr.kind, hir::ExprKind::Lit(_)) {
-            return Some(LiteralIntegerTy::Value(expr));
+    /// If `expr` is not a literal integer like `1`, returns `None`.
+    fn literal_integer(expr: &hir::Expr<'_>) -> Option<u128> {
+        if let hir::ExprKind::Lit(ref lit) = expr.kind && let ast::LitKind::Int(n, _) = lit.node {
+            Some(n)
         }
-        if let hir::ExprKind::AddrOf(.., inn) = expr.kind && let hir::ExprKind::Lit(_) = inn.kind {
-            return Some(LiteralIntegerTy::Ref(inn));
+        else {
+            None
         }
-        None
     }
 
     /// Manages when the lint should be triggered. Operations in constant environments, hard coded
@@ -117,10 +102,20 @@ impl ArithmeticSideEffects {
             return;
         }
         let has_valid_op = if Self::is_integral(lhs_ty) && Self::is_integral(rhs_ty) {
-            match (Self::literal_integer(lhs), Self::literal_integer(rhs)) {
-                (None, Some(lit_int_ty)) | (Some(lit_int_ty), None) => Self::has_valid_op(op, lit_int_ty.into()),
-                (Some(LiteralIntegerTy::Value(_)), Some(LiteralIntegerTy::Value(_))) => true,
-                (None, None) | (Some(_), Some(_)) => false,
+            let (actual_lhs, lhs_ref_counter) = peel_hir_expr_refs(lhs);
+            let (actual_rhs, rhs_ref_counter) = peel_hir_expr_refs(rhs);
+            match (Self::literal_integer(actual_lhs), Self::literal_integer(actual_rhs)) {
+                (None, None) => false,
+                (None, Some(n)) | (Some(n), None) => match (&op.node, n) {
+                    (hir::BinOpKind::Div | hir::BinOpKind::Rem, 0) => false,
+                    (hir::BinOpKind::Add | hir::BinOpKind::Sub, 0)
+                    | (hir::BinOpKind::Div | hir::BinOpKind::Rem, _)
+                    | (hir::BinOpKind::Mul, 0 | 1) => true,
+                    _ => false,
+                },
+                (Some(_), Some(_)) => {
+                    matches!((lhs_ref_counter, rhs_ref_counter), (0, 0))
+                },
             }
         } else {
             false
@@ -129,21 +124,45 @@ impl ArithmeticSideEffects {
             self.issue_lint(cx, expr);
         }
     }
+
+    fn manage_unary_ops<'tcx>(
+        &mut self,
+        cx: &LateContext<'tcx>,
+        expr: &hir::Expr<'tcx>,
+        un_expr: &hir::Expr<'tcx>,
+        un_op: hir::UnOp,
+    ) {
+        let hir::UnOp::Neg = un_op else { return; };
+        if constant(cx, cx.typeck_results(), un_expr).is_some() {
+            return;
+        }
+        let ty = cx.typeck_results().expr_ty(expr).peel_refs();
+        if self.is_allowed_ty(ty) {
+            return;
+        }
+        let actual_un_expr = peel_hir_expr_refs(un_expr).0;
+        if Self::literal_integer(actual_un_expr).is_some() {
+            return;
+        }
+        self.issue_lint(cx, expr);
+    }
+
+    fn should_skip_expr(&mut self, expr: &hir::Expr<'_>) -> bool {
+        self.expr_span.is_some() || self.const_span.map_or(false, |sp| sp.contains(expr.span))
+    }
 }
 
 impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'tcx>) {
-        if self.expr_span.is_some() || self.const_span.map_or(false, |sp| sp.contains(expr.span)) {
+        if self.should_skip_expr(expr) {
             return;
         }
         match &expr.kind {
-            hir::ExprKind::Binary(op, lhs, rhs) | hir::ExprKind::AssignOp(op, lhs, rhs) => {
+            hir::ExprKind::AssignOp(op, lhs, rhs) | hir::ExprKind::Binary(op, lhs, rhs) => {
                 self.manage_bin_ops(cx, expr, op, lhs, rhs);
             },
-            hir::ExprKind::Unary(hir::UnOp::Neg, _) => {
-                if constant_simple(cx, cx.typeck_results(), expr).is_none() {
-                    self.issue_lint(cx, expr);
-                }
+            hir::ExprKind::Unary(un_op, un_expr) => {
+                self.manage_unary_ops(cx, expr, un_expr, *un_op);
             },
             _ => {},
         }
@@ -177,22 +196,3 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
         }
     }
 }
-
-/// Tells if an expression is a integer declared by value or by reference.
-///
-/// If `LiteralIntegerTy::Ref`, then the contained value will be `hir::ExprKind::Lit` rather
-/// than `hirExprKind::Addr`.
-enum LiteralIntegerTy<'expr, 'tcx> {
-    /// For example, `&199`
-    Ref(&'expr hir::Expr<'tcx>),
-    /// For example, `1` or `i32::MAX`
-    Value(&'expr hir::Expr<'tcx>),
-}
-
-impl<'expr, 'tcx> From<LiteralIntegerTy<'expr, 'tcx>> for &'expr hir::Expr<'tcx> {
-    fn from(from: LiteralIntegerTy<'expr, 'tcx>) -> Self {
-        match from {
-            LiteralIntegerTy::Ref(elem) | LiteralIntegerTy::Value(elem) => elem,
-        }
-    }
-}
diff --git a/clippy_lints/src/operators/op_ref.rs b/clippy_lints/src/operators/op_ref.rs
index 71b31b5e4a5..d7917e86a86 100644
--- a/clippy_lints/src/operators/op_ref.rs
+++ b/clippy_lints/src/operators/op_ref.rs
@@ -199,7 +199,7 @@ fn in_impl<'tcx>(
     }
 }
 
-fn are_equal<'tcx>(cx: &LateContext<'tcx>, middle_ty: Ty<'_>, hir_ty: &rustc_hir::Ty<'_>) -> bool {
+fn are_equal(cx: &LateContext<'_>, middle_ty: Ty<'_>, hir_ty: &rustc_hir::Ty<'_>) -> bool {
     if_chain! {
         if let ty::Adt(adt_def, _) = middle_ty.kind();
         if let Some(local_did) = adt_def.did().as_local();
diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs
index 4eb42da1fed..472f52380bb 100644
--- a/clippy_lints/src/option_if_let_else.rs
+++ b/clippy_lints/src/option_if_let_else.rs
@@ -213,11 +213,14 @@ fn try_convert_match<'tcx>(
     cx: &LateContext<'tcx>,
     arms: &[Arm<'tcx>],
 ) -> Option<(&'tcx Pat<'tcx>, &'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> {
-    if arms.len() == 2 {
-        return if is_none_or_err_arm(cx, &arms[1]) {
-            Some((arms[0].pat, arms[0].body, arms[1].body))
-        } else if is_none_or_err_arm(cx, &arms[0]) {
-            Some((arms[1].pat, arms[1].body, arms[0].body))
+    if let [first_arm, second_arm] = arms
+        && first_arm.guard.is_none()
+        && second_arm.guard.is_none()
+        {
+        return if is_none_or_err_arm(cx, second_arm) {
+            Some((first_arm.pat, first_arm.body, second_arm.body))
+        } else if is_none_or_err_arm(cx, first_arm) {
+            Some((second_arm.pat, second_arm.body, first_arm.body))
         } else {
             None
         };
diff --git a/clippy_lints/src/partialeq_to_none.rs b/clippy_lints/src/partialeq_to_none.rs
index 6810a243175..456ded3fc02 100644
--- a/clippy_lints/src/partialeq_to_none.rs
+++ b/clippy_lints/src/partialeq_to_none.rs
@@ -33,7 +33,7 @@ declare_clippy_lint! {
     ///     if f.is_some() { "yay" } else { "nay" }
     /// }
     /// ```
-    #[clippy::version = "1.64.0"]
+    #[clippy::version = "1.65.0"]
     pub PARTIALEQ_TO_NONE,
     style,
     "Binary comparison to `Option<T>::None` relies on `T: PartialEq`, which is unneeded"
diff --git a/clippy_lints/src/pattern_type_mismatch.rs b/clippy_lints/src/pattern_type_mismatch.rs
index a4d265111f9..97b5a4ce364 100644
--- a/clippy_lints/src/pattern_type_mismatch.rs
+++ b/clippy_lints/src/pattern_type_mismatch.rs
@@ -130,7 +130,7 @@ enum DerefPossible {
     Impossible,
 }
 
-fn apply_lint<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'_>, deref_possible: DerefPossible) -> bool {
+fn apply_lint(cx: &LateContext<'_>, pat: &Pat<'_>, deref_possible: DerefPossible) -> bool {
     let maybe_mismatch = find_first_mismatch(cx, pat);
     if let Some((span, mutability, level)) = maybe_mismatch {
         span_lint_and_help(
@@ -163,7 +163,7 @@ enum Level {
     Lower,
 }
 
-fn find_first_mismatch<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'_>) -> Option<(Span, Mutability, Level)> {
+fn find_first_mismatch(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option<(Span, Mutability, Level)> {
     let mut result = None;
     pat.walk(|p| {
         if result.is_some() {
diff --git a/clippy_lints/src/ptr_offset_with_cast.rs b/clippy_lints/src/ptr_offset_with_cast.rs
index 72dda67c72b..47b8891e123 100644
--- a/clippy_lints/src/ptr_offset_with_cast.rs
+++ b/clippy_lints/src/ptr_offset_with_cast.rs
@@ -105,17 +105,17 @@ fn expr_as_ptr_offset_call<'tcx>(
 }
 
 // Is the type of the expression a usize?
-fn is_expr_ty_usize<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> bool {
+fn is_expr_ty_usize(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     cx.typeck_results().expr_ty(expr) == cx.tcx.types.usize
 }
 
 // Is the type of the expression a raw pointer?
-fn is_expr_ty_raw_ptr<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> bool {
+fn is_expr_ty_raw_ptr(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     cx.typeck_results().expr_ty(expr).is_unsafe_ptr()
 }
 
-fn build_suggestion<'tcx>(
-    cx: &LateContext<'tcx>,
+fn build_suggestion(
+    cx: &LateContext<'_>,
     method: Method,
     receiver_expr: &Expr<'_>,
     cast_lhs_expr: &Expr<'_>,
diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs
index bb86fb3b7d4..5269bbd1f1a 100644
--- a/clippy_lints/src/question_mark.rs
+++ b/clippy_lints/src/question_mark.rs
@@ -189,6 +189,7 @@ fn is_early_return(smbl: Symbol, cx: &LateContext<'_>, if_block: &IfBlockType<'_
                             && expr_return_none_or_err(smbl, cx, if_else.unwrap(), let_expr, Some(let_pat_sym)))
                             || is_res_lang_ctor(cx, res, ResultErr)
                                 && expr_return_none_or_err(smbl, cx, if_then, let_expr, Some(let_pat_sym))
+                                && if_else.is_none()
                     },
                     _ => false,
                 }
diff --git a/clippy_lints/src/redundant_closure_call.rs b/clippy_lints/src/redundant_closure_call.rs
index 4cbe9597c53..8e675d34a18 100644
--- a/clippy_lints/src/redundant_closure_call.rs
+++ b/clippy_lints/src/redundant_closure_call.rs
@@ -105,8 +105,8 @@ impl EarlyLintPass for RedundantClosureCall {
 
 impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'_>) {
-        fn count_closure_usage<'a, 'tcx>(
-            cx: &'a LateContext<'tcx>,
+        fn count_closure_usage<'tcx>(
+            cx: &LateContext<'tcx>,
             block: &'tcx hir::Block<'_>,
             path: &'tcx hir::Path<'tcx>,
         ) -> usize {
diff --git a/clippy_lints/src/redundant_pub_crate.rs b/clippy_lints/src/redundant_pub_crate.rs
index 26075e9f70f..833dc4913b4 100644
--- a/clippy_lints/src/redundant_pub_crate.rs
+++ b/clippy_lints/src/redundant_pub_crate.rs
@@ -70,7 +70,8 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
         }
 
         if let ItemKind::Mod { .. } = item.kind {
-            self.is_exported.push(cx.effective_visibilities.is_exported(item.owner_id.def_id));
+            self.is_exported
+                .push(cx.effective_visibilities.is_exported(item.owner_id.def_id));
         }
     }
 
diff --git a/clippy_lints/src/renamed_lints.rs b/clippy_lints/src/renamed_lints.rs
index 76d6ad0b23e..8e214218f23 100644
--- a/clippy_lints/src/renamed_lints.rs
+++ b/clippy_lints/src/renamed_lints.rs
@@ -11,8 +11,6 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
     ("clippy::disallowed_method", "clippy::disallowed_methods"),
     ("clippy::disallowed_type", "clippy::disallowed_types"),
     ("clippy::eval_order_dependence", "clippy::mixed_read_write_in_expression"),
-    ("clippy::for_loop_over_option", "for_loops_over_fallibles"),
-    ("clippy::for_loop_over_result", "for_loops_over_fallibles"),
     ("clippy::identity_conversion", "clippy::useless_conversion"),
     ("clippy::if_let_some_result", "clippy::match_result_ok"),
     ("clippy::logic_bug", "clippy::overly_complex_bool_expr"),
@@ -31,10 +29,13 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
     ("clippy::to_string_in_display", "clippy::recursive_format_impl"),
     ("clippy::zero_width_space", "clippy::invisible_characters"),
     ("clippy::drop_bounds", "drop_bounds"),
+    ("clippy::for_loop_over_option", "for_loops_over_fallibles"),
+    ("clippy::for_loop_over_result", "for_loops_over_fallibles"),
     ("clippy::for_loops_over_fallibles", "for_loops_over_fallibles"),
     ("clippy::into_iter_on_array", "array_into_iter"),
     ("clippy::invalid_atomic_ordering", "invalid_atomic_ordering"),
     ("clippy::invalid_ref", "invalid_value"),
+    ("clippy::let_underscore_drop", "let_underscore_drop"),
     ("clippy::mem_discriminant_non_enum", "enum_intrinsics_non_enums"),
     ("clippy::panic_params", "non_fmt_panics"),
     ("clippy::positional_named_format_parameters", "named_arguments_used_positionally"),
diff --git a/clippy_lints/src/single_component_path_imports.rs b/clippy_lints/src/single_component_path_imports.rs
index 66b79513032..2036e85db7e 100644
--- a/clippy_lints/src/single_component_path_imports.rs
+++ b/clippy_lints/src/single_component_path_imports.rs
@@ -1,8 +1,9 @@
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg};
+use rustc_ast::node_id::{NodeId, NodeMap};
 use rustc_ast::{ptr::P, Crate, Item, ItemKind, MacroDef, ModKind, UseTreeKind};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::{edition::Edition, symbol::kw, Span, Symbol};
 
 declare_clippy_lint! {
@@ -33,51 +34,32 @@ declare_clippy_lint! {
     "imports with single component path are redundant"
 }
 
-declare_lint_pass!(SingleComponentPathImports => [SINGLE_COMPONENT_PATH_IMPORTS]);
+#[derive(Default)]
+pub struct SingleComponentPathImports {
+    /// Buffer found usages to emit when visiting that item so that `#[allow]` works as expected
+    found: NodeMap<Vec<SingleUse>>,
+}
+
+struct SingleUse {
+    name: Symbol,
+    span: Span,
+    item_id: NodeId,
+    can_suggest: bool,
+}
+
+impl_lint_pass!(SingleComponentPathImports => [SINGLE_COMPONENT_PATH_IMPORTS]);
 
 impl EarlyLintPass for SingleComponentPathImports {
     fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) {
         if cx.sess().opts.edition < Edition::Edition2018 {
             return;
         }
-        check_mod(cx, &krate.items);
-    }
-}
 
-fn check_mod(cx: &EarlyContext<'_>, items: &[P<Item>]) {
-    // keep track of imports reused with `self` keyword,
-    // such as `self::crypto_hash` in the example below
-    // ```rust,ignore
-    // use self::crypto_hash::{Algorithm, Hasher};
-    // ```
-    let mut imports_reused_with_self = Vec::new();
-
-    // keep track of single use statements
-    // such as `crypto_hash` in the example below
-    // ```rust,ignore
-    // use crypto_hash;
-    // ```
-    let mut single_use_usages = Vec::new();
-
-    // keep track of macros defined in the module as we don't want it to trigger on this (#7106)
-    // ```rust,ignore
-    // macro_rules! foo { () => {} };
-    // pub(crate) use foo;
-    // ```
-    let mut macros = Vec::new();
-
-    for item in items {
-        track_uses(
-            cx,
-            item,
-            &mut imports_reused_with_self,
-            &mut single_use_usages,
-            &mut macros,
-        );
+        self.check_mod(cx, &krate.items);
     }
 
-    for (name, span, can_suggest) in single_use_usages {
-        if !imports_reused_with_self.contains(&name) {
+    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
+        for SingleUse { span, can_suggest, .. } in self.found.remove(&item.id).into_iter().flatten() {
             if can_suggest {
                 span_lint_and_sugg(
                     cx,
@@ -102,74 +84,127 @@ fn check_mod(cx: &EarlyContext<'_>, items: &[P<Item>]) {
     }
 }
 
-fn track_uses(
-    cx: &EarlyContext<'_>,
-    item: &Item,
-    imports_reused_with_self: &mut Vec<Symbol>,
-    single_use_usages: &mut Vec<(Symbol, Span, bool)>,
-    macros: &mut Vec<Symbol>,
-) {
-    if item.span.from_expansion() || item.vis.kind.is_pub() {
-        return;
-    }
+impl SingleComponentPathImports {
+    fn check_mod(&mut self, cx: &EarlyContext<'_>, items: &[P<Item>]) {
+        // keep track of imports reused with `self` keyword, such as `self::crypto_hash` in the example
+        // below. Removing the `use crypto_hash;` would make this a compile error
+        // ```
+        // use crypto_hash;
+        //
+        // use self::crypto_hash::{Algorithm, Hasher};
+        // ```
+        let mut imports_reused_with_self = Vec::new();
 
-    match &item.kind {
-        ItemKind::Mod(_, ModKind::Loaded(ref items, ..)) => {
-            check_mod(cx, items);
-        },
-        ItemKind::MacroDef(MacroDef { macro_rules: true, .. }) => {
-            macros.push(item.ident.name);
-        },
-        ItemKind::Use(use_tree) => {
-            let segments = &use_tree.prefix.segments;
-
-            // keep track of `use some_module;` usages
-            if segments.len() == 1 {
-                if let UseTreeKind::Simple(None, _, _) = use_tree.kind {
-                    let name = segments[0].ident.name;
-                    if !macros.contains(&name) {
-                        single_use_usages.push((name, item.span, true));
-                    }
-                }
-                return;
+        // keep track of single use statements such as `crypto_hash` in the example below
+        // ```
+        // use crypto_hash;
+        // ```
+        let mut single_use_usages = Vec::new();
+
+        // keep track of macros defined in the module as we don't want it to trigger on this (#7106)
+        // ```
+        // macro_rules! foo { () => {} };
+        // pub(crate) use foo;
+        // ```
+        let mut macros = Vec::new();
+
+        for item in items {
+            self.track_uses(
+                cx,
+                item,
+                &mut imports_reused_with_self,
+                &mut single_use_usages,
+                &mut macros,
+            );
+        }
+
+        for usage in single_use_usages {
+            if !imports_reused_with_self.contains(&usage.name) {
+                self.found.entry(usage.item_id).or_default().push(usage);
             }
+        }
+    }
 
-            if segments.is_empty() {
-                // keep track of `use {some_module, some_other_module};` usages
-                if let UseTreeKind::Nested(trees) = &use_tree.kind {
-                    for tree in trees {
-                        let segments = &tree.0.prefix.segments;
-                        if segments.len() == 1 {
-                            if let UseTreeKind::Simple(None, _, _) = tree.0.kind {
-                                let name = segments[0].ident.name;
-                                if !macros.contains(&name) {
-                                    single_use_usages.push((name, tree.0.span, false));
-                                }
-                            }
+    fn track_uses(
+        &mut self,
+        cx: &EarlyContext<'_>,
+        item: &Item,
+        imports_reused_with_self: &mut Vec<Symbol>,
+        single_use_usages: &mut Vec<SingleUse>,
+        macros: &mut Vec<Symbol>,
+    ) {
+        if item.span.from_expansion() || item.vis.kind.is_pub() {
+            return;
+        }
+
+        match &item.kind {
+            ItemKind::Mod(_, ModKind::Loaded(ref items, ..)) => {
+                self.check_mod(cx, items);
+            },
+            ItemKind::MacroDef(MacroDef { macro_rules: true, .. }) => {
+                macros.push(item.ident.name);
+            },
+            ItemKind::Use(use_tree) => {
+                let segments = &use_tree.prefix.segments;
+
+                // keep track of `use some_module;` usages
+                if segments.len() == 1 {
+                    if let UseTreeKind::Simple(None, _, _) = use_tree.kind {
+                        let name = segments[0].ident.name;
+                        if !macros.contains(&name) {
+                            single_use_usages.push(SingleUse {
+                                name,
+                                span: item.span,
+                                item_id: item.id,
+                                can_suggest: true,
+                            });
                         }
                     }
+                    return;
                 }
-            } else {
-                // keep track of `use self::some_module` usages
-                if segments[0].ident.name == kw::SelfLower {
-                    // simple case such as `use self::module::SomeStruct`
-                    if segments.len() > 1 {
-                        imports_reused_with_self.push(segments[1].ident.name);
-                        return;
-                    }
 
-                    // nested case such as `use self::{module1::Struct1, module2::Struct2}`
+                if segments.is_empty() {
+                    // keep track of `use {some_module, some_other_module};` usages
                     if let UseTreeKind::Nested(trees) = &use_tree.kind {
                         for tree in trees {
                             let segments = &tree.0.prefix.segments;
-                            if !segments.is_empty() {
-                                imports_reused_with_self.push(segments[0].ident.name);
+                            if segments.len() == 1 {
+                                if let UseTreeKind::Simple(None, _, _) = tree.0.kind {
+                                    let name = segments[0].ident.name;
+                                    if !macros.contains(&name) {
+                                        single_use_usages.push(SingleUse {
+                                            name,
+                                            span: tree.0.span,
+                                            item_id: item.id,
+                                            can_suggest: false,
+                                        });
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    // keep track of `use self::some_module` usages
+                    if segments[0].ident.name == kw::SelfLower {
+                        // simple case such as `use self::module::SomeStruct`
+                        if segments.len() > 1 {
+                            imports_reused_with_self.push(segments[1].ident.name);
+                            return;
+                        }
+
+                        // nested case such as `use self::{module1::Struct1, module2::Struct2}`
+                        if let UseTreeKind::Nested(trees) = &use_tree.kind {
+                            for tree in trees {
+                                let segments = &tree.0.prefix.segments;
+                                if !segments.is_empty() {
+                                    imports_reused_with_self.push(segments[0].ident.name);
+                                }
                             }
                         }
                     }
                 }
-            }
-        },
-        _ => {},
+            },
+            _ => {},
+        }
     }
 }
diff --git a/clippy_lints/src/slow_vector_initialization.rs b/clippy_lints/src/slow_vector_initialization.rs
index 76039923151..a2109038a05 100644
--- a/clippy_lints/src/slow_vector_initialization.rs
+++ b/clippy_lints/src/slow_vector_initialization.rs
@@ -168,7 +168,7 @@ impl SlowVectorInit {
         };
     }
 
-    fn emit_lint<'tcx>(cx: &LateContext<'tcx>, slow_fill: &Expr<'_>, vec_alloc: &VecAllocation<'_>, msg: &str) {
+    fn emit_lint(cx: &LateContext<'_>, slow_fill: &Expr<'_>, vec_alloc: &VecAllocation<'_>, msg: &str) {
         let len_expr = Sugg::hir(cx, vec_alloc.len_expr, "len");
 
         span_lint_and_then(cx, SLOW_VECTOR_INITIALIZATION, slow_fill.span, msg, |diag| {
diff --git a/clippy_lints/src/suspicious_xor_used_as_pow.rs b/clippy_lints/src/suspicious_xor_used_as_pow.rs
new file mode 100644
index 00000000000..301aa5798bf
--- /dev/null
+++ b/clippy_lints/src/suspicious_xor_used_as_pow.rs
@@ -0,0 +1,53 @@
+use clippy_utils::{numeric_literal::NumericLiteral, source::snippet_with_context};
+use rustc_errors::Applicability;
+use rustc_hir::{BinOpKind, Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_middle::lint::in_external_macro;
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Warns for a Bitwise XOR (`^`) operator being probably confused as a powering. It will not trigger if any of the numbers are not in decimal.
+    /// ### Why is this bad?
+    ///	It's most probably a typo and may lead to unexpected behaviours.
+    /// ### Example
+    /// ```rust
+    /// let x = 3_i32 ^ 4_i32;
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// let x = 3_i32.pow(4);
+    /// ```
+    #[clippy::version = "1.66.0"]
+    pub SUSPICIOUS_XOR_USED_AS_POW,
+    restriction,
+    "XOR (`^`) operator possibly used as exponentiation operator"
+}
+declare_lint_pass!(ConfusingXorAndPow => [SUSPICIOUS_XOR_USED_AS_POW]);
+
+impl LateLintPass<'_> for ConfusingXorAndPow {
+    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+        if !in_external_macro(cx.sess(), expr.span) &&
+        	let ExprKind::Binary(op, left, right) = &expr.kind &&
+            op.node == BinOpKind::BitXor &&
+            left.span.ctxt() == right.span.ctxt() &&
+            let ExprKind::Lit(lit_left) = &left.kind &&
+            let ExprKind::Lit(lit_right) = &right.kind &&
+            let snip_left = snippet_with_context(cx, lit_left.span, lit_left.span.ctxt(), "..", &mut Applicability::MaybeIncorrect) &&
+            let snip_right = snippet_with_context(cx, lit_right.span, lit_right.span.ctxt(), "..", &mut Applicability::MaybeIncorrect) &&
+            let Some(left_val) = NumericLiteral::from_lit_kind(&snip_left.0, &lit_left.node) &&
+            let Some(right_val) = NumericLiteral::from_lit_kind(&snip_right.0, &lit_right.node) &&
+			left_val.is_decimal() &&
+			right_val.is_decimal() {
+					clippy_utils::diagnostics::span_lint_and_sugg(
+					        cx,
+					        SUSPICIOUS_XOR_USED_AS_POW,
+					        expr.span,
+					        "`^` is not the exponentiation operator",
+					        "did you mean to write",
+					        format!("{}.pow({})", left_val.format(), right_val.format()),
+					        Applicability::MaybeIncorrect,
+					    );
+		}
+    }
+}
diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs
index f46c21e1265..c374529d1ea 100644
--- a/clippy_lints/src/swap.rs
+++ b/clippy_lints/src/swap.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{can_mut_borrow_both, eq_expr_value, std_or_core};
+use clippy_utils::{can_mut_borrow_both, eq_expr_value, in_constant, std_or_core};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Block, Expr, ExprKind, PatKind, QPath, Stmt, StmtKind};
@@ -16,6 +16,8 @@ declare_clippy_lint! {
     /// ### What it does
     /// Checks for manual swapping.
     ///
+    /// Note that the lint will not be emitted in const blocks, as the suggestion would not be applicable.
+    ///
     /// ### Why is this bad?
     /// The `std::mem::swap` function exposes the intent better
     /// without deinitializing or copying either variable.
@@ -138,6 +140,10 @@ fn generate_swap_warning(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>, spa
 
 /// Implementation of the `MANUAL_SWAP` lint.
 fn check_manual_swap(cx: &LateContext<'_>, block: &Block<'_>) {
+    if in_constant(cx, block.hir_id) {
+        return;
+    }
+
     for w in block.stmts.windows(3) {
         if_chain! {
             // let t = foo();
diff --git a/clippy_lints/src/trailing_empty_array.rs b/clippy_lints/src/trailing_empty_array.rs
index 8cf3efc8dc7..63b326048a4 100644
--- a/clippy_lints/src/trailing_empty_array.rs
+++ b/clippy_lints/src/trailing_empty_array.rs
@@ -1,9 +1,9 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use rustc_hir::{HirId, Item, ItemKind};
+use clippy_utils::has_repr_attr;
+use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::Const;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -72,7 +72,3 @@ fn is_struct_with_trailing_zero_sized_array(cx: &LateContext<'_>, item: &Item<'_
         }
     }
 }
-
-fn has_repr_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool {
-    cx.tcx.hir().attrs(hir_id).iter().any(|attr| attr.has_name(sym::repr))
-}
diff --git a/clippy_lints/src/transmute/transmute_undefined_repr.rs b/clippy_lints/src/transmute/transmute_undefined_repr.rs
index 3d4bbbf648c..34642f4b122 100644
--- a/clippy_lints/src/transmute/transmute_undefined_repr.rs
+++ b/clippy_lints/src/transmute/transmute_undefined_repr.rs
@@ -27,32 +27,24 @@ pub(super) fn check<'tcx>(
 
             // `Repr(C)` <-> unordered type.
             // If the first field of the `Repr(C)` type matches then the transmute is ok
-            (
-                ReducedTy::OrderedFields(_, Some(from_sub_ty)),
-                ReducedTy::UnorderedFields(to_sub_ty),
-            )
-            | (
-                ReducedTy::UnorderedFields(from_sub_ty),
-                ReducedTy::OrderedFields(_, Some(to_sub_ty)),
-            ) => {
+            (ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::UnorderedFields(to_sub_ty))
+            | (ReducedTy::UnorderedFields(from_sub_ty), ReducedTy::OrderedFields(_, Some(to_sub_ty))) => {
                 from_ty = from_sub_ty;
                 to_ty = to_sub_ty;
                 continue;
-            }
-            (ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::Other(to_sub_ty))
-                if reduced_tys.to_fat_ptr =>
-            {
+            },
+            (ReducedTy::OrderedFields(_, Some(from_sub_ty)), ReducedTy::Other(to_sub_ty)) if reduced_tys.to_fat_ptr => {
                 from_ty = from_sub_ty;
                 to_ty = to_sub_ty;
                 continue;
-            }
+            },
             (ReducedTy::Other(from_sub_ty), ReducedTy::OrderedFields(_, Some(to_sub_ty)))
                 if reduced_tys.from_fat_ptr =>
             {
                 from_ty = from_sub_ty;
                 to_ty = to_sub_ty;
                 continue;
-            }
+            },
 
             // ptr <-> ptr
             (ReducedTy::Other(from_sub_ty), ReducedTy::Other(to_sub_ty))
@@ -62,19 +54,19 @@ pub(super) fn check<'tcx>(
                 from_ty = from_sub_ty;
                 to_ty = to_sub_ty;
                 continue;
-            }
+            },
 
             // fat ptr <-> (*size, *size)
             (ReducedTy::Other(_), ReducedTy::UnorderedFields(to_ty))
                 if reduced_tys.from_fat_ptr && is_size_pair(to_ty) =>
             {
                 return false;
-            }
+            },
             (ReducedTy::UnorderedFields(from_ty), ReducedTy::Other(_))
                 if reduced_tys.to_fat_ptr && is_size_pair(from_ty) =>
             {
                 return false;
-            }
+            },
 
             // fat ptr -> some struct | some struct -> fat ptr
             (ReducedTy::Other(_), _) if reduced_tys.from_fat_ptr => {
@@ -85,14 +77,12 @@ pub(super) fn check<'tcx>(
                     &format!("transmute from `{from_ty_orig}` which has an undefined layout"),
                     |diag| {
                         if from_ty_orig.peel_refs() != from_ty.peel_refs() {
-                            diag.note(&format!(
-                                "the contained type `{from_ty}` has an undefined layout"
-                            ));
+                            diag.note(&format!("the contained type `{from_ty}` has an undefined layout"));
                         }
                     },
                 );
                 return true;
-            }
+            },
             (_, ReducedTy::Other(_)) if reduced_tys.to_fat_ptr => {
                 span_lint_and_then(
                     cx,
@@ -101,18 +91,14 @@ pub(super) fn check<'tcx>(
                     &format!("transmute to `{to_ty_orig}` which has an undefined layout"),
                     |diag| {
                         if to_ty_orig.peel_refs() != to_ty.peel_refs() {
-                            diag.note(&format!(
-                                "the contained type `{to_ty}` has an undefined layout"
-                            ));
+                            diag.note(&format!("the contained type `{to_ty}` has an undefined layout"));
                         }
                     },
                 );
                 return true;
-            }
+            },
 
-            (ReducedTy::UnorderedFields(from_ty), ReducedTy::UnorderedFields(to_ty))
-                if from_ty != to_ty =>
-            {
+            (ReducedTy::UnorderedFields(from_ty), ReducedTy::UnorderedFields(to_ty)) if from_ty != to_ty => {
                 let same_adt_did = if let (ty::Adt(from_def, from_subs), ty::Adt(to_def, to_subs))
                         = (from_ty.kind(), to_ty.kind())
                         && from_def == to_def
@@ -139,25 +125,19 @@ pub(super) fn check<'tcx>(
                             ));
                         } else {
                             if from_ty_orig.peel_refs() != from_ty {
-                                diag.note(&format!(
-                                    "the contained type `{from_ty}` has an undefined layout"
-                                ));
+                                diag.note(&format!("the contained type `{from_ty}` has an undefined layout"));
                             }
                             if to_ty_orig.peel_refs() != to_ty {
-                                diag.note(&format!(
-                                    "the contained type `{to_ty}` has an undefined layout"
-                                ));
+                                diag.note(&format!("the contained type `{to_ty}` has an undefined layout"));
                             }
                         }
                     },
                 );
                 return true;
-            }
+            },
             (
                 ReducedTy::UnorderedFields(from_ty),
-                ReducedTy::Other(_)
-                | ReducedTy::OrderedFields(..)
-                | ReducedTy::TypeErasure { raw_ptr_only: true },
+                ReducedTy::Other(_) | ReducedTy::OrderedFields(..) | ReducedTy::TypeErasure { raw_ptr_only: true },
             ) => {
                 span_lint_and_then(
                     cx,
@@ -166,18 +146,14 @@ pub(super) fn check<'tcx>(
                     &format!("transmute from `{from_ty_orig}` which has an undefined layout"),
                     |diag| {
                         if from_ty_orig.peel_refs() != from_ty {
-                            diag.note(&format!(
-                                "the contained type `{from_ty}` has an undefined layout"
-                            ));
+                            diag.note(&format!("the contained type `{from_ty}` has an undefined layout"));
                         }
                     },
                 );
                 return true;
-            }
+            },
             (
-                ReducedTy::Other(_)
-                | ReducedTy::OrderedFields(..)
-                | ReducedTy::TypeErasure { raw_ptr_only: true },
+                ReducedTy::Other(_) | ReducedTy::OrderedFields(..) | ReducedTy::TypeErasure { raw_ptr_only: true },
                 ReducedTy::UnorderedFields(to_ty),
             ) => {
                 span_lint_and_then(
@@ -187,25 +163,19 @@ pub(super) fn check<'tcx>(
                     &format!("transmute into `{to_ty_orig}` which has an undefined layout"),
                     |diag| {
                         if to_ty_orig.peel_refs() != to_ty {
-                            diag.note(&format!(
-                                "the contained type `{to_ty}` has an undefined layout"
-                            ));
+                            diag.note(&format!("the contained type `{to_ty}` has an undefined layout"));
                         }
                     },
                 );
                 return true;
-            }
+            },
             (
-                ReducedTy::OrderedFields(..)
-                | ReducedTy::Other(_)
-                | ReducedTy::TypeErasure { raw_ptr_only: true },
-                ReducedTy::OrderedFields(..)
-                | ReducedTy::Other(_)
-                | ReducedTy::TypeErasure { raw_ptr_only: true },
+                ReducedTy::OrderedFields(..) | ReducedTy::Other(_) | ReducedTy::TypeErasure { raw_ptr_only: true },
+                ReducedTy::OrderedFields(..) | ReducedTy::Other(_) | ReducedTy::TypeErasure { raw_ptr_only: true },
             )
             | (ReducedTy::UnorderedFields(_), ReducedTy::UnorderedFields(_)) => {
                 break;
-            }
+            },
         }
     }
 
@@ -223,38 +193,42 @@ struct ReducedTys<'tcx> {
 }
 
 /// Remove references so long as both types are references.
-fn reduce_refs<'tcx>(
-    cx: &LateContext<'tcx>,
-    mut from_ty: Ty<'tcx>,
-    mut to_ty: Ty<'tcx>,
-) -> ReducedTys<'tcx> {
+fn reduce_refs<'tcx>(cx: &LateContext<'tcx>, mut from_ty: Ty<'tcx>, mut to_ty: Ty<'tcx>) -> ReducedTys<'tcx> {
     let mut from_raw_ptr = false;
     let mut to_raw_ptr = false;
-    let (from_fat_ptr, to_fat_ptr) =
-        loop {
-            break match (from_ty.kind(), to_ty.kind()) {
-                (
-                    &(ty::Ref(_, from_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: from_sub_ty, .. })),
-                    &(ty::Ref(_, to_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: to_sub_ty, .. })),
-                ) => {
-                    from_raw_ptr = matches!(*from_ty.kind(), ty::RawPtr(_));
-                    from_ty = from_sub_ty;
-                    to_raw_ptr = matches!(*to_ty.kind(), ty::RawPtr(_));
-                    to_ty = to_sub_ty;
-                    continue;
-                }
-                (
-                    &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })),
-                    _,
-                ) if !unsized_ty.is_sized(cx.tcx, cx.param_env) => (true, false),
-                (
-                    _,
-                    &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })),
-                ) if !unsized_ty.is_sized(cx.tcx, cx.param_env) => (false, true),
-                _ => (false, false),
-            };
+    let (from_fat_ptr, to_fat_ptr) = loop {
+        break match (from_ty.kind(), to_ty.kind()) {
+            (
+                &(ty::Ref(_, from_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: from_sub_ty, .. })),
+                &(ty::Ref(_, to_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: to_sub_ty, .. })),
+            ) => {
+                from_raw_ptr = matches!(*from_ty.kind(), ty::RawPtr(_));
+                from_ty = from_sub_ty;
+                to_raw_ptr = matches!(*to_ty.kind(), ty::RawPtr(_));
+                to_ty = to_sub_ty;
+                continue;
+            },
+            (&(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })), _)
+                if !unsized_ty.is_sized(cx.tcx, cx.param_env) =>
+            {
+                (true, false)
+            },
+            (_, &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })))
+                if !unsized_ty.is_sized(cx.tcx, cx.param_env) =>
+            {
+                (false, true)
+            },
+            _ => (false, false),
         };
-    ReducedTys { from_ty, to_ty, from_raw_ptr, to_raw_ptr, from_fat_ptr, to_fat_ptr }
+    };
+    ReducedTys {
+        from_ty,
+        to_ty,
+        from_raw_ptr,
+        to_raw_ptr,
+        from_fat_ptr,
+        to_fat_ptr,
+    }
 }
 
 enum ReducedTy<'tcx> {
@@ -277,11 +251,11 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
         return match *ty.kind() {
             ty::Array(sub_ty, _) if matches!(sub_ty.kind(), ty::Int(_) | ty::Uint(_)) => {
                 ReducedTy::TypeErasure { raw_ptr_only: false }
-            }
+            },
             ty::Array(sub_ty, _) | ty::Slice(sub_ty) => {
                 ty = sub_ty;
                 continue;
-            }
+            },
             ty::Tuple(args) if args.is_empty() => ReducedTy::TypeErasure { raw_ptr_only: false },
             ty::Tuple(args) => {
                 let mut iter = args.iter();
@@ -293,7 +267,7 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
                     continue;
                 }
                 ReducedTy::UnorderedFields(ty)
-            }
+            },
             ty::Adt(def, substs) if def.is_struct() => {
                 let mut iter = def
                     .non_enum_variant()
@@ -312,12 +286,10 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx>
                 } else {
                     ReducedTy::UnorderedFields(ty)
                 }
-            }
-            ty::Adt(def, _)
-                if def.is_enum() && (def.variants().is_empty() || is_c_void(cx, ty)) =>
-            {
+            },
+            ty::Adt(def, _) if def.is_enum() && (def.variants().is_empty() || is_c_void(cx, ty)) => {
                 ReducedTy::TypeErasure { raw_ptr_only: false }
-            }
+            },
             // TODO: Check if the conversion to or from at least one of a union's fields is valid.
             ty::Adt(def, _) if def.is_union() => ReducedTy::TypeErasure { raw_ptr_only: false },
             ty::Foreign(_) | ty::Param(_) => ReducedTy::TypeErasure { raw_ptr_only: false },
@@ -356,11 +328,7 @@ fn same_except_params<'tcx>(subs1: SubstsRef<'tcx>, subs2: SubstsRef<'tcx>) -> b
     for (ty1, ty2) in subs1.types().zip(subs2.types()).filter(|(ty1, ty2)| ty1 != ty2) {
         match (ty1.kind(), ty2.kind()) {
             (ty::Param(_), _) | (_, ty::Param(_)) => (),
-            (ty::Adt(adt1, subs1), ty::Adt(adt2, subs2))
-                if adt1 == adt2 && same_except_params(subs1, subs2) =>
-            {
-                ()
-            }
+            (ty::Adt(adt1, subs1), ty::Adt(adt2, subs2)) if adt1 == adt2 && same_except_params(subs1, subs2) => (),
             _ => return false,
         }
     }
diff --git a/clippy_lints/src/transmute/utils.rs b/clippy_lints/src/transmute/utils.rs
index 641cdf5d330..49d863ec03f 100644
--- a/clippy_lints/src/transmute/utils.rs
+++ b/clippy_lints/src/transmute/utils.rs
@@ -1,9 +1,9 @@
+use rustc_hir as hir;
 use rustc_hir::Expr;
 use rustc_hir_typeck::{cast, FnCtxt, Inherited};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{cast::CastKind, Ty};
 use rustc_span::DUMMY_SP;
-use rustc_hir as hir;
 
 // check if the component types of the transmuted collection and the result have different ABI,
 // size or alignment
@@ -55,9 +55,14 @@ fn check_cast<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>
         );
 
         if let Ok(check) = cast::CastCheck::new(
-            &fn_ctxt, e, from_ty, to_ty,
+            &fn_ctxt,
+            e,
+            from_ty,
+            to_ty,
             // We won't show any error to the user, so we don't care what the span is here.
-            DUMMY_SP, DUMMY_SP, hir::Constness::NotConst,
+            DUMMY_SP,
+            DUMMY_SP,
+            hir::Constness::NotConst,
         ) {
             let res = check.do_check(&fn_ctxt);
 
diff --git a/clippy_lints/src/types/box_collection.rs b/clippy_lints/src/types/box_collection.rs
index 802415e163d..43665a922d4 100644
--- a/clippy_lints/src/types/box_collection.rs
+++ b/clippy_lints/src/types/box_collection.rs
@@ -39,12 +39,19 @@ fn get_std_collection(cx: &LateContext<'_>, qpath: &QPath<'_>) -> Option<Symbol>
     let id = path_def_id(cx, param)?;
     cx.tcx
         .get_diagnostic_name(id)
-        .filter(|&name| matches!(name, sym::HashMap | sym::Vec | sym::HashSet
-            | sym::VecDeque
-            | sym::LinkedList
-            | sym::BTreeMap
-            | sym::BTreeSet
-            | sym::BinaryHeap))
+        .filter(|&name| {
+            matches!(
+                name,
+                sym::HashMap
+                    | sym::Vec
+                    | sym::HashSet
+                    | sym::VecDeque
+                    | sym::LinkedList
+                    | sym::BTreeMap
+                    | sym::BTreeSet
+                    | sym::BinaryHeap
+            )
+        })
         .or_else(|| {
             cx.tcx
                 .lang_items()
diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs
index f6de87b0526..20978e81dc5 100644
--- a/clippy_lints/src/types/mod.rs
+++ b/clippy_lints/src/types/mod.rs
@@ -379,7 +379,9 @@ impl<'tcx> LateLintPass<'tcx> for Types {
     }
 
     fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) {
-        let is_exported = cx.effective_visibilities.is_exported(cx.tcx.hir().local_def_id(field.hir_id));
+        let is_exported = cx
+            .effective_visibilities
+            .is_exported(cx.tcx.hir().local_def_id(field.hir_id));
 
         self.check_ty(
             cx,
diff --git a/clippy_lints/src/types/redundant_allocation.rs b/clippy_lints/src/types/redundant_allocation.rs
index 2b964b64a33..fae5385ffc8 100644
--- a/clippy_lints/src/types/redundant_allocation.rs
+++ b/clippy_lints/src/types/redundant_allocation.rs
@@ -5,16 +5,12 @@ use rustc_errors::Applicability;
 use rustc_hir::{self as hir, def_id::DefId, QPath, TyKind};
 use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::LateContext;
+use rustc_middle::ty::TypeVisitable;
 use rustc_span::symbol::sym;
 
 use super::{utils, REDUNDANT_ALLOCATION};
 
-pub(super) fn check(
-    cx: &LateContext<'_>,
-    hir_ty: &hir::Ty<'_>,
-    qpath: &QPath<'_>,
-    def_id: DefId,
-) -> bool {
+pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {
     let mut applicability = Applicability::MaybeIncorrect;
     let outer_sym = if Some(def_id) == cx.tcx.lang_items().owned_box() {
         "Box"
@@ -34,12 +30,7 @@ pub(super) fn check(
             hir_ty.span,
             &format!("usage of `{outer_sym}<{generic_snippet}>`"),
             |diag| {
-                diag.span_suggestion(
-                    hir_ty.span,
-                    "try",
-                    format!("{generic_snippet}"),
-                    applicability,
-                );
+                diag.span_suggestion(hir_ty.span, "try", format!("{generic_snippet}"), applicability);
                 diag.note(&format!(
                     "`{generic_snippet}` is already a pointer, `{outer_sym}<{generic_snippet}>` allocates a pointer on the heap"
                 ));
@@ -61,15 +52,16 @@ pub(super) fn check(
         return false
     };
     let inner_span = match qpath_generic_tys(inner_qpath).next() {
-        Some(ty) => {
+        Some(hir_ty) => {
             // Reallocation of a fat pointer causes it to become thin. `hir_ty_to_ty` is safe to use
             // here because `mod.rs` guarantees this lint is only run on types outside of bodies and
             // is not run on locals.
-            if !hir_ty_to_ty(cx.tcx, ty).is_sized(cx.tcx, cx.param_env) {
+            let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+            if ty.has_escaping_bound_vars() || !ty.is_sized(cx.tcx, cx.param_env) {
                 return false;
             }
-            ty.span
-        }
+            hir_ty.span
+        },
         None => return false,
     };
     if inner_sym == outer_sym {
diff --git a/clippy_lints/src/types/vec_box.rs b/clippy_lints/src/types/vec_box.rs
index 9ad2cb853d3..7a3c7cd8a99 100644
--- a/clippy_lints/src/types/vec_box.rs
+++ b/clippy_lints/src/types/vec_box.rs
@@ -42,7 +42,7 @@ pub(super) fn check(
             if !ty_ty.has_escaping_bound_vars();
             if ty_ty.is_sized(cx.tcx, cx.param_env);
             if let Ok(ty_ty_size) = cx.layout_of(ty_ty).map(|l| l.size.bytes());
-            if ty_ty_size <= box_size_threshold;
+            if ty_ty_size < box_size_threshold;
             then {
                 span_lint_and_sugg(
                     cx,
diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs
index d2e675a783e..e8f15a44473 100644
--- a/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -68,7 +68,8 @@ impl LateLintPass<'_> for UndocumentedUnsafeBlocks {
             && !in_external_macro(cx.tcx.sess, block.span)
             && !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, block.hir_id)
             && !is_unsafe_from_proc_macro(cx, block.span)
-            && !block_has_safety_comment(cx, block)
+            && !block_has_safety_comment(cx, block.span)
+            && !block_parents_have_safety_comment(cx, block.hir_id)
         {
             let source_map = cx.tcx.sess.source_map();
             let span = if source_map.is_multiline(block.span) {
@@ -126,8 +127,41 @@ fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, span: Span) -> bool {
         .map_or(true, |src| !src.starts_with("unsafe"))
 }
 
+// Checks if any parent {expression, statement, block, local, const, static}
+// has a safety comment
+fn block_parents_have_safety_comment(cx: &LateContext<'_>, id: hir::HirId) -> bool {
+    if let Some(node) = get_parent_node(cx.tcx, id) {
+        return match node {
+            Node::Expr(expr) => !is_branchy(expr) && span_in_body_has_safety_comment(cx, expr.span),
+            Node::Stmt(hir::Stmt {
+                kind:
+                    hir::StmtKind::Local(hir::Local { span, .. })
+                    | hir::StmtKind::Expr(hir::Expr { span, .. })
+                    | hir::StmtKind::Semi(hir::Expr { span, .. }),
+                ..
+            })
+            | Node::Local(hir::Local { span, .. })
+            | Node::Item(hir::Item {
+                kind: hir::ItemKind::Const(..) | ItemKind::Static(..),
+                span,
+                ..
+            }) => span_in_body_has_safety_comment(cx, *span),
+            _ => false,
+        };
+    }
+    false
+}
+
+/// Checks if an expression is "branchy", e.g. loop, match/if/etc.
+fn is_branchy(expr: &hir::Expr<'_>) -> bool {
+    matches!(
+        expr.kind,
+        hir::ExprKind::If(..) | hir::ExprKind::Loop(..) | hir::ExprKind::Match(..)
+    )
+}
+
 /// Checks if the lines immediately preceding the block contain a safety comment.
-fn block_has_safety_comment(cx: &LateContext<'_>, block: &hir::Block<'_>) -> bool {
+fn block_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
     // This intentionally ignores text before the start of a function so something like:
     // ```
     //     // SAFETY: reason
@@ -136,7 +170,7 @@ fn block_has_safety_comment(cx: &LateContext<'_>, block: &hir::Block<'_>) -> boo
     // won't work. This is to avoid dealing with where such a comment should be place relative to
     // attributes and doc comments.
 
-    span_from_macro_expansion_has_safety_comment(cx, block.span) || span_in_body_has_safety_comment(cx, block.span)
+    span_from_macro_expansion_has_safety_comment(cx, span) || span_in_body_has_safety_comment(cx, span)
 }
 
 /// Checks if the lines immediately preceding the item contain a safety comment.
diff --git a/clippy_lints/src/unsafe_removed_from_name.rs b/clippy_lints/src/unsafe_removed_from_name.rs
index 32cd4681201..95258652768 100644
--- a/clippy_lints/src/unsafe_removed_from_name.rs
+++ b/clippy_lints/src/unsafe_removed_from_name.rs
@@ -50,7 +50,7 @@ fn check_use_tree(use_tree: &UseTree, cx: &EarlyContext<'_>, span: Span) {
         },
         UseTreeKind::Simple(None, ..) | UseTreeKind::Glob => {},
         UseTreeKind::Nested(ref nested_use_tree) => {
-            for &(ref use_tree, _) in nested_use_tree {
+            for (use_tree, _) in nested_use_tree {
                 check_use_tree(use_tree, cx, span);
             }
         },
diff --git a/clippy_lints/src/unused_peekable.rs b/clippy_lints/src/unused_peekable.rs
index b452be08409..4ee16d9a5e4 100644
--- a/clippy_lints/src/unused_peekable.rs
+++ b/clippy_lints/src/unused_peekable.rs
@@ -36,7 +36,7 @@ declare_clippy_lint! {
     ///     // ...
     /// }
     /// ```
-    #[clippy::version = "1.64.0"]
+    #[clippy::version = "1.65.0"]
     pub UNUSED_PEEKABLE,
     nursery,
     "creating a peekable iterator without using any of its methods"
diff --git a/clippy_lints/src/unused_rounding.rs b/clippy_lints/src/unused_rounding.rs
index 5ab351bc29c..aac6719a8dc 100644
--- a/clippy_lints/src/unused_rounding.rs
+++ b/clippy_lints/src/unused_rounding.rs
@@ -30,16 +30,15 @@ declare_clippy_lint! {
 declare_lint_pass!(UnusedRounding => [UNUSED_ROUNDING]);
 
 fn is_useless_rounding(expr: &Expr) -> Option<(&str, String)> {
-    if let ExprKind::MethodCall(box MethodCall { seg, receiver, .. }) = &expr.kind
-        && let method_name = seg.ident.name.as_str()
+    if let ExprKind::MethodCall(box MethodCall { seg:name_ident, receiver, .. }) = &expr.kind
+        && let method_name = name_ident.ident.name.as_str()
         && (method_name == "ceil" || method_name == "round" || method_name == "floor")
         && let ExprKind::Lit(token_lit) = &receiver.kind
         && token_lit.is_semantic_float() {
-            let f = token_lit.symbol.as_str().parse::<f64>().unwrap();
             let mut f_str = token_lit.symbol.to_string();
-            match token_lit.suffix {
-                Some(suffix) => f_str.push_str(suffix.as_str()),
-                None => {}
+            let f = f_str.trim_end_matches('_').parse::<f64>().unwrap();
+            if let Some(suffix) = token_lit.suffix {
+                f_str.push_str(suffix.as_str());
             }
             if f.fract() == 0.0 {
                 Some((method_name, f_str))
diff --git a/clippy_lints/src/unused_unit.rs b/clippy_lints/src/unused_unit.rs
index cd1d90e860b..cad8da18c2f 100644
--- a/clippy_lints/src/unused_unit.rs
+++ b/clippy_lints/src/unused_unit.rs
@@ -1,8 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::{position_before_rarrow, snippet_opt};
 use if_chain::if_chain;
-use rustc_ast::ast;
-use rustc_ast::visit::FnKind;
+use rustc_ast::{ast, visit::FnKind, ClosureBinder};
 use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -43,6 +42,11 @@ impl EarlyLintPass for UnusedUnit {
             if let ast::TyKind::Tup(ref vals) = ty.kind;
             if vals.is_empty() && !ty.span.from_expansion() && get_def(span) == get_def(ty.span);
             then {
+                // implicit types in closure signatures are forbidden when `for<...>` is present
+                if let FnKind::Closure(&ClosureBinder::For { .. }, ..) = kind {
+                    return;
+                }
+
                 lint_unneeded_unit_return(cx, ty, span);
             }
         }
diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs
index c6cdf3f85fc..e2860db71a5 100644
--- a/clippy_lints/src/use_self.rs
+++ b/clippy_lints/src/use_self.rs
@@ -30,7 +30,6 @@ declare_clippy_lint! {
     ///
     /// ### Known problems
     /// - Unaddressed false negative in fn bodies of trait implementations
-    /// - False positive with associated types in traits (#4140)
     ///
     /// ### Example
     /// ```rust
@@ -103,6 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
             if parameters.as_ref().map_or(true, |params| {
                 !params.parenthesized && !params.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_)))
             });
+            if !item.span.from_expansion();
             if !is_from_proc_macro(cx, item); // expensive, should be last check
             then {
                 StackItem::Check {
@@ -234,24 +234,13 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
             then {} else { return; }
         }
         match expr.kind {
-            ExprKind::Struct(QPath::Resolved(_, path), ..) => match path.res {
-                Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => (),
-                Res::Def(DefKind::Variant, _) => lint_path_to_variant(cx, path),
-                _ => span_lint(cx, path.span),
-            },
-            // tuple struct instantiation (`Foo(arg)` or `Enum::Foo(arg)`)
+            ExprKind::Struct(QPath::Resolved(_, path), ..) => check_path(cx, path),
             ExprKind::Call(fun, _) => {
                 if let ExprKind::Path(QPath::Resolved(_, path)) = fun.kind {
-                    if let Res::Def(DefKind::Ctor(ctor_of, _), ..) = path.res {
-                        match ctor_of {
-                            CtorOf::Variant => lint_path_to_variant(cx, path),
-                            CtorOf::Struct => span_lint(cx, path.span),
-                        }
-                    }
+                    check_path(cx, path);
                 }
             },
-            // unit enum variants (`Enum::A`)
-            ExprKind::Path(QPath::Resolved(_, path)) => lint_path_to_variant(cx, path),
+            ExprKind::Path(QPath::Resolved(_, path)) => check_path(cx, path),
             _ => (),
         }
     }
@@ -267,15 +256,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
                  | PatKind::Struct(QPath::Resolved(_, path), _, _) = pat.kind;
             if cx.typeck_results().pat_ty(pat) == cx.tcx.type_of(impl_id);
             then {
-                match path.res {
-                    Res::Def(DefKind::Ctor(ctor_of, _), ..) => match ctor_of {
-                            CtorOf::Variant => lint_path_to_variant(cx, path),
-                            CtorOf::Struct => span_lint(cx, path.span),
-                    },
-                    Res::Def(DefKind::Variant, ..) => lint_path_to_variant(cx, path),
-                    Res::Def(DefKind::Struct, ..) => span_lint(cx, path.span),
-                    _ => ()
-                }
+                check_path(cx, path);
             }
         }
     }
@@ -313,6 +294,16 @@ fn span_lint(cx: &LateContext<'_>, span: Span) {
     );
 }
 
+fn check_path(cx: &LateContext<'_>, path: &Path<'_>) {
+    match path.res {
+        Res::Def(DefKind::Ctor(CtorOf::Variant, _) | DefKind::Variant, ..) => {
+            lint_path_to_variant(cx, path);
+        },
+        Res::Def(DefKind::Ctor(CtorOf::Struct, _) | DefKind::Struct, ..) => span_lint(cx, path.span),
+        _ => (),
+    }
+}
+
 fn lint_path_to_variant(cx: &LateContext<'_>, path: &Path<'_>) {
     if let [.., self_seg, _variant] = path.segments {
         let span = path
diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs
index 668123e4d6e..b37d4239477 100644
--- a/clippy_lints/src/utils/conf.rs
+++ b/clippy_lints/src/utils/conf.rs
@@ -53,11 +53,11 @@ impl DisallowedPath {
         path
     }
 
-    pub fn reason(&self) -> Option<&str> {
+    pub fn reason(&self) -> Option<String> {
         match self {
             Self::WithReason {
                 reason: Some(reason), ..
-            } => Some(reason),
+            } => Some(format!("{reason} (from clippy.toml)")),
             _ => None,
         }
     }
@@ -213,7 +213,7 @@ define_Conf! {
     ///
     /// Suppress lints whenever the suggested change would cause breakage for other crates.
     (avoid_breaking_exported_api: bool = true),
-    /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP.
+    /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION.
     ///
     /// The minimum rust version that the project supports
     (msrv: Option<String> = None),
@@ -335,6 +335,12 @@ define_Conf! {
     ///
     /// Enables verbose mode. Triggers if there is more than one uppercase char next to each other
     (upper_case_acronyms_aggressive: bool = false),
+    /// Lint: MANUAL_LET_ELSE.
+    ///
+    /// Whether the matches should be considered by the lint, and whether there should
+    /// be filtering for common types.
+    (matches_for_let_else: crate::manual_let_else::MatchLintBehaviour =
+        crate::manual_let_else::MatchLintBehaviour::WellKnownTypes),
     /// Lint: _CARGO_COMMON_METADATA.
     ///
     /// For internal testing only, ignores the current `publish` settings in the Cargo manifest.
@@ -373,23 +379,36 @@ define_Conf! {
     (max_include_file_size: u64 = 1_000_000),
     /// Lint: EXPECT_USED.
     ///
-    /// Whether `expect` should be allowed in test functions
+    /// Whether `expect` should be allowed within `#[cfg(test)]`
     (allow_expect_in_tests: bool = false),
     /// Lint: UNWRAP_USED.
     ///
-    /// Whether `unwrap` should be allowed in test functions
+    /// Whether `unwrap` should be allowed in test cfg
     (allow_unwrap_in_tests: bool = false),
     /// Lint: DBG_MACRO.
     ///
     /// Whether `dbg!` should be allowed in test functions
     (allow_dbg_in_tests: bool = false),
-    /// Lint: RESULT_LARGE_ERR
+    /// Lint: PRINT_STDOUT, PRINT_STDERR.
+    ///
+    /// Whether print macros (ex. `println!`) should be allowed in test functions
+    (allow_print_in_tests: bool = false),
+    /// Lint: RESULT_LARGE_ERR.
     ///
     /// The maximum size of the `Err`-variant in a `Result` returned from a function
     (large_error_threshold: u64 = 128),
+    /// Lint: MUTABLE_KEY.
+    ///
+    /// A list of paths to types that should be treated like `Arc`, i.e. ignored but
+    /// for the generic parameters for determining interior mutability
+    (ignore_interior_mutability: Vec<String> = Vec::from(["bytes::Bytes".into()])),
 }
 
 /// Search for the configuration file.
+///
+/// # Errors
+///
+/// Returns any unexpected filesystem error encountered when searching for the config file
 pub fn lookup_conf_file() -> io::Result<Option<PathBuf>> {
     /// Possible filename to search for.
     const CONFIG_FILE_NAMES: [&str; 2] = [".clippy.toml", "clippy.toml"];
diff --git a/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs b/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
index 096b601572b..4b33d492a0e 100644
--- a/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
+++ b/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
@@ -2,7 +2,7 @@ use clippy_utils::consts::{constant_simple, Constant};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
 use clippy_utils::ty::match_type;
-use clippy_utils::{def_path_res, is_expn_of, match_def_path, paths};
+use clippy_utils::{def_path_def_ids, is_expn_of, match_def_path, paths};
 use if_chain::if_chain;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::Applicability;
@@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
         }
 
         for &module in &[&paths::KW_MODULE, &paths::SYM_MODULE] {
-            if let Some(def_id) = def_path_res(cx, module, None).opt_def_id() {
+            for def_id in def_path_def_ids(cx, module) {
                 for item in cx.tcx.module_children(def_id).iter() {
                     if_chain! {
                         if let Res::Def(DefKind::Const, item_def_id) = item.res;
diff --git a/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/clippy_lints/src/utils/internal_lints/invalid_paths.rs
index 22a5aa5351a..680935f2329 100644
--- a/clippy_lints/src/utils/internal_lints/invalid_paths.rs
+++ b/clippy_lints/src/utils/internal_lints/invalid_paths.rs
@@ -3,7 +3,7 @@ use clippy_utils::def_path_res;
 use clippy_utils::diagnostics::span_lint;
 use if_chain::if_chain;
 use rustc_hir as hir;
-use rustc_hir::def::{DefKind, Res};
+use rustc_hir::def::DefKind;
 use rustc_hir::Item;
 use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass};
@@ -63,7 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidPaths {
 // This is not a complete resolver for paths. It works on all the paths currently used in the paths
 // module.  That's all it does and all it needs to do.
 pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
-    if def_path_res(cx, path, None) != Res::Err {
+    if !def_path_res(cx, path).is_empty() {
         return true;
     }
 
diff --git a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
index 0dac64376b0..1aebb8b3104 100644
--- a/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
+++ b/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
@@ -256,7 +256,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {
     }
 }
 
-pub(super) fn is_lint_ref_type<'tcx>(cx: &LateContext<'tcx>, ty: &hir::Ty<'_>) -> bool {
+pub(super) fn is_lint_ref_type(cx: &LateContext<'_>, ty: &hir::Ty<'_>) -> bool {
     if let TyKind::Rptr(
         _,
         MutTy {
diff --git a/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
index f2276395fed..393988dbad3 100644
--- a/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
+++ b/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{def_path_res, is_lint_allowed, match_any_def_paths, peel_hir_expr_refs};
+use clippy_utils::{def_path_def_ids, is_lint_allowed, match_any_def_paths, peel_hir_expr_refs};
 use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
 use rustc_data_structures::fx::FxHashSet;
@@ -11,9 +11,9 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::{Expr, ExprKind, Local, Mutability, Node};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir::interpret::{Allocation, ConstValue, GlobalAlloc};
-use rustc_middle::ty::{self, AssocKind, DefIdTree, Ty};
+use rustc_middle::ty::{self, DefIdTree, Ty};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::symbol::{Ident, Symbol};
+use rustc_span::symbol::Symbol;
 use rustc_span::Span;
 
 use std::str;
@@ -110,7 +110,7 @@ impl UnnecessaryDefPath {
             // Extract the path to the matched type
             if let Some(segments) = path_to_matched_type(cx, item_arg);
             let segments: Vec<&str> = segments.iter().map(|sym| &**sym).collect();
-            if let Some(def_id) = inherent_def_path_res(cx, &segments[..]);
+            if let Some(def_id) = def_path_def_ids(cx, &segments[..]).next();
             then {
                 // Check if the target item is a diagnostic item or LangItem.
                 #[rustfmt::skip]
@@ -209,7 +209,7 @@ impl UnnecessaryDefPath {
     fn check_array(&mut self, cx: &LateContext<'_>, elements: &[Expr<'_>], span: Span) {
         let Some(path) = path_from_array(elements) else { return };
 
-        if let Some(def_id) = inherent_def_path_res(cx, &path.iter().map(AsRef::as_ref).collect::<Vec<_>>()) {
+        for def_id in def_path_def_ids(cx, &path.iter().map(AsRef::as_ref).collect::<Vec<_>>()) {
             self.array_def_ids.insert((def_id, span));
         }
     }
@@ -246,7 +246,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
 
 fn read_mir_alloc_def_path<'tcx>(cx: &LateContext<'tcx>, alloc: &'tcx Allocation, ty: Ty<'_>) -> Option<Vec<String>> {
     let (alloc, ty) = if let ty::Ref(_, ty, Mutability::Not) = *ty.kind() {
-        let &alloc = alloc.provenance().values().next()?;
+        let &alloc = alloc.provenance().ptrs().values().next()?;
         if let GlobalAlloc::Memory(alloc) = cx.tcx.global_alloc(alloc) {
             (alloc.inner(), ty)
         } else {
@@ -262,6 +262,7 @@ fn read_mir_alloc_def_path<'tcx>(cx: &LateContext<'tcx>, alloc: &'tcx Allocation
     {
         alloc
             .provenance()
+            .ptrs()
             .values()
             .map(|&alloc| {
                 if let GlobalAlloc::Memory(alloc) = cx.tcx.global_alloc(alloc) {
@@ -293,38 +294,6 @@ fn path_from_array(exprs: &[Expr<'_>]) -> Option<Vec<String>> {
         .collect()
 }
 
-// def_path_res will match field names before anything else, but for this we want to match
-// inherent functions first.
-fn inherent_def_path_res(cx: &LateContext<'_>, segments: &[&str]) -> Option<DefId> {
-    def_path_res(cx, segments, None).opt_def_id().map(|def_id| {
-        if cx.tcx.def_kind(def_id) == DefKind::Field {
-            let method_name = *segments.last().unwrap();
-            cx.tcx
-                .def_key(def_id)
-                .parent
-                .and_then(|parent_idx| {
-                    cx.tcx
-                        .inherent_impls(DefId {
-                            index: parent_idx,
-                            krate: def_id.krate,
-                        })
-                        .iter()
-                        .find_map(|impl_id| {
-                            cx.tcx.associated_items(*impl_id).find_by_name_and_kind(
-                                cx.tcx,
-                                Ident::from_str(method_name),
-                                AssocKind::Fn,
-                                *impl_id,
-                            )
-                        })
-                })
-                .map_or(def_id, |item| item.def_id)
-        } else {
-            def_id
-        }
-    })
-}
-
 fn get_lang_item_name(cx: &LateContext<'_>, def_id: DefId) -> Option<&'static str> {
     if let Some((lang_item, _)) = cx.tcx.lang_items().iter().find(|(_, id)| *id == def_id) {
         Some(lang_item.variant_name())
diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs
index 36574198f91..6b321765bc0 100644
--- a/clippy_lints/src/write.rs
+++ b/clippy_lints/src/write.rs
@@ -1,6 +1,7 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use clippy_utils::macros::{root_macro_call_first_node, FormatArgsExpn, MacroCall};
 use clippy_utils::source::{expand_past_previous_comma, snippet_opt};
+use clippy_utils::{is_in_cfg_test, is_in_test_function};
 use rustc_ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, HirIdMap, Impl, Item, ItemKind};
@@ -232,6 +233,16 @@ declare_clippy_lint! {
 #[derive(Default)]
 pub struct Write {
     in_debug_impl: bool,
+    allow_print_in_tests: bool,
+}
+
+impl Write {
+    pub fn new(allow_print_in_tests: bool) -> Self {
+        Self {
+            allow_print_in_tests,
+            ..Default::default()
+        }
+    }
 }
 
 impl_lint_pass!(Write => [
@@ -271,13 +282,15 @@ impl<'tcx> LateLintPass<'tcx> for Write {
             .as_ref()
             .map_or(false, |crate_name| crate_name == "build_script_build");
 
+        let allowed_in_tests = self.allow_print_in_tests
+            && (is_in_test_function(cx.tcx, expr.hir_id) || is_in_cfg_test(cx.tcx, expr.hir_id));
         match diag_name {
-            sym::print_macro | sym::println_macro => {
+            sym::print_macro | sym::println_macro if !allowed_in_tests => {
                 if !is_build_script {
                     span_lint(cx, PRINT_STDOUT, macro_call.span, &format!("use of `{name}!`"));
                 }
             },
-            sym::eprint_macro | sym::eprintln_macro => {
+            sym::eprint_macro | sym::eprintln_macro if !allowed_in_tests => {
                 span_lint(cx, PRINT_STDERR, macro_call.span, &format!("use of `{name}!`"));
             },
             sym::write_macro | sym::writeln_macro => {},