about summary refs log tree commit diff
path: root/clippy_lints/src
diff options
context:
space:
mode:
authorxFrednet <xFrednet@gmail.com>2022-05-20 20:37:38 +0200
committerxFrednet <xFrednet@gmail.com>2022-05-20 20:47:31 +0200
commit4e6cf0036e5e7afdc4fe86cccc99482ff4cf71bf (patch)
treec0de46a0482ccc460d4789e23b4d2abb5bf17787 /clippy_lints/src
parent01421e0cbda66655e25d48c1c72c2dcbe77040c2 (diff)
parent6f26383f8ec8dfe89858876eac127161d148eb13 (diff)
downloadrust-4e6cf0036e5e7afdc4fe86cccc99482ff4cf71bf.tar.gz
rust-4e6cf0036e5e7afdc4fe86cccc99482ff4cf71bf.zip
Merge remote-tracking branch 'upstream/master' into rustup
Diffstat (limited to 'clippy_lints/src')
-rw-r--r--clippy_lints/src/approx_const.rs4
-rw-r--r--clippy_lints/src/assign_ops.rs2
-rw-r--r--clippy_lints/src/attrs.rs23
-rw-r--r--clippy_lints/src/bit_mask.rs40
-rw-r--r--clippy_lints/src/booleans.rs6
-rw-r--r--clippy_lints/src/borrow_as_ptr.rs2
-rw-r--r--clippy_lints/src/casts/cast_abs_to_unsigned.rs4
-rw-r--r--clippy_lints/src/casts/cast_lossless.rs8
-rw-r--r--clippy_lints/src/casts/cast_slice_different_sizes.rs6
-rw-r--r--clippy_lints/src/casts/mod.rs13
-rw-r--r--clippy_lints/src/casts/ptr_as_ptr.rs4
-rw-r--r--clippy_lints/src/checked_conversions.rs5
-rw-r--r--clippy_lints/src/cognitive_complexity.rs4
-rw-r--r--clippy_lints/src/collapsible_match.rs5
-rw-r--r--clippy_lints/src/dbg_macro.rs4
-rw-r--r--clippy_lints/src/default.rs2
-rw-r--r--clippy_lints/src/default_numeric_fallback.rs1
-rw-r--r--clippy_lints/src/default_union_representation.rs4
-rw-r--r--clippy_lints/src/deprecated_lints.rs1
-rw-r--r--clippy_lints/src/dereference.rs4
-rw-r--r--clippy_lints/src/derive.rs79
-rw-r--r--clippy_lints/src/doc.rs6
-rw-r--r--clippy_lints/src/double_comparison.rs2
-rw-r--r--clippy_lints/src/duplicate_mod.rs102
-rw-r--r--clippy_lints/src/entry.rs4
-rw-r--r--clippy_lints/src/enum_clike.rs3
-rw-r--r--clippy_lints/src/enum_variants.rs2
-rw-r--r--clippy_lints/src/eq_op.rs3
-rw-r--r--clippy_lints/src/excessive_bools.rs2
-rw-r--r--clippy_lints/src/fallible_impl_from.rs1
-rw-r--r--clippy_lints/src/floating_point_arithmetic.rs2
-rw-r--r--clippy_lints/src/from_over_into.rs2
-rw-r--r--clippy_lints/src/if_then_some_else_none.rs2
-rw-r--r--clippy_lints/src/implicit_hasher.rs2
-rw-r--r--clippy_lints/src/implicit_return.rs4
-rw-r--r--clippy_lints/src/index_refutable_slice.rs3
-rw-r--r--clippy_lints/src/int_plus_one.rs2
-rw-r--r--clippy_lints/src/lib.register_all.rs6
-rw-r--r--clippy_lints/src/lib.register_complexity.rs2
-rw-r--r--clippy_lints/src/lib.register_lints.rs9
-rw-r--r--clippy_lints/src/lib.register_nursery.rs2
-rw-r--r--clippy_lints/src/lib.register_pedantic.rs2
-rw-r--r--clippy_lints/src/lib.register_restriction.rs1
-rw-r--r--clippy_lints/src/lib.register_style.rs1
-rw-r--r--clippy_lints/src/lib.register_suspicious.rs3
-rw-r--r--clippy_lints/src/lib.rs26
-rw-r--r--clippy_lints/src/literal_representation.rs3
-rw-r--r--clippy_lints/src/loops/mod.rs1
-rw-r--r--clippy_lints/src/loops/needless_range_loop.rs2
-rw-r--r--clippy_lints/src/loops/utils.rs2
-rw-r--r--clippy_lints/src/loops/while_let_on_iterator.rs2
-rw-r--r--clippy_lints/src/macro_use.rs6
-rw-r--r--clippy_lints/src/main_recursion.rs2
-rw-r--r--clippy_lints/src/manual_bits.rs2
-rw-r--r--clippy_lints/src/manual_map.rs2
-rw-r--r--clippy_lints/src/manual_non_exhaustive.rs12
-rw-r--r--clippy_lints/src/manual_strip.rs2
-rw-r--r--clippy_lints/src/map_clone.rs2
-rw-r--r--clippy_lints/src/matches/match_same_arms.rs6
-rw-r--r--clippy_lints/src/matches/match_single_binding.rs175
-rw-r--r--clippy_lints/src/matches/match_wild_enum.rs3
-rw-r--r--clippy_lints/src/matches/mod.rs4
-rw-r--r--clippy_lints/src/matches/redundant_pattern_match.rs2
-rw-r--r--clippy_lints/src/mem_replace.rs2
-rw-r--r--clippy_lints/src/methods/cloned_instead_of_copied.rs6
-rw-r--r--clippy_lints/src/methods/err_expect.rs4
-rw-r--r--clippy_lints/src/methods/expect_used.rs7
-rw-r--r--clippy_lints/src/methods/filter_map_next.rs4
-rw-r--r--clippy_lints/src/methods/is_digit_ascii_radix.rs4
-rw-r--r--clippy_lints/src/methods/map_unwrap_or.rs4
-rw-r--r--clippy_lints/src/methods/mod.rs376
-rw-r--r--clippy_lints/src/methods/option_as_ref_deref.rs4
-rw-r--r--clippy_lints/src/methods/str_splitn.rs6
-rw-r--r--clippy_lints/src/methods/unnecessary_to_owned.rs42
-rw-r--r--clippy_lints/src/methods/unwrap_used.rs7
-rw-r--r--clippy_lints/src/misc.rs54
-rw-r--r--clippy_lints/src/missing_const_for_fn.rs4
-rw-r--r--clippy_lints/src/missing_doc.rs21
-rw-r--r--clippy_lints/src/mixed_read_write_in_expression.rs (renamed from clippy_lints/src/eval_order_dependence.rs)8
-rw-r--r--clippy_lints/src/mutable_debug_assertion.rs6
-rw-r--r--clippy_lints/src/needless_bitwise_bool.rs4
-rw-r--r--clippy_lints/src/needless_pass_by_value.rs2
-rw-r--r--clippy_lints/src/neg_multiply.rs1
-rw-r--r--clippy_lints/src/new_without_default.rs1
-rw-r--r--clippy_lints/src/non_expressive_names.rs2
-rw-r--r--clippy_lints/src/pass_by_ref_or_value.rs4
-rw-r--r--clippy_lints/src/pattern_type_mismatch.rs1
-rw-r--r--clippy_lints/src/ptr.rs2
-rw-r--r--clippy_lints/src/ranges.rs75
-rw-r--r--clippy_lints/src/rc_clone_in_vec_init.rs141
-rw-r--r--clippy_lints/src/redundant_clone.rs5
-rw-r--r--clippy_lints/src/redundant_field_names.rs2
-rw-r--r--clippy_lints/src/redundant_static_lifetimes.rs2
-rw-r--r--clippy_lints/src/reference.rs5
-rw-r--r--clippy_lints/src/regex.rs2
-rw-r--r--clippy_lints/src/renamed_lints.rs1
-rw-r--r--clippy_lints/src/same_name_method.rs10
-rw-r--r--clippy_lints/src/tabs_in_doc_comments.rs1
-rw-r--r--clippy_lints/src/trait_bounds.rs4
-rw-r--r--clippy_lints/src/transmute/mod.rs4
-rw-r--r--clippy_lints/src/types/redundant_allocation.rs7
-rw-r--r--clippy_lints/src/undocumented_unsafe_blocks.rs196
-rw-r--r--clippy_lints/src/uninit_vec.rs2
-rw-r--r--clippy_lints/src/unit_types/let_unit_value.rs17
-rw-r--r--clippy_lints/src/unnested_or_patterns.rs8
-rw-r--r--clippy_lints/src/unused_unit.rs2
-rw-r--r--clippy_lints/src/use_self.rs6
-rw-r--r--clippy_lints/src/useless_conversion.rs2
-rw-r--r--clippy_lints/src/utils/conf.rs137
-rw-r--r--clippy_lints/src/vec.rs5
-rw-r--r--clippy_lints/src/vec_init_then_push.rs190
-rw-r--r--clippy_lints/src/write.rs3
112 files changed, 1420 insertions, 626 deletions
diff --git a/clippy_lints/src/approx_const.rs b/clippy_lints/src/approx_const.rs
index e109ee0009e..da1b646f477 100644
--- a/clippy_lints/src/approx_const.rs
+++ b/clippy_lints/src/approx_const.rs
@@ -87,9 +87,7 @@ impl ApproxConstant {
         let s = s.as_str();
         if s.parse::<f64>().is_ok() {
             for &(constant, name, min_digits, msrv) in &KNOWN_CONSTS {
-                if is_approx_const(constant, s, min_digits)
-                    && msrv.as_ref().map_or(true, |msrv| meets_msrv(self.msrv.as_ref(), msrv))
-                {
+                if is_approx_const(constant, s, min_digits) && msrv.map_or(true, |msrv| meets_msrv(self.msrv, msrv)) {
                     span_lint_and_help(
                         cx,
                         APPROX_CONSTANT,
diff --git a/clippy_lints/src/assign_ops.rs b/clippy_lints/src/assign_ops.rs
index 12c1bddf79d..4c2d3366483 100644
--- a/clippy_lints/src/assign_ops.rs
+++ b/clippy_lints/src/assign_ops.rs
@@ -50,7 +50,7 @@ declare_clippy_lint! {
     /// ### Known problems
     /// Clippy cannot know for sure if `a op= a op b` should have
     /// been `a = a op a op b` or `a = a op b`/`a op= b`. Therefore, it suggests both.
-    /// If `a op= a op b` is really the correct behaviour it should be
+    /// If `a op= a op b` is really the correct behavior it should be
     /// written as `a = a op a op b` as it's less confusing.
     ///
     /// ### Example
diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs
index 8b0e11cb802..3de91f3d24a 100644
--- a/clippy_lints/src/attrs.rs
+++ b/clippy_lints/src/attrs.rs
@@ -6,7 +6,7 @@ use clippy_utils::msrvs;
 use clippy_utils::source::{first_line_of_span, is_present_in_source, snippet_opt, without_block_comments};
 use clippy_utils::{extract_msrv_attr, meets_msrv};
 use if_chain::if_chain;
-use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MacArgs, MacArgsEq, MetaItemKind, NestedMetaItem};
+use rustc_ast::{AttrKind, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
 use rustc_errors::Applicability;
 use rustc_hir::{
     Block, Expr, ExprKind, ImplItem, ImplItemKind, Item, ItemKind, StmtKind, TraitFn, TraitItem, TraitItemKind,
@@ -586,21 +586,10 @@ impl EarlyLintPass for EarlyAttributes {
 
 fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
     for attr in &item.attrs {
-        let attr_item = if let AttrKind::Normal(ref attr, _) = attr.kind {
-            attr
-        } else {
-            return;
-        };
-
-        if attr.style == AttrStyle::Outer {
-            if let MacArgs::Eq(_, MacArgsEq::Ast(expr)) = &attr_item.args
-                && !matches!(expr.kind, rustc_ast::ExprKind::Lit(..)) {
-                return;
-            }
-            if attr_item.args.inner_tokens().is_empty() || !is_present_in_source(cx, attr.span) {
-                return;
-            }
-
+        if matches!(attr.kind, AttrKind::Normal(..))
+            && attr.style == AttrStyle::Outer
+            && is_present_in_source(cx, attr.span)
+        {
             let begin_of_attr_to_item = Span::new(attr.span.lo(), item.span.lo(), item.span.ctxt(), item.span.parent());
             let end_of_attr_to_item = Span::new(attr.span.hi(), item.span.lo(), item.span.ctxt(), item.span.parent());
 
@@ -624,7 +613,7 @@ fn check_empty_line_after_outer_attr(cx: &EarlyContext<'_>, item: &rustc_ast::It
 
 fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute, msrv: Option<RustcVersion>) {
     if_chain! {
-        if meets_msrv(msrv.as_ref(), &msrvs::TOOL_ATTRIBUTES);
+        if meets_msrv(msrv, msrvs::TOOL_ATTRIBUTES);
         // check cfg_attr
         if attr.has_name(sym::cfg_attr);
         if let Some(items) = attr.meta_item_list();
diff --git a/clippy_lints/src/bit_mask.rs b/clippy_lints/src/bit_mask.rs
index ca4af66cad1..dc7e400fdc2 100644
--- a/clippy_lints/src/bit_mask.rs
+++ b/clippy_lints/src/bit_mask.rs
@@ -1,7 +1,6 @@
 use clippy_utils::consts::{constant, Constant};
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use clippy_utils::sugg::Sugg;
-use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
@@ -130,23 +129,24 @@ impl<'tcx> LateLintPass<'tcx> for BitMask {
                 }
             }
         }
-        if_chain! {
-            if let ExprKind::Binary(op, left, right) = &e.kind;
-            if BinOpKind::Eq == op.node;
-            if let ExprKind::Binary(op1, left1, right1) = &left.kind;
-            if BinOpKind::BitAnd == op1.node;
-            if let ExprKind::Lit(lit) = &right1.kind;
-            if let LitKind::Int(n, _) = lit.node;
-            if let ExprKind::Lit(lit1) = &right.kind;
-            if let LitKind::Int(0, _) = lit1.node;
-            if n.leading_zeros() == n.count_zeros();
-            if n > u128::from(self.verbose_bit_mask_threshold);
-            then {
-                span_lint_and_then(cx,
-                                   VERBOSE_BIT_MASK,
-                                   e.span,
-                                   "bit mask could be simplified with a call to `trailing_zeros`",
-                                   |diag| {
+
+        if let ExprKind::Binary(op, left, right) = &e.kind
+            && BinOpKind::Eq == op.node
+            && let ExprKind::Binary(op1, left1, right1) = &left.kind
+            && BinOpKind::BitAnd == op1.node
+            && let ExprKind::Lit(lit) = &right1.kind
+            && let LitKind::Int(n, _) = lit.node
+            && let ExprKind::Lit(lit1) = &right.kind
+            && let LitKind::Int(0, _) = lit1.node
+            && n.leading_zeros() == n.count_zeros()
+            && n > u128::from(self.verbose_bit_mask_threshold)
+        {
+            span_lint_and_then(
+                cx,
+                VERBOSE_BIT_MASK,
+                e.span,
+                "bit mask could be simplified with a call to `trailing_zeros`",
+                |diag| {
                     let sugg = Sugg::hir(cx, left1, "...").maybe_par();
                     diag.span_suggestion(
                         e.span,
@@ -154,8 +154,8 @@ impl<'tcx> LateLintPass<'tcx> for BitMask {
                         format!("{}.trailing_zeros() >= {}", sugg, n.count_ones()),
                         Applicability::MaybeIncorrect,
                     );
-                });
-            }
+                },
+            );
         }
     }
 }
diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs
index f7449c8dc72..0adb6327164 100644
--- a/clippy_lints/src/booleans.rs
+++ b/clippy_lints/src/booleans.rs
@@ -137,7 +137,7 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
         }
         for (n, expr) in self.terminals.iter().enumerate() {
             if eq_expr_value(self.cx, e, expr) {
-                #[allow(clippy::cast_possible_truncation)]
+                #[expect(clippy::cast_possible_truncation)]
                 return Ok(Bool::Term(n as u8));
             }
 
@@ -149,7 +149,7 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
                 if eq_expr_value(self.cx, e_lhs, expr_lhs);
                 if eq_expr_value(self.cx, e_rhs, expr_rhs);
                 then {
-                    #[allow(clippy::cast_possible_truncation)]
+                    #[expect(clippy::cast_possible_truncation)]
                     return Ok(Bool::Not(Box::new(Bool::Term(n as u8))));
                 }
             }
@@ -157,7 +157,7 @@ impl<'a, 'tcx, 'v> Hir2Qmm<'a, 'tcx, 'v> {
         let n = self.terminals.len();
         self.terminals.push(e);
         if n < 32 {
-            #[allow(clippy::cast_possible_truncation)]
+            #[expect(clippy::cast_possible_truncation)]
             Ok(Bool::Term(n as u8))
         } else {
             Err("too many literals".to_owned())
diff --git a/clippy_lints/src/borrow_as_ptr.rs b/clippy_lints/src/borrow_as_ptr.rs
index 9f8eb488c29..0993adbae2e 100644
--- a/clippy_lints/src/borrow_as_ptr.rs
+++ b/clippy_lints/src/borrow_as_ptr.rs
@@ -57,7 +57,7 @@ impl BorrowAsPtr {
 
 impl<'tcx> LateLintPass<'tcx> for BorrowAsPtr {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if !meets_msrv(self.msrv.as_ref(), &msrvs::BORROW_AS_PTR) {
+        if !meets_msrv(self.msrv, msrvs::BORROW_AS_PTR) {
             return;
         }
 
diff --git a/clippy_lints/src/casts/cast_abs_to_unsigned.rs b/clippy_lints/src/casts/cast_abs_to_unsigned.rs
index e9b0f1f672d..6bac6bf83f8 100644
--- a/clippy_lints/src/casts/cast_abs_to_unsigned.rs
+++ b/clippy_lints/src/casts/cast_abs_to_unsigned.rs
@@ -16,10 +16,10 @@ pub(super) fn check(
     cast_expr: &Expr<'_>,
     cast_from: Ty<'_>,
     cast_to: Ty<'_>,
-    msrv: &Option<RustcVersion>,
+    msrv: Option<RustcVersion>,
 ) {
     if_chain! {
-        if meets_msrv(msrv.as_ref(), &msrvs::UNSIGNED_ABS);
+        if meets_msrv(msrv, msrvs::UNSIGNED_ABS);
         if cast_from.is_integral();
         if cast_to.is_integral();
         if cast_from.is_signed();
diff --git a/clippy_lints/src/casts/cast_lossless.rs b/clippy_lints/src/casts/cast_lossless.rs
index 4a95bed1148..938458e30ca 100644
--- a/clippy_lints/src/casts/cast_lossless.rs
+++ b/clippy_lints/src/casts/cast_lossless.rs
@@ -16,7 +16,7 @@ pub(super) fn check(
     cast_op: &Expr<'_>,
     cast_from: Ty<'_>,
     cast_to: Ty<'_>,
-    msrv: &Option<RustcVersion>,
+    msrv: Option<RustcVersion>,
 ) {
     if !should_lint(cx, expr, cast_from, cast_to, msrv) {
         return;
@@ -68,7 +68,7 @@ fn should_lint(
     expr: &Expr<'_>,
     cast_from: Ty<'_>,
     cast_to: Ty<'_>,
-    msrv: &Option<RustcVersion>,
+    msrv: Option<RustcVersion>,
 ) -> bool {
     // Do not suggest using From in consts/statics until it is valid to do so (see #2267).
     if in_constant(cx, expr.hir_id) {
@@ -93,9 +93,9 @@ fn should_lint(
             } else {
                 64
             };
-            from_nbits < to_nbits
+            !is_isize_or_usize(cast_from) && from_nbits < to_nbits
         },
-        (false, true) if matches!(cast_from.kind(), ty::Bool) && meets_msrv(msrv.as_ref(), &msrvs::FROM_BOOL) => true,
+        (false, true) if matches!(cast_from.kind(), ty::Bool) && meets_msrv(msrv, msrvs::FROM_BOOL) => true,
         (_, _) => {
             matches!(cast_from.kind(), ty::Float(FloatTy::F32)) && matches!(cast_to.kind(), ty::Float(FloatTy::F64))
         },
diff --git a/clippy_lints/src/casts/cast_slice_different_sizes.rs b/clippy_lints/src/casts/cast_slice_different_sizes.rs
index 2238668abca..027c660ce3b 100644
--- a/clippy_lints/src/casts/cast_slice_different_sizes.rs
+++ b/clippy_lints/src/casts/cast_slice_different_sizes.rs
@@ -8,9 +8,9 @@ use rustc_semver::RustcVersion;
 
 use super::CAST_SLICE_DIFFERENT_SIZES;
 
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: &Option<RustcVersion>) {
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: Option<RustcVersion>) {
     // suggestion is invalid if `ptr::slice_from_raw_parts` does not exist
-    if !meets_msrv(msrv.as_ref(), &msrvs::PTR_SLICE_RAW_PARTS) {
+    if !meets_msrv(msrv, msrvs::PTR_SLICE_RAW_PARTS) {
         return;
     }
 
@@ -121,7 +121,7 @@ fn expr_cast_chain_tys<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Optio
         let to_slice_ty = get_raw_slice_ty_mut(cast_to)?;
 
         // If the expression that makes up the source of this cast is itself a cast, recursively
-        // call `expr_cast_chain_tys` and update the end type with the final tartet type.
+        // call `expr_cast_chain_tys` and update the end type with the final target type.
         // Otherwise, this cast is not immediately nested, just construct the info for this cast
         if let Some(prev_info) = expr_cast_chain_tys(cx, cast_expr) {
             Some(CastChainInfo {
diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs
index b58252dcb94..daf3b7b4ce4 100644
--- a/clippy_lints/src/casts/mod.rs
+++ b/clippy_lints/src/casts/mod.rs
@@ -306,7 +306,7 @@ declare_clippy_lint! {
     /// Checks for casts of `&T` to `&mut T` anywhere in the code.
     ///
     /// ### Why is this bad?
-    /// It’s basically guaranteed to be undefined behaviour.
+    /// It’s basically guaranteed to be undefined behavior.
     /// `UnsafeCell` is the only way to obtain aliasable data that is considered
     /// mutable.
     ///
@@ -413,6 +413,7 @@ declare_clippy_lint! {
 }
 
 declare_clippy_lint! {
+    /// ### What it does
     /// Checks for `as` casts between raw pointers to slices with differently sized elements.
     ///
     /// ### Why is this bad?
@@ -531,7 +532,7 @@ impl_lint_pass!(Casts => [
 impl<'tcx> LateLintPass<'tcx> for Casts {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         if !in_external_macro(cx.sess(), expr.span) {
-            ptr_as_ptr::check(cx, expr, &self.msrv);
+            ptr_as_ptr::check(cx, expr, self.msrv);
         }
 
         if expr.span.from_expansion() {
@@ -561,9 +562,9 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
                     cast_possible_wrap::check(cx, expr, cast_from, cast_to);
                     cast_precision_loss::check(cx, expr, cast_from, cast_to);
                     cast_sign_loss::check(cx, expr, cast_expr, cast_from, cast_to);
-                    cast_abs_to_unsigned::check(cx, expr, cast_expr, cast_from, cast_to, &self.msrv);
+                    cast_abs_to_unsigned::check(cx, expr, cast_expr, cast_from, cast_to, self.msrv);
                 }
-                cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to, &self.msrv);
+                cast_lossless::check(cx, expr, cast_expr, cast_from, cast_to, self.msrv);
                 cast_enum_constructor::check(cx, expr, cast_expr, cast_from);
             }
         }
@@ -571,8 +572,8 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
         cast_ref_to_mut::check(cx, expr);
         cast_ptr_alignment::check(cx, expr);
         char_lit_as_u8::check(cx, expr);
-        ptr_as_ptr::check(cx, expr, &self.msrv);
-        cast_slice_different_sizes::check(cx, expr, &self.msrv);
+        ptr_as_ptr::check(cx, expr, self.msrv);
+        cast_slice_different_sizes::check(cx, expr, self.msrv);
     }
 
     extract_msrv_attr!(LateContext);
diff --git a/clippy_lints/src/casts/ptr_as_ptr.rs b/clippy_lints/src/casts/ptr_as_ptr.rs
index fb04f93fbcf..46d45d09661 100644
--- a/clippy_lints/src/casts/ptr_as_ptr.rs
+++ b/clippy_lints/src/casts/ptr_as_ptr.rs
@@ -12,8 +12,8 @@ use rustc_semver::RustcVersion;
 
 use super::PTR_AS_PTR;
 
-pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Option<RustcVersion>) {
-    if !meets_msrv(msrv.as_ref(), &msrvs::POINTER_CAST) {
+pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: Option<RustcVersion>) {
+    if !meets_msrv(msrv, msrvs::POINTER_CAST) {
         return;
     }
 
diff --git a/clippy_lints/src/checked_conversions.rs b/clippy_lints/src/checked_conversions.rs
index 31cc3698592..7eeaaa01921 100644
--- a/clippy_lints/src/checked_conversions.rs
+++ b/clippy_lints/src/checked_conversions.rs
@@ -30,7 +30,6 @@ declare_clippy_lint! {
     /// Could be written:
     ///
     /// ```rust
-    /// # use std::convert::TryFrom;
     /// # let foo = 1;
     /// # let _ =
     /// i32::try_from(foo).is_ok()
@@ -57,7 +56,7 @@ impl_lint_pass!(CheckedConversions => [CHECKED_CONVERSIONS]);
 
 impl<'tcx> LateLintPass<'tcx> for CheckedConversions {
     fn check_expr(&mut self, cx: &LateContext<'_>, item: &Expr<'_>) {
-        if !meets_msrv(self.msrv.as_ref(), &msrvs::TRY_FROM) {
+        if !meets_msrv(self.msrv, msrvs::TRY_FROM) {
             return;
         }
 
@@ -123,7 +122,7 @@ struct Conversion<'a> {
 }
 
 /// The kind of conversion that is checked
-#[derive(Copy, Clone, Debug, PartialEq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
 enum ConversionType {
     SignedToUnsigned,
     SignedToSigned,
diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs
index 2bf7f868905..317c4bfb322 100644
--- a/clippy_lints/src/cognitive_complexity.rs
+++ b/clippy_lints/src/cognitive_complexity.rs
@@ -48,7 +48,7 @@ impl CognitiveComplexity {
 impl_lint_pass!(CognitiveComplexity => [COGNITIVE_COMPLEXITY]);
 
 impl CognitiveComplexity {
-    #[allow(clippy::cast_possible_truncation)]
+    #[expect(clippy::cast_possible_truncation)]
     fn check<'tcx>(
         &mut self,
         cx: &LateContext<'tcx>,
@@ -70,7 +70,7 @@ impl CognitiveComplexity {
         let ret_adjust = if is_type_diagnostic_item(cx, ret_ty, sym::Result) {
             returns
         } else {
-            #[allow(clippy::integer_division)]
+            #[expect(clippy::integer_division)]
             (returns / 2)
         };
 
diff --git a/clippy_lints/src/collapsible_match.rs b/clippy_lints/src/collapsible_match.rs
index 826eb0ae6b1..ec55009f347 100644
--- a/clippy_lints/src/collapsible_match.rs
+++ b/clippy_lints/src/collapsible_match.rs
@@ -109,7 +109,10 @@ fn check_arm<'tcx>(
             (Some(a), Some(b)) => SpanlessEq::new(cx).eq_expr(a, b),
         };
         // the binding must not be used in the if guard
-        if outer_guard.map_or(true, |(Guard::If(e) | Guard::IfLet(Let { init: e, .. }))| !is_local_used(cx, *e, binding_id));
+        if outer_guard.map_or(
+            true,
+            |(Guard::If(e) | Guard::IfLet(Let { init: e, .. }))| !is_local_used(cx, *e, binding_id)
+        );
         // ...or anywhere in the inner expression
         if match inner {
             IfLetOrMatch::IfLet(_, _, body, els) => {
diff --git a/clippy_lints/src/dbg_macro.rs b/clippy_lints/src/dbg_macro.rs
index a0e5d302633..f99d793c201 100644
--- a/clippy_lints/src/dbg_macro.rs
+++ b/clippy_lints/src/dbg_macro.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::is_in_test_function;
 use clippy_utils::macros::root_macro_call_first_node;
 use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::{is_in_cfg_test, is_in_test_function};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -37,7 +37,7 @@ impl LateLintPass<'_> for DbgMacro {
         let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return };
         if cx.tcx.is_diagnostic_item(sym::dbg_macro, macro_call.def_id) {
             // we make an exception for test code
-            if is_in_test_function(cx.tcx, expr.hir_id) {
+            if is_in_test_function(cx.tcx, expr.hir_id) || is_in_cfg_test(cx.tcx, expr.hir_id) {
                 return;
             }
             let mut applicability = Applicability::MachineApplicable;
diff --git a/clippy_lints/src/default.rs b/clippy_lints/src/default.rs
index f7e4bc24321..243dfd3a461 100644
--- a/clippy_lints/src/default.rs
+++ b/clippy_lints/src/default.rs
@@ -110,7 +110,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
         }
     }
 
-    #[allow(clippy::too_many_lines)]
+    #[expect(clippy::too_many_lines)]
     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &Block<'tcx>) {
         // start from the `let mut _ = _::default();` and look at all the following
         // statements, see if they re-assign the fields of the binding
diff --git a/clippy_lints/src/default_numeric_fallback.rs b/clippy_lints/src/default_numeric_fallback.rs
index f3996e5b44d..3d9f9ed41ce 100644
--- a/clippy_lints/src/default_numeric_fallback.rs
+++ b/clippy_lints/src/default_numeric_fallback.rs
@@ -116,7 +116,6 @@ impl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
-    #[allow(clippy::too_many_lines)]
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
         match &expr.kind {
             ExprKind::Call(func, args) => {
diff --git a/clippy_lints/src/default_union_representation.rs b/clippy_lints/src/default_union_representation.rs
index 9b5da0bd8a6..d559ad423df 100644
--- a/clippy_lints/src/default_union_representation.rs
+++ b/clippy_lints/src/default_union_representation.rs
@@ -25,7 +25,7 @@ declare_clippy_lint! {
     ///
     /// fn main() {
     ///     let _x: u32 = unsafe {
-    ///         Foo { a: 0_i32 }.b // Undefined behaviour: `b` is allowed to be padding
+    ///         Foo { a: 0_i32 }.b // Undefined behavior: `b` is allowed to be padding
     ///     };
     /// }
     /// ```
@@ -39,7 +39,7 @@ declare_clippy_lint! {
     ///
     /// fn main() {
     ///     let _x: u32 = unsafe {
-    ///         Foo { a: 0_i32 }.b // Now defined behaviour, this is just an i32 -> u32 transmute
+    ///         Foo { a: 0_i32 }.b // Now defined behavior, this is just an i32 -> u32 transmute
     ///     };
     /// }
     /// ```
diff --git a/clippy_lints/src/deprecated_lints.rs b/clippy_lints/src/deprecated_lints.rs
index bba27576c89..5d5ea0f49c8 100644
--- a/clippy_lints/src/deprecated_lints.rs
+++ b/clippy_lints/src/deprecated_lints.rs
@@ -194,7 +194,6 @@ declare_deprecated_lint! {
     /// ### Deprecation reason
     /// The `avoid_breaking_exported_api` config option was added, which
     /// enables the `enum_variant_names` lint for public items.
-    /// ```
     #[clippy::version = "1.54.0"]
     pub PUB_ENUM_VARIANT_NAMES,
     "set the `avoid-breaking-exported-api` config option to `false` to enable the `enum_variant_names` lint for public items"
diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs
index fe391198342..ea4c0207bb0 100644
--- a/clippy_lints/src/dereference.rs
+++ b/clippy_lints/src/dereference.rs
@@ -168,7 +168,7 @@ struct RefPat {
 }
 
 impl<'tcx> LateLintPass<'tcx> for Dereferencing {
-    #[allow(clippy::too_many_lines)]
+    #[expect(clippy::too_many_lines)]
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         // Skip path expressions from deref calls. e.g. `Deref::deref(e)`
         if Some(expr.hir_id) == self.skip_expr.take() {
@@ -580,7 +580,7 @@ fn find_adjustments<'tcx>(
     }
 }
 
-#[allow(clippy::needless_pass_by_value)]
+#[expect(clippy::needless_pass_by_value)]
 fn report(cx: &LateContext<'_>, expr: &Expr<'_>, state: State, data: StateData) {
     match state {
         State::DerefMethod {
diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs
index 545bc7d2103..fe99f4a8d55 100644
--- a/clippy_lints/src/derive.rs
+++ b/clippy_lints/src/derive.rs
@@ -1,8 +1,9 @@
-use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_then};
+use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::paths;
 use clippy_utils::ty::{implements_trait, is_copy};
 use clippy_utils::{is_lint_allowed, match_def_path};
 use if_chain::if_chain;
+use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, Visitor};
 use rustc_hir::{
     BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, HirId, Impl, Item, ItemKind, TraitRef, UnsafeSource, Unsafety,
@@ -101,8 +102,8 @@ declare_clippy_lint! {
     /// types.
     ///
     /// ### Why is this bad?
-    /// To avoid surprising behaviour, these traits should
-    /// agree and the behaviour of `Copy` cannot be overridden. In almost all
+    /// To avoid surprising behavior, these traits should
+    /// agree and the behavior of `Copy` cannot be overridden. In almost all
     /// situations a `Copy` type should have a `Clone` implementation that does
     /// nothing more than copy the object, which is what `#[derive(Copy, Clone)]`
     /// gets you.
@@ -156,11 +157,44 @@ declare_clippy_lint! {
     "deriving `serde::Deserialize` on a type that has methods using `unsafe`"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for types that derive `PartialEq` and could implement `Eq`.
+    ///
+    /// ### Why is this bad?
+    /// If a type `T` derives `PartialEq` and all of its members implement `Eq`,
+    /// then `T` can always implement `Eq`. Implementing `Eq` allows `T` to be used
+    /// in APIs that require `Eq` types. It also allows structs containing `T` to derive
+    /// `Eq` themselves.
+    ///
+    /// ### Example
+    /// ```rust
+    /// #[derive(PartialEq)]
+    /// struct Foo {
+    ///     i_am_eq: i32,
+    ///     i_am_eq_too: Vec<String>,
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// #[derive(PartialEq, Eq)]
+    /// struct Foo {
+    ///     i_am_eq: i32,
+    ///     i_am_eq_too: Vec<String>,
+    /// }
+    /// ```
+    #[clippy::version = "1.62.0"]
+    pub DERIVE_PARTIAL_EQ_WITHOUT_EQ,
+    style,
+    "deriving `PartialEq` on a type that can implement `Eq`, without implementing `Eq`"
+}
+
 declare_lint_pass!(Derive => [
     EXPL_IMPL_CLONE_ON_COPY,
     DERIVE_HASH_XOR_EQ,
     DERIVE_ORD_XOR_PARTIAL_ORD,
-    UNSAFE_DERIVE_DESERIALIZE
+    UNSAFE_DERIVE_DESERIALIZE,
+    DERIVE_PARTIAL_EQ_WITHOUT_EQ
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Derive {
@@ -171,14 +205,14 @@ impl<'tcx> LateLintPass<'tcx> for Derive {
         }) = item.kind
         {
             let ty = cx.tcx.type_of(item.def_id);
-            let is_automatically_derived =
-                cx.tcx.has_attr(item.def_id.to_def_id(), sym::automatically_derived);
+            let is_automatically_derived = cx.tcx.has_attr(item.def_id.to_def_id(), sym::automatically_derived);
 
             check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived);
             check_ord_partial_ord(cx, item.span, trait_ref, ty, is_automatically_derived);
 
             if is_automatically_derived {
                 check_unsafe_derive_deserialize(cx, item, trait_ref, ty);
+                check_partial_eq_without_eq(cx, item.span, trait_ref, ty);
             } else {
                 check_copy_clone(cx, item, trait_ref, ty);
             }
@@ -419,3 +453,36 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {
         self.cx.tcx.hir()
     }
 }
+
+/// Implementation of the `DERIVE_PARTIAL_EQ_WITHOUT_EQ` lint.
+fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_ref: &TraitRef<'_>, ty: Ty<'tcx>) {
+    if_chain! {
+        if let ty::Adt(adt, substs) = ty.kind();
+        if let Some(eq_trait_def_id) = cx.tcx.get_diagnostic_item(sym::Eq);
+        if let Some(def_id) = trait_ref.trait_def_id();
+        if cx.tcx.is_diagnostic_item(sym::PartialEq, def_id);
+        if !implements_trait(cx, ty, eq_trait_def_id, substs);
+        then {
+            // If all of our fields implement `Eq`, we can implement `Eq` too
+            for variant in adt.variants() {
+                for field in &variant.fields {
+                    let ty = field.ty(cx.tcx, substs);
+
+                    if !implements_trait(cx, ty, eq_trait_def_id, substs) {
+                        return;
+                    }
+                }
+            }
+
+            span_lint_and_sugg(
+                cx,
+                DERIVE_PARTIAL_EQ_WITHOUT_EQ,
+                span.ctxt().outer_expn_data().call_site,
+                "you are deriving `PartialEq` and can implement `Eq`",
+                "consider deriving `Eq` as well",
+                "PartialEq, Eq".to_string(),
+                Applicability::MachineApplicable,
+            )
+        }
+    }
+}
diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs
index b3fd8af4730..aaec88f50c7 100644
--- a/clippy_lints/src/doc.rs
+++ b/clippy_lints/src/doc.rs
@@ -198,7 +198,7 @@ declare_clippy_lint! {
     "presence of `fn main() {` in code examples"
 }
 
-#[allow(clippy::module_name_repetitions)]
+#[expect(clippy::module_name_repetitions)]
 #[derive(Clone)]
 pub struct DocMarkdown {
     valid_idents: FxHashSet<String>,
@@ -373,7 +373,7 @@ fn lint_for_missing_headers<'tcx>(
 /// `rustc_ast::parse::lexer::comments::strip_doc_comment_decoration` because we
 /// need to keep track of
 /// the spans but this function is inspired from the later.
-#[allow(clippy::cast_possible_truncation)]
+#[expect(clippy::cast_possible_truncation)]
 #[must_use]
 pub fn strip_doc_comment_decoration(doc: &str, comment_kind: CommentKind, span: Span) -> (String, Vec<(usize, Span)>) {
     // one-line comments lose their prefix
@@ -428,7 +428,7 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
     /// 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
     /// point to a fake address.
-    #[allow(clippy::unnecessary_wraps)] // we're following a type signature
+    #[expect(clippy::unnecessary_wraps)] // we're following a type signature
     fn fake_broken_link_callback<'a>(_: BrokenLink<'_>) -> Option<(CowStr<'a>, CowStr<'a>)> {
         Some(("fake".into(), "fake".into()))
     }
diff --git a/clippy_lints/src/double_comparison.rs b/clippy_lints/src/double_comparison.rs
index 176092e5b28..be95375789d 100644
--- a/clippy_lints/src/double_comparison.rs
+++ b/clippy_lints/src/double_comparison.rs
@@ -40,7 +40,7 @@ declare_clippy_lint! {
 declare_lint_pass!(DoubleComparisons => [DOUBLE_COMPARISONS]);
 
 impl<'tcx> DoubleComparisons {
-    #[allow(clippy::similar_names)]
+    #[expect(clippy::similar_names)]
     fn check_binop(cx: &LateContext<'tcx>, op: BinOpKind, lhs: &'tcx Expr<'_>, rhs: &'tcx Expr<'_>, span: Span) {
         let (lkind, llhs, lrhs, rkind, rlhs, rrhs) = match (&lhs.kind, &rhs.kind) {
             (ExprKind::Binary(lb, llhs, lrhs), ExprKind::Binary(rb, rlhs, rrhs)) => {
diff --git a/clippy_lints/src/duplicate_mod.rs b/clippy_lints/src/duplicate_mod.rs
new file mode 100644
index 00000000000..c6c7b959d4f
--- /dev/null
+++ b/clippy_lints/src/duplicate_mod.rs
@@ -0,0 +1,102 @@
+use clippy_utils::diagnostics::span_lint_and_help;
+use rustc_ast::ast::{Crate, Inline, Item, ItemKind, ModKind};
+use rustc_errors::MultiSpan;
+use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::{FileName, Span};
+use std::collections::BTreeMap;
+use std::path::PathBuf;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for files that are included as modules multiple times.
+    ///
+    /// ### Why is this bad?
+    /// Loading a file as a module more than once causes it to be compiled
+    /// multiple times, taking longer and putting duplicate content into the
+    /// module tree.
+    ///
+    /// ### Example
+    /// ```rust,ignore
+    /// // lib.rs
+    /// mod a;
+    /// mod b;
+    /// ```
+    /// ```rust,ignore
+    /// // a.rs
+    /// #[path = "./b.rs"]
+    /// mod b;
+    /// ```
+    ///
+    /// Use instead:
+    ///
+    /// ```rust,ignore
+    /// // lib.rs
+    /// mod a;
+    /// mod b;
+    /// ```
+    /// ```rust,ignore
+    /// // a.rs
+    /// use crate::b;
+    /// ```
+    #[clippy::version = "1.62.0"]
+    pub DUPLICATE_MOD,
+    suspicious,
+    "file loaded as module multiple times"
+}
+
+#[derive(PartialOrd, Ord, PartialEq, Eq)]
+struct Modules {
+    local_path: PathBuf,
+    spans: Vec<Span>,
+}
+
+#[derive(Default)]
+pub struct DuplicateMod {
+    /// map from the canonicalized path to `Modules`, `BTreeMap` to make the
+    /// order deterministic for tests
+    modules: BTreeMap<PathBuf, Modules>,
+}
+
+impl_lint_pass!(DuplicateMod => [DUPLICATE_MOD]);
+
+impl EarlyLintPass for DuplicateMod {
+    fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
+        if let ItemKind::Mod(_, ModKind::Loaded(_, Inline::No, mod_spans)) = &item.kind
+            && let FileName::Real(real) = cx.sess().source_map().span_to_filename(mod_spans.inner_span)
+            && let Some(local_path) = real.into_local_path()
+            && let Ok(absolute_path) = local_path.canonicalize()
+        {
+            let modules = self.modules.entry(absolute_path).or_insert(Modules {
+                local_path,
+                spans: Vec::new(),
+            });
+            modules.spans.push(item.span_with_attributes());
+        }
+    }
+
+    fn check_crate_post(&mut self, cx: &EarlyContext<'_>, _: &Crate) {
+        for Modules { local_path, spans } in self.modules.values() {
+            if spans.len() < 2 {
+                continue;
+            }
+
+            let mut multi_span = MultiSpan::from_spans(spans.clone());
+            let (&first, duplicates) = spans.split_first().unwrap();
+
+            multi_span.push_span_label(first, "first loaded here");
+            for &duplicate in duplicates {
+                multi_span.push_span_label(duplicate, "loaded again here");
+            }
+
+            span_lint_and_help(
+                cx,
+                DUPLICATE_MOD,
+                multi_span,
+                &format!("file is loaded as a module multiple times: `{}`", local_path.display()),
+                None,
+                "replace all but one `mod` item with `use` items",
+            );
+        }
+    }
+}
diff --git a/clippy_lints/src/entry.rs b/clippy_lints/src/entry.rs
index d3d3ed2c235..c5a987842c3 100644
--- a/clippy_lints/src/entry.rs
+++ b/clippy_lints/src/entry.rs
@@ -63,7 +63,7 @@ declare_clippy_lint! {
 declare_lint_pass!(HashMapPass => [MAP_ENTRY]);
 
 impl<'tcx> LateLintPass<'tcx> for HashMapPass {
-    #[allow(clippy::too_many_lines)]
+    #[expect(clippy::too_many_lines)]
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         let (cond_expr, then_expr, else_expr) = match higher::If::hir(expr) {
             Some(higher::If { cond, then, r#else }) => (cond, then, r#else),
@@ -319,7 +319,7 @@ struct Insertion<'tcx> {
 ///   `or_insert_with`.
 /// * Determine if there's any sub-expression that can't be placed in a closure.
 /// * Determine if there's only a single insert statement. `or_insert` can be used in this case.
-#[allow(clippy::struct_excessive_bools)]
+#[expect(clippy::struct_excessive_bools)]
 struct InsertSearcher<'cx, 'tcx> {
     cx: &'cx LateContext<'tcx>,
     /// The map expression used in the contains call.
diff --git a/clippy_lints/src/enum_clike.rs b/clippy_lints/src/enum_clike.rs
index e2a5430da08..10be245b362 100644
--- a/clippy_lints/src/enum_clike.rs
+++ b/clippy_lints/src/enum_clike.rs
@@ -8,7 +8,6 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::{self, IntTy, UintTy};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use std::convert::TryFrom;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -37,7 +36,7 @@ declare_clippy_lint! {
 declare_lint_pass!(UnportableVariant => [ENUM_CLIKE_UNPORTABLE_VARIANT]);
 
 impl<'tcx> LateLintPass<'tcx> for UnportableVariant {
-    #[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_sign_loss)]
+    #[expect(clippy::cast_possible_wrap)]
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         if cx.tcx.data_layout.pointer_size.bits() != 64 {
             return;
diff --git a/clippy_lints/src/enum_variants.rs b/clippy_lints/src/enum_variants.rs
index 346d03ca556..e029b8e8537 100644
--- a/clippy_lints/src/enum_variants.rs
+++ b/clippy_lints/src/enum_variants.rs
@@ -240,7 +240,7 @@ impl LateLintPass<'_> for EnumVariantNames {
         assert!(last.is_some());
     }
 
-    #[allow(clippy::similar_names)]
+    #[expect(clippy::similar_names)]
     fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
         let item_name = item.ident.name.as_str();
         let item_camel = to_camel_case(item_name);
diff --git a/clippy_lints/src/eq_op.rs b/clippy_lints/src/eq_op.rs
index 51c811b304c..afb5d32f953 100644
--- a/clippy_lints/src/eq_op.rs
+++ b/clippy_lints/src/eq_op.rs
@@ -72,7 +72,7 @@ declare_clippy_lint! {
 declare_lint_pass!(EqOp => [EQ_OP, OP_REF]);
 
 impl<'tcx> LateLintPass<'tcx> for EqOp {
-    #[allow(clippy::similar_names, clippy::too_many_lines)]
+    #[expect(clippy::similar_names, clippy::too_many_lines)]
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
         if_chain! {
             if let Some((macro_call, macro_name)) = first_node_macro_backtrace(cx, e).find_map(|macro_call| {
@@ -138,7 +138,6 @@ impl<'tcx> LateLintPass<'tcx> for EqOp {
                 },
             };
             if let Some(trait_id) = trait_id {
-                #[allow(clippy::match_same_arms)]
                 match (&left.kind, &right.kind) {
                     // do not suggest to dereference literals
                     (&ExprKind::Lit(..), _) | (_, &ExprKind::Lit(..)) => {},
diff --git a/clippy_lints/src/excessive_bools.rs b/clippy_lints/src/excessive_bools.rs
index 245a4fc12fd..7a81fb37e84 100644
--- a/clippy_lints/src/excessive_bools.rs
+++ b/clippy_lints/src/excessive_bools.rs
@@ -4,8 +4,6 @@ use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::{sym, Span};
 
-use std::convert::TryInto;
-
 declare_clippy_lint! {
     /// ### What it does
     /// Checks for excessive
diff --git a/clippy_lints/src/fallible_impl_from.rs b/clippy_lints/src/fallible_impl_from.rs
index 088d9996516..9f868df3ad0 100644
--- a/clippy_lints/src/fallible_impl_from.rs
+++ b/clippy_lints/src/fallible_impl_from.rs
@@ -32,7 +32,6 @@ declare_clippy_lint! {
     /// // Good
     /// struct Foo(i32);
     ///
-    /// use std::convert::TryFrom;
     /// impl TryFrom<String> for Foo {
     ///     type Error = ();
     ///     fn try_from(s: String) -> Result<Self, Self::Error> {
diff --git a/clippy_lints/src/floating_point_arithmetic.rs b/clippy_lints/src/floating_point_arithmetic.rs
index 79ce53f7a5f..42503c26de1 100644
--- a/clippy_lints/src/floating_point_arithmetic.rs
+++ b/clippy_lints/src/floating_point_arithmetic.rs
@@ -215,7 +215,7 @@ fn check_ln1p(cx: &LateContext<'_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
 // converted to an integer without loss of precision. For now we only check
 // ranges [-16777215, 16777216) for type f32 as whole number floats outside
 // this range are lossy and ambiguous.
-#[allow(clippy::cast_possible_truncation)]
+#[expect(clippy::cast_possible_truncation)]
 fn get_integer_from_float_constant(value: &Constant) -> Option<i32> {
     match value {
         F32(num) if num.fract() == 0.0 => {
diff --git a/clippy_lints/src/from_over_into.rs b/clippy_lints/src/from_over_into.rs
index c2f52605151..5d25c1d0634 100644
--- a/clippy_lints/src/from_over_into.rs
+++ b/clippy_lints/src/from_over_into.rs
@@ -55,7 +55,7 @@ impl_lint_pass!(FromOverInto => [FROM_OVER_INTO]);
 
 impl<'tcx> LateLintPass<'tcx> for FromOverInto {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
-        if !meets_msrv(self.msrv.as_ref(), &msrvs::RE_REBALANCING_COHERENCE) {
+        if !meets_msrv(self.msrv, msrvs::RE_REBALANCING_COHERENCE) {
             return;
         }
 
diff --git a/clippy_lints/src/if_then_some_else_none.rs b/clippy_lints/src/if_then_some_else_none.rs
index 9525c163ece..b8d227855d9 100644
--- a/clippy_lints/src/if_then_some_else_none.rs
+++ b/clippy_lints/src/if_then_some_else_none.rs
@@ -57,7 +57,7 @@ impl_lint_pass!(IfThenSomeElseNone => [IF_THEN_SOME_ELSE_NONE]);
 
 impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'tcx Expr<'_>) {
-        if !meets_msrv(self.msrv.as_ref(), &msrvs::BOOL_THEN) {
+        if !meets_msrv(self.msrv, msrvs::BOOL_THEN) {
             return;
         }
 
diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs
index feb1b1014b1..4f9680f60fe 100644
--- a/clippy_lints/src/implicit_hasher.rs
+++ b/clippy_lints/src/implicit_hasher.rs
@@ -62,7 +62,7 @@ declare_clippy_lint! {
 declare_lint_pass!(ImplicitHasher => [IMPLICIT_HASHER]);
 
 impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
-    #[allow(clippy::cast_possible_truncation, clippy::too_many_lines)]
+    #[expect(clippy::cast_possible_truncation, clippy::too_many_lines)]
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         use rustc_span::BytePos;
 
diff --git a/clippy_lints/src/implicit_return.rs b/clippy_lints/src/implicit_return.rs
index d650d6e9a85..647947d5d30 100644
--- a/clippy_lints/src/implicit_return.rs
+++ b/clippy_lints/src/implicit_return.rs
@@ -164,7 +164,7 @@ fn lint_implicit_returns(
             })
             .visit_block(block);
             if add_return {
-                #[allow(clippy::option_if_let_else)]
+                #[expect(clippy::option_if_let_else)]
                 if let Some(span) = call_site_span {
                     lint_return(cx, span);
                     LintLocation::Parent
@@ -196,7 +196,7 @@ fn lint_implicit_returns(
 
         _ =>
         {
-            #[allow(clippy::option_if_let_else)]
+            #[expect(clippy::option_if_let_else)]
             if let Some(span) = call_site_span {
                 lint_return(cx, span);
                 LintLocation::Parent
diff --git a/clippy_lints/src/index_refutable_slice.rs b/clippy_lints/src/index_refutable_slice.rs
index 8a84513b779..9ce5b8e17a9 100644
--- a/clippy_lints/src/index_refutable_slice.rs
+++ b/clippy_lints/src/index_refutable_slice.rs
@@ -14,7 +14,6 @@ use rustc_middle::ty;
 use rustc_semver::RustcVersion;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::{symbol::Ident, Span};
-use std::convert::TryInto;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -75,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for IndexRefutableSlice {
             if !expr.span.from_expansion() || is_expn_of(expr.span, "if_chain").is_some();
             if let Some(IfLet {let_pat, if_then, ..}) = IfLet::hir(cx, expr);
             if !is_lint_allowed(cx, INDEX_REFUTABLE_SLICE, expr.hir_id);
-            if meets_msrv(self.msrv.as_ref(), &msrvs::SLICE_PATTERNS);
+            if meets_msrv(self.msrv, msrvs::SLICE_PATTERNS);
 
             let found_slices = find_slice_values(cx, let_pat);
             if !found_slices.is_empty();
diff --git a/clippy_lints/src/int_plus_one.rs b/clippy_lints/src/int_plus_one.rs
index 3716d36ad88..8db7b307ddb 100644
--- a/clippy_lints/src/int_plus_one.rs
+++ b/clippy_lints/src/int_plus_one.rs
@@ -52,7 +52,7 @@ enum Side {
 }
 
 impl IntPlusOne {
-    #[allow(clippy::cast_sign_loss)]
+    #[expect(clippy::cast_sign_loss)]
     fn check_lit(lit: &Lit, target_value: i128) -> bool {
         if let LitKind::Int(value, ..) = lit.kind {
             return value == (target_value as u128);
diff --git a/clippy_lints/src/lib.register_all.rs b/clippy_lints/src/lib.register_all.rs
index e68718f9fdf..48ceeb43ee7 100644
--- a/clippy_lints/src/lib.register_all.rs
+++ b/clippy_lints/src/lib.register_all.rs
@@ -46,6 +46,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(derivable_impls::DERIVABLE_IMPLS),
     LintId::of(derive::DERIVE_HASH_XOR_EQ),
     LintId::of(derive::DERIVE_ORD_XOR_PARTIAL_ORD),
+    LintId::of(derive::DERIVE_PARTIAL_EQ_WITHOUT_EQ),
     LintId::of(disallowed_methods::DISALLOWED_METHODS),
     LintId::of(disallowed_types::DISALLOWED_TYPES),
     LintId::of(doc::MISSING_SAFETY_DOC),
@@ -59,6 +60,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     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(duration_subsec::DURATION_SUBSEC),
     LintId::of(entry::MAP_ENTRY),
     LintId::of(enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT),
@@ -69,8 +71,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(erasing_op::ERASING_OP),
     LintId::of(escape::BOXED_LOCAL),
     LintId::of(eta_reduction::REDUNDANT_CLOSURE),
-    LintId::of(eval_order_dependence::DIVERGING_SUB_EXPRESSION),
-    LintId::of(eval_order_dependence::EVAL_ORDER_DEPENDENCE),
     LintId::of(explicit_write::EXPLICIT_WRITE),
     LintId::of(float_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS),
     LintId::of(float_literal::EXCESSIVE_PRECISION),
@@ -228,6 +228,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     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(mut_key::MUTABLE_KEY_TYPE),
     LintId::of(mut_mutex_lock::MUT_MUTEX_LOCK),
     LintId::of(mut_reference::UNNECESSARY_MUT_PASSED),
@@ -263,6 +264,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(ranges::MANUAL_RANGE_CONTAINS),
     LintId::of(ranges::RANGE_ZIP_WITH_LEN),
     LintId::of(ranges::REVERSED_EMPTY_RANGES),
+    LintId::of(rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT),
     LintId::of(redundant_clone::REDUNDANT_CLONE),
     LintId::of(redundant_closure_call::REDUNDANT_CLOSURE_CALL),
     LintId::of(redundant_field_names::REDUNDANT_FIELD_NAMES),
diff --git a/clippy_lints/src/lib.register_complexity.rs b/clippy_lints/src/lib.register_complexity.rs
index 6f3c433af31..b15c979d0c7 100644
--- a/clippy_lints/src/lib.register_complexity.rs
+++ b/clippy_lints/src/lib.register_complexity.rs
@@ -12,7 +12,6 @@ store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec!
     LintId::of(double_comparison::DOUBLE_COMPARISONS),
     LintId::of(double_parens::DOUBLE_PARENS),
     LintId::of(duration_subsec::DURATION_SUBSEC),
-    LintId::of(eval_order_dependence::DIVERGING_SUB_EXPRESSION),
     LintId::of(explicit_write::EXPLICIT_WRITE),
     LintId::of(format::USELESS_FORMAT),
     LintId::of(functions::TOO_MANY_ARGUMENTS),
@@ -59,6 +58,7 @@ store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec!
     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),
diff --git a/clippy_lints/src/lib.register_lints.rs b/clippy_lints/src/lib.register_lints.rs
index c888a5feda2..5552ea8aa80 100644
--- a/clippy_lints/src/lib.register_lints.rs
+++ b/clippy_lints/src/lib.register_lints.rs
@@ -113,6 +113,7 @@ store.register_lints(&[
     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_methods::DISALLOWED_METHODS,
@@ -132,6 +133,7 @@ store.register_lints(&[
     drop_forget_ref::FORGET_NON_DROP,
     drop_forget_ref::FORGET_REF,
     drop_forget_ref::UNDROPPED_MANUALLY_DROPS,
+    duplicate_mod::DUPLICATE_MOD,
     duration_subsec::DURATION_SUBSEC,
     else_if_without_else::ELSE_IF_WITHOUT_ELSE,
     empty_drop::EMPTY_DROP,
@@ -149,8 +151,6 @@ store.register_lints(&[
     escape::BOXED_LOCAL,
     eta_reduction::REDUNDANT_CLOSURE,
     eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS,
-    eval_order_dependence::DIVERGING_SUB_EXPRESSION,
-    eval_order_dependence::EVAL_ORDER_DEPENDENCE,
     excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS,
     excessive_bools::STRUCT_EXCESSIVE_BOOLS,
     exhaustive_items::EXHAUSTIVE_ENUMS,
@@ -381,6 +381,8 @@ store.register_lints(&[
     missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS,
     missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES,
     missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS,
+    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,
     modulo_arithmetic::MODULO_ARITHMETIC,
@@ -446,6 +448,7 @@ store.register_lints(&[
     ranges::RANGE_PLUS_ONE,
     ranges::RANGE_ZIP_WITH_LEN,
     ranges::REVERSED_EMPTY_RANGES,
+    rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT,
     redundant_clone::REDUNDANT_CLONE,
     redundant_closure_call::REDUNDANT_CLOSURE_CALL,
     redundant_else::REDUNDANT_ELSE,
@@ -470,12 +473,12 @@ store.register_lints(&[
     shadow::SHADOW_REUSE,
     shadow::SHADOW_SAME,
     shadow::SHADOW_UNRELATED,
+    significant_drop_in_scrutinee::SIGNIFICANT_DROP_IN_SCRUTINEE,
     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,
     stable_sort_primitive::STABLE_SORT_PRIMITIVE,
-    significant_drop_in_scrutinee::SIGNIFICANT_DROP_IN_SCRUTINEE,
     strings::STRING_ADD,
     strings::STRING_ADD_ASSIGN,
     strings::STRING_FROM_UTF8_AS_BYTES,
diff --git a/clippy_lints/src/lib.register_nursery.rs b/clippy_lints/src/lib.register_nursery.rs
index 34d1555049d..d43c7e03533 100644
--- a/clippy_lints/src/lib.register_nursery.rs
+++ b/clippy_lints/src/lib.register_nursery.rs
@@ -29,6 +29,8 @@ store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
     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(trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS),
+    LintId::of(trait_bounds::TYPE_REPETITION_IN_BOUNDS),
     LintId::of(transmute::TRANSMUTE_UNDEFINED_REPR),
     LintId::of(transmute::USELESS_TRANSMUTE),
     LintId::of(use_self::USE_SELF),
diff --git a/clippy_lints/src/lib.register_pedantic.rs b/clippy_lints/src/lib.register_pedantic.rs
index 63232fd4113..2ee2c6e3358 100644
--- a/clippy_lints/src/lib.register_pedantic.rs
+++ b/clippy_lints/src/lib.register_pedantic.rs
@@ -84,8 +84,6 @@ store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
     LintId::of(semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED),
     LintId::of(stable_sort_primitive::STABLE_SORT_PRIMITIVE),
     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),
diff --git a/clippy_lints/src/lib.register_restriction.rs b/clippy_lints/src/lib.register_restriction.rs
index 77ec6c83ba4..a6d3a06dc16 100644
--- a/clippy_lints/src/lib.register_restriction.rs
+++ b/clippy_lints/src/lib.register_restriction.rs
@@ -46,6 +46,7 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
     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(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(modulo_arithmetic::MODULO_ARITHMETIC),
diff --git a/clippy_lints/src/lib.register_style.rs b/clippy_lints/src/lib.register_style.rs
index d183c0449cd..62f26d821a0 100644
--- a/clippy_lints/src/lib.register_style.rs
+++ b/clippy_lints/src/lib.register_style.rs
@@ -16,6 +16,7 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![
     LintId::of(comparison_chain::COMPARISON_CHAIN),
     LintId::of(default::FIELD_REASSIGN_WITH_DEFAULT),
     LintId::of(dereference::NEEDLESS_BORROW),
+    LintId::of(derive::DERIVE_PARTIAL_EQ_WITHOUT_EQ),
     LintId::of(disallowed_methods::DISALLOWED_METHODS),
     LintId::of(disallowed_types::DISALLOWED_TYPES),
     LintId::of(doc::MISSING_SAFETY_DOC),
diff --git a/clippy_lints/src/lib.register_suspicious.rs b/clippy_lints/src/lib.register_suspicious.rs
index 7a881bfe399..338a6a28bc9 100644
--- a/clippy_lints/src/lib.register_suspicious.rs
+++ b/clippy_lints/src/lib.register_suspicious.rs
@@ -14,7 +14,7 @@ store.register_group(true, "clippy::suspicious", Some("clippy_suspicious"), vec!
     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(eval_order_dependence::EVAL_ORDER_DEPENDENCE),
+    LintId::of(duplicate_mod::DUPLICATE_MOD),
     LintId::of(float_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS),
     LintId::of(format_impl::PRINT_IN_FORMAT_IMPL),
     LintId::of(formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING),
@@ -26,6 +26,7 @@ store.register_group(true, "clippy::suspicious", Some("clippy_suspicious"), vec!
     LintId::of(methods::SUSPICIOUS_MAP),
     LintId::of(mut_key::MUTABLE_KEY_TYPE),
     LintId::of(octal_escapes::OCTAL_ESCAPES),
+    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),
 ])
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 09071a255c5..4ac834f7240 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -8,6 +8,7 @@
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
 #![feature(let_else)]
+#![feature(lint_reasons)]
 #![feature(once_cell)]
 #![feature(rustc_private)]
 #![feature(stmt_expr_attributes)]
@@ -210,6 +211,7 @@ mod doc;
 mod double_comparison;
 mod double_parens;
 mod drop_forget_ref;
+mod duplicate_mod;
 mod duration_subsec;
 mod else_if_without_else;
 mod empty_drop;
@@ -223,7 +225,6 @@ mod equatable_if_let;
 mod erasing_op;
 mod escape;
 mod eta_reduction;
-mod eval_order_dependence;
 mod excessive_bools;
 mod exhaustive_items;
 mod exit;
@@ -299,6 +300,7 @@ mod missing_const_for_fn;
 mod missing_doc;
 mod missing_enforced_import_rename;
 mod missing_inline;
+mod mixed_read_write_in_expression;
 mod module_style;
 mod modulo_arithmetic;
 mod mut_key;
@@ -345,6 +347,7 @@ mod ptr_offset_with_cast;
 mod pub_use;
 mod question_mark;
 mod ranges;
+mod rc_clone_in_vec_init;
 mod redundant_clone;
 mod redundant_closure_call;
 mod redundant_else;
@@ -417,7 +420,7 @@ 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::TryConf;
+use crate::utils::conf::{format_error, TryConf};
 
 /// Register all pre expansion lints
 ///
@@ -462,7 +465,7 @@ pub fn read_conf(sess: &Session) -> Conf {
         sess.struct_err(&format!(
             "error reading Clippy's configuration file `{}`: {}",
             file_name.display(),
-            error
+            format_error(error)
         ))
         .emit();
     }
@@ -473,7 +476,7 @@ pub fn read_conf(sess: &Session) -> Conf {
 /// Register all lints and lint groups with the rustc plugin registry
 ///
 /// Used in `./src/driver.rs`.
-#[allow(clippy::too_many_lines)]
+#[expect(clippy::too_many_lines)]
 pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &Conf) {
     register_removed_non_tool_lints(store);
 
@@ -583,8 +586,17 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     });
 
     let avoid_breaking_exported_api = conf.avoid_breaking_exported_api;
+    let allow_expect_in_tests = conf.allow_expect_in_tests;
+    let allow_unwrap_in_tests = conf.allow_unwrap_in_tests;
     store.register_late_pass(move || Box::new(approx_const::ApproxConstant::new(msrv)));
-    store.register_late_pass(move || Box::new(methods::Methods::new(avoid_breaking_exported_api, msrv)));
+    store.register_late_pass(move || {
+        Box::new(methods::Methods::new(
+            avoid_breaking_exported_api,
+            msrv,
+            allow_expect_in_tests,
+            allow_unwrap_in_tests,
+        ))
+    });
     store.register_late_pass(move || Box::new(matches::Matches::new(msrv)));
     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)));
@@ -669,7 +681,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| Box::new(arithmetic::Arithmetic::default()));
     store.register_late_pass(|| Box::new(assign_ops::AssignOps));
     store.register_late_pass(|| Box::new(let_if_seq::LetIfSeq));
-    store.register_late_pass(|| Box::new(eval_order_dependence::EvalOrderDependence));
+    store.register_late_pass(|| Box::new(mixed_read_write_in_expression::EvalOrderDependence));
     store.register_late_pass(|| Box::new(missing_doc::MissingDoc::new()));
     store.register_late_pass(|| Box::new(missing_inline::MissingInline));
     store.register_late_pass(move || Box::new(exhaustive_items::ExhaustiveItems));
@@ -892,6 +904,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     let max_include_file_size = conf.max_include_file_size;
     store.register_late_pass(move || Box::new(large_include_file::LargeIncludeFile::new(max_include_file_size)));
     store.register_late_pass(|| Box::new(strings::TrimSplitWhitespace));
+    store.register_late_pass(|| Box::new(rc_clone_in_vec_init::RcCloneInVecInit));
+    store.register_early_pass(|| Box::new(duplicate_mod::DuplicateMod::default()));
     // add lints here, do not remove this comment, it's used in `new_lint`
 }
 
diff --git a/clippy_lints/src/literal_representation.rs b/clippy_lints/src/literal_representation.rs
index 269d3c62eaf..9998712b852 100644
--- a/clippy_lints/src/literal_representation.rs
+++ b/clippy_lints/src/literal_representation.rs
@@ -204,7 +204,6 @@ impl WarningType {
     }
 }
 
-#[allow(clippy::module_name_repetitions)]
 #[derive(Copy, Clone)]
 pub struct LiteralDigitGrouping {
     lint_fraction_readability: bool,
@@ -432,7 +431,7 @@ impl LiteralDigitGrouping {
     }
 }
 
-#[allow(clippy::module_name_repetitions)]
+#[expect(clippy::module_name_repetitions)]
 #[derive(Copy, Clone)]
 pub struct DecimalLiteralRepresentation {
     threshold: u64,
diff --git a/clippy_lints/src/loops/mod.rs b/clippy_lints/src/loops/mod.rs
index f029067d367..75d771f992a 100644
--- a/clippy_lints/src/loops/mod.rs
+++ b/clippy_lints/src/loops/mod.rs
@@ -620,7 +620,6 @@ declare_lint_pass!(Loops => [
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Loops {
-    #[allow(clippy::too_many_lines)]
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         let for_loop = higher::ForLoop::hir(expr);
         if let Some(higher::ForLoop {
diff --git a/clippy_lints/src/loops/needless_range_loop.rs b/clippy_lints/src/loops/needless_range_loop.rs
index 6ed141fa4a5..09f9c05b4fc 100644
--- a/clippy_lints/src/loops/needless_range_loop.rs
+++ b/clippy_lints/src/loops/needless_range_loop.rs
@@ -19,7 +19,7 @@ use std::mem;
 
 /// Checks for looping over a range and then indexing a sequence with it.
 /// The iteratee must be a range literal.
-#[allow(clippy::too_many_lines)]
+#[expect(clippy::too_many_lines)]
 pub(super) fn check<'tcx>(
     cx: &LateContext<'tcx>,
     pat: &'tcx Pat<'_>,
diff --git a/clippy_lints/src/loops/utils.rs b/clippy_lints/src/loops/utils.rs
index 772d251b620..4801a84eb92 100644
--- a/clippy_lints/src/loops/utils.rs
+++ b/clippy_lints/src/loops/utils.rs
@@ -13,7 +13,7 @@ use rustc_span::symbol::{sym, Symbol};
 use rustc_typeck::hir_ty_to_ty;
 use std::iter::Iterator;
 
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Eq)]
 enum IncrementVisitorVarState {
     Initial,  // Not examined yet
     IncrOnce, // Incremented exactly once, may be a loop counter
diff --git a/clippy_lints/src/loops/while_let_on_iterator.rs b/clippy_lints/src/loops/while_let_on_iterator.rs
index 20a8294a0d1..82760607ba2 100644
--- a/clippy_lints/src/loops/while_let_on_iterator.rs
+++ b/clippy_lints/src/loops/while_let_on_iterator.rs
@@ -239,7 +239,7 @@ fn uses_iter<'tcx>(cx: &LateContext<'tcx>, iter_expr: &IterExpr, container: &'tc
     v.uses_iter
 }
 
-#[allow(clippy::too_many_lines)]
+#[expect(clippy::too_many_lines)]
 fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &Expr<'_>) -> bool {
     struct AfterLoopVisitor<'a, 'b, 'tcx> {
         cx: &'a LateContext<'tcx>,
diff --git a/clippy_lints/src/macro_use.rs b/clippy_lints/src/macro_use.rs
index ca1ccb93bf3..da806918be0 100644
--- a/clippy_lints/src/macro_use.rs
+++ b/clippy_lints/src/macro_use.rs
@@ -35,7 +35,8 @@ struct PathAndSpan {
     span: Span,
 }
 
-/// `MacroRefData` includes the name of the macro.
+/// `MacroRefData` includes the name of the macro
+/// and the path from `SourceMap::span_to_filename`.
 #[derive(Debug, Clone)]
 pub struct MacroRefData {
     name: String,
@@ -48,7 +49,7 @@ impl MacroRefData {
 }
 
 #[derive(Default)]
-#[allow(clippy::module_name_repetitions)]
+#[expect(clippy::module_name_repetitions)]
 pub struct MacroUseImports {
     /// the actual import path used and the span of the attribute above it.
     imports: Vec<(String, Span)>,
@@ -134,7 +135,6 @@ impl<'tcx> LateLintPass<'tcx> for MacroUseImports {
             self.push_unique_macro_pat_ty(cx, ty.span);
         }
     }
-    #[allow(clippy::too_many_lines)]
     fn check_crate_post(&mut self, cx: &LateContext<'_>) {
         let mut used = FxHashMap::default();
         let mut check_dup = vec![];
diff --git a/clippy_lints/src/main_recursion.rs b/clippy_lints/src/main_recursion.rs
index fad8fa467d4..20333c150e3 100644
--- a/clippy_lints/src/main_recursion.rs
+++ b/clippy_lints/src/main_recursion.rs
@@ -12,7 +12,7 @@ declare_clippy_lint! {
     ///
     /// ### Why is this bad?
     /// Apart from special setups (which we could detect following attributes like #![no_std]),
-    /// recursing into main() seems like an unintuitive antipattern we should be able to detect.
+    /// recursing into main() seems like an unintuitive anti-pattern we should be able to detect.
     ///
     /// ### Example
     /// ```no_run
diff --git a/clippy_lints/src/manual_bits.rs b/clippy_lints/src/manual_bits.rs
index ac3d9447b6b..60bbcde4f1d 100644
--- a/clippy_lints/src/manual_bits.rs
+++ b/clippy_lints/src/manual_bits.rs
@@ -48,7 +48,7 @@ impl_lint_pass!(ManualBits => [MANUAL_BITS]);
 
 impl<'tcx> LateLintPass<'tcx> for ManualBits {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if !meets_msrv(self.msrv.as_ref(), &msrvs::MANUAL_BITS) {
+        if !meets_msrv(self.msrv, msrvs::MANUAL_BITS) {
             return;
         }
 
diff --git a/clippy_lints/src/manual_map.rs b/clippy_lints/src/manual_map.rs
index 8475e367b09..230ae029ed9 100644
--- a/clippy_lints/src/manual_map.rs
+++ b/clippy_lints/src/manual_map.rs
@@ -46,7 +46,7 @@ declare_clippy_lint! {
 declare_lint_pass!(ManualMap => [MANUAL_MAP]);
 
 impl<'tcx> LateLintPass<'tcx> for ManualMap {
-    #[allow(clippy::too_many_lines)]
+    #[expect(clippy::too_many_lines)]
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         let (scrutinee, then_pat, then_body, else_pat, else_body) = match IfLetOrMatch::parse(cx, expr) {
             Some(IfLetOrMatch::IfLet(scrutinee, pat, body, Some(r#else))) => (scrutinee, pat, body, None, r#else),
diff --git a/clippy_lints/src/manual_non_exhaustive.rs b/clippy_lints/src/manual_non_exhaustive.rs
index 09164690700..80845ace3f9 100644
--- a/clippy_lints/src/manual_non_exhaustive.rs
+++ b/clippy_lints/src/manual_non_exhaustive.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet_opt;
-use clippy_utils::{is_lint_allowed, meets_msrv, msrvs};
+use clippy_utils::{is_doc_hidden, is_lint_allowed, meets_msrv, msrvs};
 use rustc_ast::ast::{self, VisibilityKind};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
@@ -61,7 +61,7 @@ declare_clippy_lint! {
     "manual implementations of the non-exhaustive pattern can be simplified using #[non_exhaustive]"
 }
 
-#[allow(clippy::module_name_repetitions)]
+#[expect(clippy::module_name_repetitions)]
 pub struct ManualNonExhaustiveStruct {
     msrv: Option<RustcVersion>,
 }
@@ -75,7 +75,7 @@ impl ManualNonExhaustiveStruct {
 
 impl_lint_pass!(ManualNonExhaustiveStruct => [MANUAL_NON_EXHAUSTIVE]);
 
-#[allow(clippy::module_name_repetitions)]
+#[expect(clippy::module_name_repetitions)]
 pub struct ManualNonExhaustiveEnum {
     msrv: Option<RustcVersion>,
     constructed_enum_variants: FxHashSet<(DefId, DefId)>,
@@ -97,7 +97,7 @@ impl_lint_pass!(ManualNonExhaustiveEnum => [MANUAL_NON_EXHAUSTIVE]);
 
 impl EarlyLintPass for ManualNonExhaustiveStruct {
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
-        if !meets_msrv(self.msrv.as_ref(), &msrvs::NON_EXHAUSTIVE) {
+        if !meets_msrv(self.msrv, msrvs::NON_EXHAUSTIVE) {
             return;
         }
 
@@ -149,7 +149,7 @@ impl EarlyLintPass for ManualNonExhaustiveStruct {
 
 impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
-        if !meets_msrv(self.msrv.as_ref(), &msrvs::NON_EXHAUSTIVE) {
+        if !meets_msrv(self.msrv, msrvs::NON_EXHAUSTIVE) {
             return;
         }
 
@@ -160,7 +160,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
                 let id = cx.tcx.hir().local_def_id(v.id);
                 (matches!(v.data, hir::VariantData::Unit(_))
                     && v.ident.as_str().starts_with('_')
-                    && cx.tcx.is_doc_hidden(id.to_def_id()))
+                    && is_doc_hidden(cx.tcx.hir().attrs(v.id)))
                 .then(|| (id, v.span))
             });
             if let Some((id, span)) = iter.next()
diff --git a/clippy_lints/src/manual_strip.rs b/clippy_lints/src/manual_strip.rs
index aacabf303a7..dfb3efc4e28 100644
--- a/clippy_lints/src/manual_strip.rs
+++ b/clippy_lints/src/manual_strip.rs
@@ -68,7 +68,7 @@ enum StripKind {
 
 impl<'tcx> LateLintPass<'tcx> for ManualStrip {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if !meets_msrv(self.msrv.as_ref(), &msrvs::STR_STRIP_PREFIX) {
+        if !meets_msrv(self.msrv, msrvs::STR_STRIP_PREFIX) {
             return;
         }
 
diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs
index ceb66947d02..a13d191375b 100644
--- a/clippy_lints/src/map_clone.rs
+++ b/clippy_lints/src/map_clone.rs
@@ -144,7 +144,7 @@ impl MapClone {
     fn lint_explicit_closure(&self, cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool) {
         let mut applicability = Applicability::MachineApplicable;
 
-        let (message, sugg_method) = if is_copy && meets_msrv(self.msrv.as_ref(), &msrvs::ITERATOR_COPIED) {
+        let (message, sugg_method) = if is_copy && meets_msrv(self.msrv, msrvs::ITERATOR_COPIED) {
             ("you are using an explicit closure for copying elements", "copied")
         } else {
             ("you are using an explicit closure for cloning elements", "cloned")
diff --git a/clippy_lints/src/matches/match_same_arms.rs b/clippy_lints/src/matches/match_same_arms.rs
index 9b7344fb8b0..a96a7fe55f3 100644
--- a/clippy_lints/src/matches/match_same_arms.rs
+++ b/clippy_lints/src/matches/match_same_arms.rs
@@ -16,7 +16,7 @@ use std::collections::hash_map::Entry;
 
 use super::MATCH_SAME_ARMS;
 
-#[allow(clippy::too_many_lines)]
+#[expect(clippy::too_many_lines)]
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>]) {
     let hash = |&(_, arm): &(usize, &Arm<'_>)| -> u64 {
         let mut h = SpanlessHash::new(cx);
@@ -225,9 +225,9 @@ fn iter_matching_struct_fields<'a>(
     Iter(left.iter(), right.iter())
 }
 
-#[allow(clippy::similar_names)]
+#[expect(clippy::similar_names)]
 impl<'a> NormalizedPat<'a> {
-    #[allow(clippy::too_many_lines)]
+    #[expect(clippy::too_many_lines)]
     fn from_pat(cx: &LateContext<'_>, arena: &'a DroplessArena, pat: &'a Pat<'_>) -> Self {
         match pat.kind {
             PatKind::Wild | PatKind::Binding(.., None) => Self::Wild,
diff --git a/clippy_lints/src/matches/match_single_binding.rs b/clippy_lints/src/matches/match_single_binding.rs
index 39fe54648fb..a59711d4cac 100644
--- a/clippy_lints/src/matches/match_single_binding.rs
+++ b/clippy_lints/src/matches/match_single_binding.rs
@@ -1,15 +1,22 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::{indent_of, snippet_block, snippet_with_applicability};
+use clippy_utils::macros::HirNode;
+use clippy_utils::source::{indent_of, snippet, snippet_block, snippet_with_applicability};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{get_parent_expr, is_refutable, peel_blocks};
 use rustc_errors::Applicability;
-use rustc_hir::{Arm, Expr, ExprKind, Local, Node, PatKind};
+use rustc_hir::{Arm, Expr, ExprKind, Node, PatKind};
 use rustc_lint::LateContext;
+use rustc_span::Span;
 
 use super::MATCH_SINGLE_BINDING;
 
-#[allow(clippy::too_many_lines)]
-pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], expr: &Expr<'_>) {
+enum AssignmentExpr {
+    Assign { span: Span, match_span: Span },
+    Local { span: Span, pat_span: Span },
+}
+
+#[expect(clippy::too_many_lines)]
+pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], expr: &Expr<'a>) {
     if expr.span.from_expansion() || arms.len() != 1 || is_refutable(cx, arms[0].pat) {
         return;
     }
@@ -42,61 +49,59 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e
     let mut applicability = Applicability::MaybeIncorrect;
     match arms[0].pat.kind {
         PatKind::Binding(..) | PatKind::Tuple(_, _) | PatKind::Struct(..) => {
-            // If this match is in a local (`let`) stmt
-            let (target_span, sugg) = if let Some(parent_let_node) = opt_parent_let(cx, ex) {
-                (
-                    parent_let_node.span,
+            let (target_span, sugg) = match opt_parent_assign_span(cx, ex) {
+                Some(AssignmentExpr::Assign { span, match_span }) => {
+                    let sugg = sugg_with_curlies(
+                        cx,
+                        (ex, expr),
+                        (bind_names, matched_vars),
+                        &*snippet_body,
+                        &mut applicability,
+                        Some(span),
+                    );
+
+                    span_lint_and_sugg(
+                        cx,
+                        MATCH_SINGLE_BINDING,
+                        span.to(match_span),
+                        "this assignment could be simplified",
+                        "consider removing the `match` expression",
+                        sugg,
+                        applicability,
+                    );
+
+                    return;
+                },
+                Some(AssignmentExpr::Local { span, pat_span }) => (
+                    span,
                     format!(
                         "let {} = {};\n{}let {} = {};",
                         snippet_with_applicability(cx, bind_names, "..", &mut applicability),
                         snippet_with_applicability(cx, matched_vars, "..", &mut applicability),
                         " ".repeat(indent_of(cx, expr.span).unwrap_or(0)),
-                        snippet_with_applicability(cx, parent_let_node.pat.span, "..", &mut applicability),
+                        snippet_with_applicability(cx, pat_span, "..", &mut applicability),
                         snippet_body
                     ),
-                )
-            } else {
-                // If we are in closure, we need curly braces around suggestion
-                let mut indent = " ".repeat(indent_of(cx, ex.span).unwrap_or(0));
-                let (mut cbrace_start, mut cbrace_end) = ("".to_string(), "".to_string());
-                if let Some(parent_expr) = get_parent_expr(cx, expr) {
-                    if let ExprKind::Closure(..) = parent_expr.kind {
-                        cbrace_end = format!("\n{}}}", indent);
-                        // Fix body indent due to the closure
-                        indent = " ".repeat(indent_of(cx, bind_names).unwrap_or(0));
-                        cbrace_start = format!("{{\n{}", indent);
-                    }
-                }
-                // If the parent is already an arm, and the body is another match statement,
-                // we need curly braces around suggestion
-                let parent_node_id = cx.tcx.hir().get_parent_node(expr.hir_id);
-                if let Node::Arm(arm) = &cx.tcx.hir().get(parent_node_id) {
-                    if let ExprKind::Match(..) = arm.body.kind {
-                        cbrace_end = format!("\n{}}}", indent);
-                        // Fix body indent due to the match
-                        indent = " ".repeat(indent_of(cx, bind_names).unwrap_or(0));
-                        cbrace_start = format!("{{\n{}", indent);
-                    }
-                }
-                (
-                    expr.span,
-                    format!(
-                        "{}let {} = {};\n{}{}{}",
-                        cbrace_start,
-                        snippet_with_applicability(cx, bind_names, "..", &mut applicability),
-                        snippet_with_applicability(cx, matched_vars, "..", &mut applicability),
-                        indent,
-                        snippet_body,
-                        cbrace_end
-                    ),
-                )
+                ),
+                None => {
+                    let sugg = sugg_with_curlies(
+                        cx,
+                        (ex, expr),
+                        (bind_names, matched_vars),
+                        &*snippet_body,
+                        &mut applicability,
+                        None,
+                    );
+                    (expr.span, sugg)
+                },
             };
+
             span_lint_and_sugg(
                 cx,
                 MATCH_SINGLE_BINDING,
                 target_span,
                 "this match could be written as a `let` statement",
-                "consider using `let` statement",
+                "consider using a `let` statement",
                 sugg,
                 applicability,
             );
@@ -110,6 +115,7 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e
                     indent,
                     snippet_body
                 );
+
                 span_lint_and_sugg(
                     cx,
                     MATCH_SINGLE_BINDING,
@@ -135,15 +141,76 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e
     }
 }
 
-/// Returns true if the `ex` match expression is in a local (`let`) statement
-fn opt_parent_let<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option<&'a Local<'a>> {
+/// Returns true if the `ex` match expression is in a local (`let`) or assign expression
+fn opt_parent_assign_span<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option<AssignmentExpr> {
     let map = &cx.tcx.hir();
-    if_chain! {
-        if let Some(Node::Expr(parent_arm_expr)) = map.find(map.get_parent_node(ex.hir_id));
-        if let Some(Node::Local(parent_let_expr)) = map.find(map.get_parent_node(parent_arm_expr.hir_id));
-        then {
-            return Some(parent_let_expr);
-        }
+
+    if let Some(Node::Expr(parent_arm_expr)) = map.find(map.get_parent_node(ex.hir_id)) {
+        return match map.find(map.get_parent_node(parent_arm_expr.hir_id)) {
+            Some(Node::Local(parent_let_expr)) => Some(AssignmentExpr::Local {
+                span: parent_let_expr.span,
+                pat_span: parent_let_expr.pat.span(),
+            }),
+            Some(Node::Expr(Expr {
+                kind: ExprKind::Assign(parent_assign_expr, match_expr, _),
+                ..
+            })) => Some(AssignmentExpr::Assign {
+                span: parent_assign_expr.span,
+                match_span: match_expr.span,
+            }),
+            _ => None,
+        };
     }
+
     None
 }
+
+fn sugg_with_curlies<'a>(
+    cx: &LateContext<'a>,
+    (ex, match_expr): (&Expr<'a>, &Expr<'a>),
+    (bind_names, matched_vars): (Span, Span),
+    snippet_body: &str,
+    applicability: &mut Applicability,
+    assignment: Option<Span>,
+) -> String {
+    let mut indent = " ".repeat(indent_of(cx, ex.span).unwrap_or(0));
+
+    let (mut cbrace_start, mut cbrace_end) = (String::new(), String::new());
+    if let Some(parent_expr) = get_parent_expr(cx, match_expr) {
+        if let ExprKind::Closure(..) = parent_expr.kind {
+            cbrace_end = format!("\n{}}}", indent);
+            // Fix body indent due to the closure
+            indent = " ".repeat(indent_of(cx, bind_names).unwrap_or(0));
+            cbrace_start = format!("{{\n{}", indent);
+        }
+    }
+
+    // If the parent is already an arm, and the body is another match statement,
+    // we need curly braces around suggestion
+    let parent_node_id = cx.tcx.hir().get_parent_node(match_expr.hir_id);
+    if let Node::Arm(arm) = &cx.tcx.hir().get(parent_node_id) {
+        if let ExprKind::Match(..) = arm.body.kind {
+            cbrace_end = format!("\n{}}}", indent);
+            // Fix body indent due to the match
+            indent = " ".repeat(indent_of(cx, bind_names).unwrap_or(0));
+            cbrace_start = format!("{{\n{}", indent);
+        }
+    }
+
+    let assignment_str = assignment.map_or_else(String::new, |span| {
+        let mut s = snippet(cx, span, "..").to_string();
+        s.push_str(" = ");
+        s
+    });
+
+    format!(
+        "{}let {} = {};\n{}{}{}{}",
+        cbrace_start,
+        snippet_with_applicability(cx, bind_names, "..", applicability),
+        snippet_with_applicability(cx, matched_vars, "..", applicability),
+        indent,
+        assignment_str,
+        snippet_body,
+        cbrace_end
+    )
+}
diff --git a/clippy_lints/src/matches/match_wild_enum.rs b/clippy_lints/src/matches/match_wild_enum.rs
index fc45ccee185..6f8d766aef7 100644
--- a/clippy_lints/src/matches/match_wild_enum.rs
+++ b/clippy_lints/src/matches/match_wild_enum.rs
@@ -10,7 +10,7 @@ use rustc_span::sym;
 
 use super::{MATCH_WILDCARD_FOR_SINGLE_VARIANTS, WILDCARD_ENUM_MATCH_ARM};
 
-#[allow(clippy::too_many_lines)]
+#[expect(clippy::too_many_lines)]
 pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
     let ty = cx.typeck_results().expr_ty(ex).peel_refs();
     let adt_def = match ty.kind() {
@@ -56,7 +56,6 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
         recurse_or_patterns(arm.pat, |pat| {
             let path = match &peel_hir_pat_refs(pat).0.kind {
                 PatKind::Path(path) => {
-                    #[allow(clippy::match_same_arms)]
                     let id = match cx.qpath_res(path, pat.hir_id) {
                         Res::Def(
                             DefKind::Const | DefKind::ConstParam | DefKind::AnonConst | DefKind::InlineConst,
diff --git a/clippy_lints/src/matches/mod.rs b/clippy_lints/src/matches/mod.rs
index 401ecef460c..3d8391bce2b 100644
--- a/clippy_lints/src/matches/mod.rs
+++ b/clippy_lints/src/matches/mod.rs
@@ -658,7 +658,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
             }
             if !contains_cfg_arm(cx, expr, ex, arms) {
                 if source == MatchSource::Normal {
-                    if !(meets_msrv(self.msrv.as_ref(), &msrvs::MATCHES_MACRO)
+                    if !(meets_msrv(self.msrv, msrvs::MATCHES_MACRO)
                         && match_like_matches::check_match(cx, expr, ex, arms))
                     {
                         match_same_arms::check(cx, arms);
@@ -685,7 +685,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
             match_wild_err_arm::check(cx, ex, arms);
             wild_in_or_pats::check(cx, arms);
         } else {
-            if meets_msrv(self.msrv.as_ref(), &msrvs::MATCHES_MACRO) {
+            if meets_msrv(self.msrv, msrvs::MATCHES_MACRO) {
                 match_like_matches::check(cx, expr);
             }
             redundant_pattern_match::check(cx, expr);
diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs
index 37b67647efe..1a8b9d15f37 100644
--- a/clippy_lints/src/matches/redundant_pattern_match.rs
+++ b/clippy_lints/src/matches/redundant_pattern_match.rs
@@ -340,7 +340,7 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op
     }
 }
 
-#[allow(clippy::too_many_arguments)]
+#[expect(clippy::too_many_arguments)]
 fn find_good_method_for_match<'a>(
     cx: &LateContext<'_>,
     arms: &[Arm<'_>],
diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs
index 054937e3e36..41073d40f3d 100644
--- a/clippy_lints/src/mem_replace.rs
+++ b/clippy_lints/src/mem_replace.rs
@@ -254,7 +254,7 @@ impl<'tcx> LateLintPass<'tcx> for MemReplace {
             then {
                 check_replace_option_with_none(cx, src, dest, expr.span);
                 check_replace_with_uninit(cx, src, dest, expr.span);
-                if meets_msrv(self.msrv.as_ref(), &msrvs::MEM_TAKE) {
+                if meets_msrv(self.msrv, msrvs::MEM_TAKE) {
                     check_replace_with_default(cx, src, dest, expr.span);
                 }
             }
diff --git a/clippy_lints/src/methods/cloned_instead_of_copied.rs b/clippy_lints/src/methods/cloned_instead_of_copied.rs
index 6d30bb5a278..e9aeab2d5b6 100644
--- a/clippy_lints/src/methods/cloned_instead_of_copied.rs
+++ b/clippy_lints/src/methods/cloned_instead_of_copied.rs
@@ -10,16 +10,16 @@ use rustc_span::{sym, Span};
 
 use super::CLONED_INSTEAD_OF_COPIED;
 
-pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span, msrv: Option<&RustcVersion>) {
+pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span, msrv: Option<RustcVersion>) {
     let recv_ty = cx.typeck_results().expr_ty_adjusted(recv);
     let inner_ty = match recv_ty.kind() {
         // `Option<T>` -> `T`
         ty::Adt(adt, subst)
-            if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && meets_msrv(msrv, &msrvs::OPTION_COPIED) =>
+            if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && meets_msrv(msrv, msrvs::OPTION_COPIED) =>
         {
             subst.type_at(0)
         },
-        _ if is_trait_method(cx, expr, sym::Iterator) && meets_msrv(msrv, &msrvs::ITERATOR_COPIED) => {
+        _ if is_trait_method(cx, expr, sym::Iterator) && meets_msrv(msrv, msrvs::ITERATOR_COPIED) => {
             match get_iterator_item_ty(cx, recv_ty) {
                 // <T as Iterator>::Item
                 Some(ty) => ty,
diff --git a/clippy_lints/src/methods/err_expect.rs b/clippy_lints/src/methods/err_expect.rs
index be9d4ad94fb..570a1b87358 100644
--- a/clippy_lints/src/methods/err_expect.rs
+++ b/clippy_lints/src/methods/err_expect.rs
@@ -13,7 +13,7 @@ pub(super) fn check(
     cx: &LateContext<'_>,
     _expr: &rustc_hir::Expr<'_>,
     recv: &rustc_hir::Expr<'_>,
-    msrv: Option<&RustcVersion>,
+    msrv: Option<RustcVersion>,
     expect_span: Span,
     err_span: Span,
 ) {
@@ -21,7 +21,7 @@ pub(super) fn check(
         if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result);
         // Test the version to make sure the lint can be showed (expect_err has been
         // introduced in rust 1.17.0 : https://github.com/rust-lang/rust/pull/38982)
-        if meets_msrv(msrv, &msrvs::EXPECT_ERR);
+        if meets_msrv(msrv, msrvs::EXPECT_ERR);
 
         // Grabs the `Result<T, E>` type
         let result_type = cx.typeck_results().expr_ty(recv);
diff --git a/clippy_lints/src/methods/expect_used.rs b/clippy_lints/src/methods/expect_used.rs
index 55be513c5bb..fbc3348f185 100644
--- a/clippy_lints/src/methods/expect_used.rs
+++ b/clippy_lints/src/methods/expect_used.rs
@@ -1,4 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::is_in_test_function;
 use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
@@ -7,7 +8,7 @@ use rustc_span::sym;
 use super::EXPECT_USED;
 
 /// lint use of `expect()` for `Option`s and `Result`s
-pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {
+pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, allow_expect_in_tests: bool) {
     let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
 
     let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) {
@@ -18,6 +19,10 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
         None
     };
 
+    if allow_expect_in_tests && is_in_test_function(cx.tcx, expr.hir_id) {
+        return;
+    }
+
     if let Some((lint, kind, none_value)) = mess {
         span_lint_and_help(
             cx,
diff --git a/clippy_lints/src/methods/filter_map_next.rs b/clippy_lints/src/methods/filter_map_next.rs
index f0d69a1f42e..38ec4d8e3ab 100644
--- a/clippy_lints/src/methods/filter_map_next.rs
+++ b/clippy_lints/src/methods/filter_map_next.rs
@@ -14,10 +14,10 @@ pub(super) fn check<'tcx>(
     expr: &'tcx hir::Expr<'_>,
     recv: &'tcx hir::Expr<'_>,
     arg: &'tcx hir::Expr<'_>,
-    msrv: Option<&RustcVersion>,
+    msrv: Option<RustcVersion>,
 ) {
     if is_trait_method(cx, expr, sym::Iterator) {
-        if !meets_msrv(msrv, &msrvs::ITERATOR_FIND_MAP) {
+        if !meets_msrv(msrv, msrvs::ITERATOR_FIND_MAP) {
             return;
         }
 
diff --git a/clippy_lints/src/methods/is_digit_ascii_radix.rs b/clippy_lints/src/methods/is_digit_ascii_radix.rs
index ad333df2f2d..aa176dcc8b4 100644
--- a/clippy_lints/src/methods/is_digit_ascii_radix.rs
+++ b/clippy_lints/src/methods/is_digit_ascii_radix.rs
@@ -15,9 +15,9 @@ pub(super) fn check<'tcx>(
     expr: &'tcx Expr<'_>,
     self_arg: &'tcx Expr<'_>,
     radix: &'tcx Expr<'_>,
-    msrv: Option<&RustcVersion>,
+    msrv: Option<RustcVersion>,
 ) {
-    if !meets_msrv(msrv, &msrvs::IS_ASCII_DIGIT) {
+    if !meets_msrv(msrv, msrvs::IS_ASCII_DIGIT) {
         return;
     }
 
diff --git a/clippy_lints/src/methods/map_unwrap_or.rs b/clippy_lints/src/methods/map_unwrap_or.rs
index 9ec84e76519..4a8e7ce4ddb 100644
--- a/clippy_lints/src/methods/map_unwrap_or.rs
+++ b/clippy_lints/src/methods/map_unwrap_or.rs
@@ -19,13 +19,13 @@ pub(super) fn check<'tcx>(
     recv: &'tcx hir::Expr<'_>,
     map_arg: &'tcx hir::Expr<'_>,
     unwrap_arg: &'tcx hir::Expr<'_>,
-    msrv: Option<&RustcVersion>,
+    msrv: Option<RustcVersion>,
 ) -> bool {
     // lint if the caller of `map()` is an `Option`
     let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Option);
     let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result);
 
-    if is_result && !meets_msrv(msrv, &msrvs::RESULT_MAP_OR_ELSE) {
+    if is_result && !meets_msrv(msrv, msrvs::RESULT_MAP_OR_ELSE) {
         return false;
     }
 
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index f3be71f6b8b..35fc452ed7c 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -1563,7 +1563,7 @@ declare_clippy_lint! {
     #[clippy::version = "1.39.0"]
     pub MANUAL_SATURATING_ARITHMETIC,
     style,
-    "`.chcked_add/sub(x).unwrap_or(MAX/MIN)`"
+    "`.checked_add/sub(x).unwrap_or(MAX/MIN)`"
 }
 
 declare_clippy_lint! {
@@ -1776,8 +1776,6 @@ declare_clippy_lint! {
     ///
     /// ### Example
     /// ```rust
-    /// use std::iter::FromIterator;
-    ///
     /// let five_fives = std::iter::repeat(5).take(5);
     ///
     /// let v = Vec::from_iter(five_fives);
@@ -2200,14 +2198,23 @@ declare_clippy_lint! {
 pub struct Methods {
     avoid_breaking_exported_api: bool,
     msrv: Option<RustcVersion>,
+    allow_expect_in_tests: bool,
+    allow_unwrap_in_tests: bool,
 }
 
 impl Methods {
     #[must_use]
-    pub fn new(avoid_breaking_exported_api: bool, msrv: Option<RustcVersion>) -> Self {
+    pub fn new(
+        avoid_breaking_exported_api: bool,
+        msrv: Option<RustcVersion>,
+        allow_expect_in_tests: bool,
+        allow_unwrap_in_tests: bool,
+    ) -> Self {
         Self {
             avoid_breaking_exported_api,
             msrv,
+            allow_expect_in_tests,
+            allow_unwrap_in_tests,
         }
     }
 }
@@ -2306,7 +2313,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
             return;
         }
 
-        check_methods(cx, expr, self.msrv.as_ref());
+        self.check_methods(cx, expr);
 
         match expr.kind {
             hir::ExprKind::Call(func, args) => {
@@ -2322,7 +2329,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
                 single_char_add_str::check(cx, expr, args);
                 into_iter_on_ref::check(cx, expr, method_span, method_call.ident.name, args);
                 single_char_pattern::check(cx, expr, method_call.ident.name, args);
-                unnecessary_to_owned::check(cx, expr, method_call.ident.name, args, self.msrv.as_ref());
+                unnecessary_to_owned::check(cx, expr, method_call.ident.name, args, self.msrv);
             },
             hir::ExprKind::Binary(op, lhs, rhs) if op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne => {
                 let mut info = BinaryExprInfo {
@@ -2505,196 +2512,201 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
     extract_msrv_attr!(LateContext);
 }
 
-#[allow(clippy::too_many_lines)]
-fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Option<&RustcVersion>) {
-    if let Some((name, [recv, args @ ..], span)) = method_call(expr) {
-        match (name, args) {
-            ("add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub", [_arg]) => {
-                zst_offset::check(cx, expr, recv);
-            },
-            ("and_then", [arg]) => {
-                let biom_option_linted = bind_instead_of_map::OptionAndThenSome::check(cx, expr, recv, arg);
-                let biom_result_linted = bind_instead_of_map::ResultAndThenOk::check(cx, expr, recv, arg);
-                if !biom_option_linted && !biom_result_linted {
-                    unnecessary_lazy_eval::check(cx, expr, recv, arg, "and");
-                }
-            },
-            ("as_deref" | "as_deref_mut", []) => {
-                needless_option_as_deref::check(cx, expr, recv, name);
-            },
-            ("as_mut", []) => useless_asref::check(cx, expr, "as_mut", recv),
-            ("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, msrv),
-            ("collect", []) => match method_call(recv) {
-                Some((name @ ("cloned" | "copied"), [recv2], _)) => {
-                    iter_cloned_collect::check(cx, name, expr, recv2);
+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) {
+            match (name, args) {
+                ("add" | "offset" | "sub" | "wrapping_offset" | "wrapping_add" | "wrapping_sub", [_arg]) => {
+                    zst_offset::check(cx, expr, recv);
+                },
+                ("and_then", [arg]) => {
+                    let biom_option_linted = bind_instead_of_map::OptionAndThenSome::check(cx, expr, recv, arg);
+                    let biom_result_linted = bind_instead_of_map::ResultAndThenOk::check(cx, expr, recv, arg);
+                    if !biom_option_linted && !biom_result_linted {
+                        unnecessary_lazy_eval::check(cx, expr, recv, arg, "and");
+                    }
+                },
+                ("as_deref" | "as_deref_mut", []) => {
+                    needless_option_as_deref::check(cx, expr, recv, name);
+                },
+                ("as_mut", []) => useless_asref::check(cx, expr, "as_mut", recv),
+                ("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);
+                        }
+                    },
+                    _ => {},
+                },
+                (name @ "count", args @ []) => match method_call(recv) {
+                    Some(("cloned", [recv2], _)) => iter_overeager_cloned::check(cx, expr, recv2, name, args),
+                    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),
+                    _ => {},
+                },
+                ("drain", [arg]) => {
+                    iter_with_drain::check(cx, expr, recv, span, arg);
+                },
+                ("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),
+                    _ => expect_used::check(cx, expr, recv, self.allow_expect_in_tests),
+                },
+                ("extend", [arg]) => {
+                    string_extend_chars::check(cx, expr, recv, arg);
+                    extend_with_drain::check(cx, expr, recv, arg);
+                },
+                ("filter_map", [arg]) => {
+                    unnecessary_filter_map::check(cx, expr, arg, name);
+                    filter_map_identity::check(cx, expr, arg, span);
                 },
-                Some(("map", [m_recv, m_arg], _)) => {
-                    map_collect_result_unit::check(cx, expr, m_recv, m_arg, recv);
+                ("find_map", [arg]) => {
+                    unnecessary_filter_map::check(cx, expr, arg, name);
                 },
-                Some(("take", [take_self_arg, take_arg], _)) => {
-                    if meets_msrv(msrv, &msrvs::STR_REPEAT) {
-                        manual_str_repeat::check(cx, expr, recv, take_self_arg, take_arg);
+                ("flat_map", [arg]) => {
+                    flat_map_identity::check(cx, expr, arg, span);
+                    flat_map_option::check(cx, expr, arg, span);
+                },
+                (name @ "flatten", args @ []) => 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, recv2, name, args),
+                    _ => {},
+                },
+                ("fold", [init, acc]) => unnecessary_fold::check(cx, expr, init, acc, span),
+                ("for_each", [_]) => {
+                    if let Some(("inspect", [_, _], span2)) = method_call(recv) {
+                        inspect_for_each::check(cx, expr, span2);
                     }
                 },
-                _ => {},
-            },
-            (name @ "count", args @ []) => match method_call(recv) {
-                Some(("cloned", [recv2], _)) => iter_overeager_cloned::check(cx, expr, recv2, name, args),
-                Some((name2 @ ("into_iter" | "iter" | "iter_mut"), [recv2], _)) => {
-                    iter_count::check(cx, expr, recv2, name2);
+                ("get_or_insert_with", [arg]) => unnecessary_lazy_eval::check(cx, expr, recv, arg, "get_or_insert"),
+                ("is_file", []) => filetype_is_file::check(cx, expr, recv),
+                ("is_digit", [radix]) => is_digit_ascii_radix::check(cx, expr, recv, radix, self.msrv),
+                ("is_none", []) => check_is_some_is_none(cx, expr, recv, false),
+                ("is_some", []) => check_is_some_is_none(cx, expr, recv, true),
+                ("join", [join_arg]) => {
+                    if let Some(("collect", _, span)) = method_call(recv) {
+                        unnecessary_join::check(cx, expr, recv, join_arg, span);
+                    }
                 },
-                Some(("map", [_, arg], _)) => suspicious_map::check(cx, expr, recv, arg),
-                _ => {},
-            },
-            ("drain", [arg]) => {
-                iter_with_drain::check(cx, expr, recv, span, arg);
-            },
-            ("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, msrv, span, err_span),
-                _ => expect_used::check(cx, expr, recv),
-            },
-            ("extend", [arg]) => {
-                string_extend_chars::check(cx, expr, recv, arg);
-                extend_with_drain::check(cx, expr, recv, arg);
-            },
-            ("filter_map", [arg]) => {
-                unnecessary_filter_map::check(cx, expr, arg, name);
-                filter_map_identity::check(cx, expr, arg, span);
-            },
-            ("find_map", [arg]) => {
-                unnecessary_filter_map::check(cx, expr, arg, name);
-            },
-            ("flat_map", [arg]) => {
-                flat_map_identity::check(cx, expr, arg, span);
-                flat_map_option::check(cx, expr, arg, span);
-            },
-            (name @ "flatten", args @ []) => 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, recv2, name, args),
-                _ => {},
-            },
-            ("fold", [init, acc]) => unnecessary_fold::check(cx, expr, init, acc, span),
-            ("for_each", [_]) => {
-                if let Some(("inspect", [_, _], span2)) = method_call(recv) {
-                    inspect_for_each::check(cx, expr, span2);
-                }
-            },
-            ("get_or_insert_with", [arg]) => unnecessary_lazy_eval::check(cx, expr, recv, arg, "get_or_insert"),
-            ("is_file", []) => filetype_is_file::check(cx, expr, recv),
-            ("is_digit", [radix]) => is_digit_ascii_radix::check(cx, expr, recv, radix, msrv),
-            ("is_none", []) => check_is_some_is_none(cx, expr, recv, false),
-            ("is_some", []) => check_is_some_is_none(cx, expr, recv, true),
-            ("join", [join_arg]) => {
-                if let Some(("collect", _, span)) = method_call(recv) {
-                    unnecessary_join::check(cx, expr, recv, join_arg, span);
-                }
-            },
-            ("last", args @ []) | ("skip", args @ [_]) => {
-                if let Some((name2, [recv2, args2 @ ..], _span2)) = method_call(recv) {
-                    if let ("cloned", []) = (name2, args2) {
-                        iter_overeager_cloned::check(cx, expr, recv2, name, args);
+                ("last", args @ []) | ("skip", args @ [_]) => {
+                    if let Some((name2, [recv2, args2 @ ..], _span2)) = method_call(recv) {
+                        if let ("cloned", []) = (name2, args2) {
+                            iter_overeager_cloned::check(cx, expr, recv2, name, args);
+                        }
                     }
-                }
-            },
-            (name @ ("map" | "map_err"), [m_arg]) => {
-                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, msrv),
-                        ("as_ref", []) => option_as_ref_deref::check(cx, expr, recv2, m_arg, false, msrv),
-                        ("filter", [f_arg]) => {
-                            filter_map::check(cx, expr, recv2, f_arg, span2, recv, m_arg, span, false);
-                        },
-                        ("find", [f_arg]) => filter_map::check(cx, expr, recv2, f_arg, span2, recv, m_arg, span, true),
-                        _ => {},
+                },
+                (name @ ("map" | "map_err"), [m_arg]) => {
+                    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),
+                            ("filter", [f_arg]) => {
+                                filter_map::check(cx, expr, recv2, f_arg, span2, recv, m_arg, span, false);
+                            },
+                            ("find", [f_arg]) => {
+                                filter_map::check(cx, expr, recv2, f_arg, span2, recv, m_arg, span, true);
+                            },
+                            _ => {},
+                        }
                     }
-                }
-                map_identity::check(cx, expr, recv, m_arg, name, span);
-            },
-            ("map_or", [def, map]) => option_map_or_none::check(cx, expr, recv, def, map),
-            (name @ "next", args @ []) => {
-                if let Some((name2, [recv2, args2 @ ..], _)) = method_call(recv) {
-                    match (name2, args2) {
-                        ("cloned", []) => iter_overeager_cloned::check(cx, expr, recv2, name, args),
-                        ("filter", [arg]) => filter_next::check(cx, expr, recv2, arg),
-                        ("filter_map", [arg]) => filter_map_next::check(cx, expr, recv2, arg, msrv),
-                        ("iter", []) => iter_next_slice::check(cx, expr, recv2),
-                        ("skip", [arg]) => iter_skip_next::check(cx, expr, recv2, arg),
-                        ("skip_while", [_]) => skip_while_next::check(cx, expr),
-                        _ => {},
+                    map_identity::check(cx, expr, recv, m_arg, name, span);
+                },
+                ("map_or", [def, map]) => option_map_or_none::check(cx, expr, recv, def, map),
+                (name @ "next", args @ []) => {
+                    if let Some((name2, [recv2, args2 @ ..], _)) = method_call(recv) {
+                        match (name2, args2) {
+                            ("cloned", []) => iter_overeager_cloned::check(cx, expr, recv2, name, args),
+                            ("filter", [arg]) => filter_next::check(cx, expr, recv2, arg),
+                            ("filter_map", [arg]) => filter_map_next::check(cx, expr, recv2, arg, self.msrv),
+                            ("iter", []) => iter_next_slice::check(cx, expr, recv2),
+                            ("skip", [arg]) => iter_skip_next::check(cx, expr, recv2, arg),
+                            ("skip_while", [_]) => skip_while_next::check(cx, expr),
+                            _ => {},
+                        }
                     }
-                }
-            },
-            ("nth", args @ [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, recv2, name, args),
-                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"),
-            ("or_else", [arg]) => {
-                if !bind_instead_of_map::ResultOrElseErrInfo::check(cx, expr, recv, arg) {
-                    unnecessary_lazy_eval::check(cx, expr, recv, arg, "or");
-                }
-            },
-            ("splitn" | "rsplitn", [count_arg, pat_arg]) => {
-                if let Some((Constant::Int(count), _)) = constant(cx, cx.typeck_results(), count_arg) {
-                    suspicious_splitn::check(cx, name, expr, recv, count);
-                    str_splitn::check(cx, name, expr, recv, pat_arg, count, msrv);
-                }
-            },
-            ("splitn_mut" | "rsplitn_mut", [count_arg, _]) => {
-                if let Some((Constant::Int(count), _)) = constant(cx, cx.typeck_results(), count_arg) {
-                    suspicious_splitn::check(cx, name, expr, recv, count);
-                }
-            },
-            ("step_by", [arg]) => iterator_step_by_zero::check(cx, expr, arg),
-            ("take", args @ [_arg]) => {
-                if let Some((name2, [recv2, args2 @ ..], _span2)) = method_call(recv) {
-                    if let ("cloned", []) = (name2, args2) {
-                        iter_overeager_cloned::check(cx, expr, recv2, name, args);
+                },
+                ("nth", args @ [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, recv2, name, args),
+                    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"),
+                ("or_else", [arg]) => {
+                    if !bind_instead_of_map::ResultOrElseErrInfo::check(cx, expr, recv, arg) {
+                        unnecessary_lazy_eval::check(cx, expr, recv, arg, "or");
                     }
-                }
-            },
-            ("take", []) => needless_option_take::check(cx, expr, recv),
-            ("to_os_string" | "to_owned" | "to_path_buf" | "to_vec", []) => {
-                implicit_clone::check(cx, name, expr, recv);
-            },
-            ("unwrap", []) => {
-                match method_call(recv) {
-                    Some(("get", [recv, get_arg], _)) => {
-                        get_unwrap::check(cx, expr, recv, get_arg, false);
-                    },
-                    Some(("get_mut", [recv, get_arg], _)) => {
-                        get_unwrap::check(cx, expr, recv, get_arg, true);
+                },
+                ("splitn" | "rsplitn", [count_arg, pat_arg]) => {
+                    if let Some((Constant::Int(count), _)) = constant(cx, cx.typeck_results(), count_arg) {
+                        suspicious_splitn::check(cx, name, expr, recv, count);
+                        str_splitn::check(cx, name, expr, recv, pat_arg, count, self.msrv);
+                    }
+                },
+                ("splitn_mut" | "rsplitn_mut", [count_arg, _]) => {
+                    if let Some((Constant::Int(count), _)) = constant(cx, cx.typeck_results(), count_arg) {
+                        suspicious_splitn::check(cx, name, expr, recv, count);
+                    }
+                },
+                ("step_by", [arg]) => iterator_step_by_zero::check(cx, expr, arg),
+                ("take", args @ [_arg]) => {
+                    if let Some((name2, [recv2, args2 @ ..], _span2)) = method_call(recv) {
+                        if let ("cloned", []) = (name2, args2) {
+                            iter_overeager_cloned::check(cx, expr, recv2, name, args);
+                        }
+                    }
+                },
+                ("take", []) => needless_option_take::check(cx, expr, recv),
+                ("to_os_string" | "to_owned" | "to_path_buf" | "to_vec", []) => {
+                    implicit_clone::check(cx, name, expr, recv);
+                },
+                ("unwrap", []) => {
+                    match method_call(recv) {
+                        Some(("get", [recv, get_arg], _)) => {
+                            get_unwrap::check(cx, expr, recv, get_arg, false);
+                        },
+                        Some(("get_mut", [recv, get_arg], _)) => {
+                            get_unwrap::check(cx, expr, recv, get_arg, true);
+                        },
+                        Some(("or", [recv, or_arg], or_span)) => {
+                            or_then_unwrap::check(cx, expr, recv, or_arg, or_span);
+                        },
+                        _ => {},
+                    }
+                    unwrap_used::check(cx, expr, recv, self.allow_unwrap_in_tests);
+                },
+                ("unwrap_or", [u_arg]) => match method_call(recv) {
+                    Some((arith @ ("checked_add" | "checked_sub" | "checked_mul"), [lhs, rhs], _)) => {
+                        manual_saturating_arithmetic::check(cx, expr, lhs, rhs, u_arg, &arith["checked_".len()..]);
                     },
-                    Some(("or", [recv, or_arg], or_span)) => {
-                        or_then_unwrap::check(cx, expr, recv, or_arg, or_span);
+                    Some(("map", [m_recv, m_arg], span)) => {
+                        option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span);
                     },
                     _ => {},
-                }
-                unwrap_used::check(cx, expr, recv);
-            },
-            ("unwrap_or", [u_arg]) => match method_call(recv) {
-                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)) => {
-                    option_map_unwrap_or::check(cx, expr, m_recv, m_arg, recv, u_arg, span);
+                ("unwrap_or_else", [u_arg]) => match method_call(recv) {
+                    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);
+                        unnecessary_lazy_eval::check(cx, expr, recv, u_arg, "unwrap_or");
+                    },
                 },
                 _ => {},
-            },
-            ("unwrap_or_else", [u_arg]) => match method_call(recv) {
-                Some(("map", [recv, map_arg], _)) if map_unwrap_or::check(cx, expr, recv, map_arg, u_arg, msrv) => {},
-                _ => {
-                    unwrap_or_else_default::check(cx, expr, recv, u_arg);
-                    unnecessary_lazy_eval::check(cx, expr, recv, u_arg, "unwrap_or");
-                },
-            },
-            _ => {},
+            }
         }
     }
 }
@@ -2821,7 +2833,7 @@ const TRAIT_METHODS: [ShouldImplTraitCase; 30] = [
     ShouldImplTraitCase::new("std::ops::Sub", "sub",  2,  FN_HEADER,  SelfKind::Value,  OutType::Any, true),
 ];
 
-#[derive(Clone, Copy, PartialEq, Debug)]
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
 enum SelfKind {
     Value,
     Ref,
diff --git a/clippy_lints/src/methods/option_as_ref_deref.rs b/clippy_lints/src/methods/option_as_ref_deref.rs
index ba2d2914315..b50a173d835 100644
--- a/clippy_lints/src/methods/option_as_ref_deref.rs
+++ b/clippy_lints/src/methods/option_as_ref_deref.rs
@@ -19,9 +19,9 @@ pub(super) fn check<'tcx>(
     as_ref_recv: &hir::Expr<'_>,
     map_arg: &hir::Expr<'_>,
     is_mut: bool,
-    msrv: Option<&RustcVersion>,
+    msrv: Option<RustcVersion>,
 ) {
-    if !meets_msrv(msrv, &msrvs::OPTION_AS_DEREF) {
+    if !meets_msrv(msrv, msrvs::OPTION_AS_DEREF) {
         return;
     }
 
diff --git a/clippy_lints/src/methods/str_splitn.rs b/clippy_lints/src/methods/str_splitn.rs
index 52891eeed06..90651a6ba04 100644
--- a/clippy_lints/src/methods/str_splitn.rs
+++ b/clippy_lints/src/methods/str_splitn.rs
@@ -24,7 +24,7 @@ pub(super) fn check(
     self_arg: &Expr<'_>,
     pat_arg: &Expr<'_>,
     count: u128,
-    msrv: Option<&RustcVersion>,
+    msrv: Option<RustcVersion>,
 ) {
     if count < 2 || !cx.typeck_results().expr_ty_adjusted(self_arg).peel_refs().is_str() {
         return;
@@ -34,7 +34,7 @@ pub(super) fn check(
         IterUsageKind::Nth(n) => count > n + 1,
         IterUsageKind::NextTuple => count > 2,
     };
-    let manual = count == 2 && meets_msrv(msrv, &msrvs::STR_SPLIT_ONCE);
+    let manual = count == 2 && meets_msrv(msrv, msrvs::STR_SPLIT_ONCE);
 
     match parse_iter_usage(cx, expr.span.ctxt(), cx.tcx.hir().parent_iter(expr.hir_id)) {
         Some(usage) if needless(usage.kind) => lint_needless(cx, method_name, expr, self_arg, pat_arg),
@@ -271,7 +271,7 @@ enum IterUsageKind {
     NextTuple,
 }
 
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Eq)]
 enum UnwrapKind {
     Unwrap,
     QuestionMark,
diff --git a/clippy_lints/src/methods/unnecessary_to_owned.rs b/clippy_lints/src/methods/unnecessary_to_owned.rs
index 02b882e8b55..97c4feb3122 100644
--- a/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -26,7 +26,7 @@ pub fn check<'tcx>(
     expr: &'tcx Expr<'tcx>,
     method_name: Symbol,
     args: &'tcx [Expr<'tcx>],
-    msrv: Option<&RustcVersion>,
+    msrv: Option<RustcVersion>,
 ) {
     if_chain! {
         if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
@@ -65,13 +65,12 @@ fn check_addr_of_expr(
         if let Some(parent) = get_parent_expr(cx, expr);
         if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, _) = parent.kind;
         let adjustments = cx.typeck_results().expr_adjustments(parent).iter().collect::<Vec<_>>();
-        if let Some(target_ty) = match adjustments[..]
-        {
+        if let
             // For matching uses of `Cow::from`
             [
                 Adjustment {
                     kind: Adjust::Deref(None),
-                    ..
+                    target: referent_ty,
                 },
                 Adjustment {
                     kind: Adjust::Borrow(_),
@@ -82,7 +81,7 @@ fn check_addr_of_expr(
             | [
                 Adjustment {
                     kind: Adjust::Deref(None),
-                    ..
+                    target: referent_ty,
                 },
                 Adjustment {
                     kind: Adjust::Borrow(_),
@@ -97,7 +96,7 @@ fn check_addr_of_expr(
             | [
                 Adjustment {
                     kind: Adjust::Deref(None),
-                    ..
+                    target: referent_ty,
                 },
                 Adjustment {
                     kind: Adjust::Deref(Some(OverloadedDeref { .. })),
@@ -107,17 +106,24 @@ fn check_addr_of_expr(
                     kind: Adjust::Borrow(_),
                     target: target_ty,
                 },
-            ] => Some(target_ty),
-            _ => None,
-        };
+            ] = adjustments[..];
         let receiver_ty = cx.typeck_results().expr_ty(receiver);
-        // Only flag cases where the receiver is copyable or the method is `Cow::into_owned`. This
-        // restriction is to ensure there is not overlap between `redundant_clone` and this lint.
-        if is_copy(cx, receiver_ty) || is_cow_into_owned(cx, method_name, method_def_id);
+        let (target_ty, n_target_refs) = peel_mid_ty_refs(*target_ty);
+        let (receiver_ty, n_receiver_refs) = peel_mid_ty_refs(receiver_ty);
+        // Only flag cases satisfying at least one of the following three conditions:
+        // * the referent and receiver types are distinct
+        // * the referent/receiver type is a copyable array
+        // * the method is `Cow::into_owned`
+        // This restriction is to ensure there is no overlap between `redundant_clone` and this
+        // lint. It also avoids the following false positive:
+        //  https://github.com/rust-lang/rust-clippy/issues/8759
+        //   Arrays are a bit of a corner case. Non-copyable arrays are handled by
+        // `redundant_clone`, but copyable arrays are not.
+        if *referent_ty != receiver_ty
+            || (matches!(referent_ty.kind(), ty::Array(..)) && is_copy(cx, *referent_ty))
+            || is_cow_into_owned(cx, method_name, method_def_id);
         if let Some(receiver_snippet) = snippet_opt(cx, receiver.span);
         then {
-            let (target_ty, n_target_refs) = peel_mid_ty_refs(*target_ty);
-            let (receiver_ty, n_receiver_refs) = peel_mid_ty_refs(receiver_ty);
             if receiver_ty == target_ty && n_target_refs >= n_receiver_refs {
                 span_lint_and_sugg(
                     cx,
@@ -192,7 +198,7 @@ fn check_into_iter_call_arg(
     expr: &Expr<'_>,
     method_name: Symbol,
     receiver: &Expr<'_>,
-    msrv: Option<&RustcVersion>,
+    msrv: Option<RustcVersion>,
 ) -> bool {
     if_chain! {
         if let Some(parent) = get_parent_expr(cx, expr);
@@ -207,7 +213,11 @@ fn check_into_iter_call_arg(
             if unnecessary_iter_cloned::check_for_loop_iter(cx, parent, method_name, receiver, true) {
                 return true;
             }
-            let cloned_or_copied = if is_copy(cx, item_ty) && meets_msrv(msrv, &msrvs::ITERATOR_COPIED) { "copied" } else { "cloned" };
+            let cloned_or_copied = if is_copy(cx, item_ty) && meets_msrv(msrv, msrvs::ITERATOR_COPIED) {
+                "copied"
+            } else {
+                "cloned"
+            };
             // The next suggestion may be incorrect because the removal of the `to_owned`-like
             // function could cause the iterator to hold a reference to a resource that is used
             // mutably. See https://github.com/rust-lang/rust-clippy/issues/8148.
diff --git a/clippy_lints/src/methods/unwrap_used.rs b/clippy_lints/src/methods/unwrap_used.rs
index 44676d78c60..5c761014927 100644
--- a/clippy_lints/src/methods/unwrap_used.rs
+++ b/clippy_lints/src/methods/unwrap_used.rs
@@ -1,4 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::is_in_test_function;
 use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
@@ -7,7 +8,7 @@ use rustc_span::sym;
 use super::UNWRAP_USED;
 
 /// lint use of `unwrap()` for `Option`s and `Result`s
-pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {
+pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, allow_unwrap_in_tests: bool) {
     let obj_ty = cx.typeck_results().expr_ty(recv).peel_refs();
 
     let mess = if is_type_diagnostic_item(cx, obj_ty, sym::Option) {
@@ -18,6 +19,10 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
         None
     };
 
+    if allow_unwrap_in_tests && is_in_test_function(cx.tcx, expr.hir_id) {
+        return;
+    }
+
     if let Some((lint, kind, none_value)) = mess {
         span_lint_and_help(
             cx,
diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs
index ac82dd306a5..7fdc28c5a06 100644
--- a/clippy_lints/src/misc.rs
+++ b/clippy_lints/src/misc.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then};
 use clippy_utils::source::{snippet, snippet_opt};
-use clippy_utils::ty::implements_trait;
+use clippy_utils::ty::{implements_trait, is_copy};
 use if_chain::if_chain;
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
@@ -20,8 +20,8 @@ use rustc_span::symbol::sym;
 use clippy_utils::consts::{constant, Constant};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
-    get_item_name, get_parent_expr, in_constant, is_diag_trait_item, is_integer_const, iter_input_pats,
-    last_path_segment, match_any_def_paths, path_def_id, paths, unsext, SpanlessEq,
+    get_item_name, get_parent_expr, in_constant, is_integer_const, iter_input_pats, last_path_segment,
+    match_any_def_paths, path_def_id, paths, unsext, SpanlessEq,
 };
 
 declare_clippy_lint! {
@@ -548,7 +548,7 @@ fn is_array(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     matches!(&cx.typeck_results().expr_ty(expr).peel_refs().kind(), ty::Array(_, _))
 }
 
-#[allow(clippy::too_many_lines)]
+#[expect(clippy::too_many_lines)]
 fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left: bool) {
     #[derive(Default)]
     struct EqImpl {
@@ -569,33 +569,34 @@ fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left:
         })
     }
 
-    let (arg_ty, snip) = match expr.kind {
-        ExprKind::MethodCall(.., args, _) if args.len() == 1 => {
-            if_chain!(
-                if let Some(expr_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
-                if is_diag_trait_item(cx, expr_def_id, sym::ToString)
-                    || is_diag_trait_item(cx, expr_def_id, sym::ToOwned);
-                then {
-                    (cx.typeck_results().expr_ty(&args[0]), snippet(cx, args[0].span, ".."))
-                } else {
-                    return;
-                }
-            )
+    let typeck = cx.typeck_results();
+    let (arg, arg_span) = match expr.kind {
+        ExprKind::MethodCall(.., [arg], _)
+            if typeck
+                .type_dependent_def_id(expr.hir_id)
+                .and_then(|id| cx.tcx.trait_of_item(id))
+                .map_or(false, |id| {
+                    matches!(cx.tcx.get_diagnostic_name(id), Some(sym::ToString | sym::ToOwned))
+                }) =>
+        {
+            (arg, arg.span)
         },
-        ExprKind::Call(path, [arg]) => {
+        ExprKind::Call(path, [arg])
             if path_def_id(cx, path)
                 .and_then(|id| match_any_def_paths(cx, id, &[&paths::FROM_STR_METHOD, &paths::FROM_FROM]))
-                .is_some()
-            {
-                (cx.typeck_results().expr_ty(arg), snippet(cx, arg.span, ".."))
-            } else {
-                return;
-            }
+                .map_or(false, |idx| match idx {
+                    0 => true,
+                    1 => !is_copy(cx, typeck.expr_ty(expr)),
+                    _ => false,
+                }) =>
+        {
+            (arg, arg.span)
         },
         _ => return,
     };
 
-    let other_ty = cx.typeck_results().expr_ty(other);
+    let arg_ty = typeck.expr_ty(arg);
+    let other_ty = typeck.expr_ty(other);
 
     let without_deref = symmetric_partial_eq(cx, arg_ty, other_ty).unwrap_or_default();
     let with_deref = arg_ty
@@ -627,13 +628,14 @@ fn check_to_owned(cx: &LateContext<'_>, expr: &Expr<'_>, other: &Expr<'_>, left:
                 return;
             }
 
+            let arg_snip = snippet(cx, arg_span, "..");
             let expr_snip;
             let eq_impl;
             if with_deref.is_implemented() {
-                expr_snip = format!("*{}", snip);
+                expr_snip = format!("*{}", arg_snip);
                 eq_impl = with_deref;
             } else {
-                expr_snip = snip.to_string();
+                expr_snip = arg_snip.to_string();
                 eq_impl = without_deref;
             };
 
diff --git a/clippy_lints/src/missing_const_for_fn.rs b/clippy_lints/src/missing_const_for_fn.rs
index 06209bfe7b0..16d65966c10 100644
--- a/clippy_lints/src/missing_const_for_fn.rs
+++ b/clippy_lints/src/missing_const_for_fn.rs
@@ -93,7 +93,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
         span: Span,
         hir_id: HirId,
     ) {
-        if !meets_msrv(self.msrv.as_ref(), &msrvs::CONST_IF_MATCH) {
+        if !meets_msrv(self.msrv, msrvs::CONST_IF_MATCH) {
             return;
         }
 
@@ -146,7 +146,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
 
         let mir = cx.tcx.optimized_mir(def_id);
 
-        if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, self.msrv.as_ref()) {
+        if let Err((span, err)) = is_min_const_fn(cx.tcx, mir, self.msrv) {
             if cx.tcx.is_const_fn_raw(def_id.to_def_id()) {
                 cx.tcx.sess.span_err(span, err.as_ref());
             }
diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs
index a20377f320b..b99052e66ba 100644
--- a/clippy_lints/src/missing_doc.rs
+++ b/clippy_lints/src/missing_doc.rs
@@ -7,7 +7,8 @@
 
 use clippy_utils::attrs::is_doc_hidden;
 use clippy_utils::diagnostics::span_lint;
-use rustc_ast::ast;
+use if_chain::if_chain;
+use rustc_ast::ast::{self, MetaItem, MetaItemKind};
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::ty::{self, DefIdTree};
@@ -57,6 +58,20 @@ impl MissingDoc {
         *self.doc_hidden_stack.last().expect("empty doc_hidden_stack")
     }
 
+    fn has_include(meta: Option<MetaItem>) -> bool {
+        if_chain! {
+            if let Some(meta) = meta;
+            if let MetaItemKind::List(list) = meta.kind;
+            if let Some(meta) = list.get(0);
+            if let Some(name) = meta.ident();
+            then {
+                name.name == sym::include
+            } else {
+                false
+            }
+        }
+    }
+
     fn check_missing_docs_attrs(
         &self,
         cx: &LateContext<'_>,
@@ -80,7 +95,9 @@ impl MissingDoc {
             return;
         }
 
-        let has_doc = attrs.iter().any(|a| a.doc_str().is_some());
+        let has_doc = attrs
+            .iter()
+            .any(|a| a.doc_str().is_some() || Self::has_include(a.meta()));
         if !has_doc {
             span_lint(
                 cx,
diff --git a/clippy_lints/src/eval_order_dependence.rs b/clippy_lints/src/mixed_read_write_in_expression.rs
index 65599a0587d..405fc23e8de 100644
--- a/clippy_lints/src/eval_order_dependence.rs
+++ b/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -40,8 +40,8 @@ declare_clippy_lint! {
     /// let a = tmp + x;
     /// ```
     #[clippy::version = "pre 1.29.0"]
-    pub EVAL_ORDER_DEPENDENCE,
-    suspicious,
+    pub MIXED_READ_WRITE_IN_EXPRESSION,
+    restriction,
     "whether a variable read occurs before a write depends on sub-expression evaluation order"
 }
 
@@ -73,7 +73,7 @@ declare_clippy_lint! {
     "whether an expression contains a diverging sub expression"
 }
 
-declare_lint_pass!(EvalOrderDependence => [EVAL_ORDER_DEPENDENCE, DIVERGING_SUB_EXPRESSION]);
+declare_lint_pass!(EvalOrderDependence => [MIXED_READ_WRITE_IN_EXPRESSION, DIVERGING_SUB_EXPRESSION]);
 
 impl<'tcx> LateLintPass<'tcx> for EvalOrderDependence {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
@@ -303,7 +303,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> {
             if !is_in_assignment_position(self.cx, expr) {
                 span_lint_and_note(
                     self.cx,
-                    EVAL_ORDER_DEPENDENCE,
+                    MIXED_READ_WRITE_IN_EXPRESSION,
                     expr.span,
                     &format!("unsequenced read of `{}`", self.cx.tcx.hir().name(self.var)),
                     Some(self.write_expr.span),
diff --git a/clippy_lints/src/mutable_debug_assertion.rs b/clippy_lints/src/mutable_debug_assertion.rs
index cd1bc202370..8dba60f3a58 100644
--- a/clippy_lints/src/mutable_debug_assertion.rs
+++ b/clippy_lints/src/mutable_debug_assertion.rs
@@ -16,7 +16,7 @@ declare_clippy_lint! {
     /// ### Why is this bad?
     /// In release builds `debug_assert!` macros are optimized out by the
     /// compiler.
-    /// Therefore mutating something in a `debug_assert!` macro results in different behaviour
+    /// Therefore mutating something in a `debug_assert!` macro results in different behavior
     /// between a release and debug build.
     ///
     /// ### Example
@@ -92,10 +92,6 @@ impl<'a, 'tcx> Visitor<'tcx> for MutArgVisitor<'a, 'tcx> {
                 self.found = true;
                 return;
             },
-            ExprKind::If(..) => {
-                self.found = true;
-                return;
-            },
             ExprKind::Path(_) => {
                 if let Some(adj) = self.cx.typeck_results().adjustments().get(expr.hir_id) {
                     if adj
diff --git a/clippy_lints/src/needless_bitwise_bool.rs b/clippy_lints/src/needless_bitwise_bool.rs
index 95395e2e136..623d22bc9bd 100644
--- a/clippy_lints/src/needless_bitwise_bool.rs
+++ b/clippy_lints/src/needless_bitwise_bool.rs
@@ -53,7 +53,7 @@ fn is_bitwise_operation(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     false
 }
 
-fn suggesstion_snippet(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
+fn suggestion_snippet(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
     if let ExprKind::Binary(ref op, left, right) = expr.kind {
         if let (Some(l_snippet), Some(r_snippet)) = (snippet_opt(cx, left.span), snippet_opt(cx, right.span)) {
             let op_snippet = match op.node {
@@ -75,7 +75,7 @@ impl LateLintPass<'_> for NeedlessBitwiseBool {
                 expr.span,
                 "use of bitwise operator instead of lazy operator between booleans",
                 |diag| {
-                    if let Some(sugg) = suggesstion_snippet(cx, expr) {
+                    if let Some(sugg) = suggestion_snippet(cx, expr) {
                         diag.span_suggestion(expr.span, "try", sugg, Applicability::MachineApplicable);
                     }
                 },
diff --git a/clippy_lints/src/needless_pass_by_value.rs b/clippy_lints/src/needless_pass_by_value.rs
index 4034079a90c..38960103d5e 100644
--- a/clippy_lints/src/needless_pass_by_value.rs
+++ b/clippy_lints/src/needless_pass_by_value.rs
@@ -70,7 +70,7 @@ macro_rules! need {
 }
 
 impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
-    #[allow(clippy::too_many_lines)]
+    #[expect(clippy::too_many_lines)]
     fn check_fn(
         &mut self,
         cx: &LateContext<'tcx>,
diff --git a/clippy_lints/src/neg_multiply.rs b/clippy_lints/src/neg_multiply.rs
index 6ba9ba0753d..707f3b2181a 100644
--- a/clippy_lints/src/neg_multiply.rs
+++ b/clippy_lints/src/neg_multiply.rs
@@ -34,7 +34,6 @@ declare_clippy_lint! {
 
 declare_lint_pass!(NegMultiply => [NEG_MULTIPLY]);
 
-#[allow(clippy::match_same_arms)]
 impl<'tcx> LateLintPass<'tcx> for NegMultiply {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
         if let ExprKind::Binary(ref op, left, right) = e.kind {
diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs
index 2bdccb42507..093ec389335 100644
--- a/clippy_lints/src/new_without_default.rs
+++ b/clippy_lints/src/new_without_default.rs
@@ -58,7 +58,6 @@ pub struct NewWithoutDefault {
 impl_lint_pass!(NewWithoutDefault => [NEW_WITHOUT_DEFAULT]);
 
 impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
-    #[allow(clippy::too_many_lines)]
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) {
         if let hir::ItemKind::Impl(hir::Impl {
             of_trait: None,
diff --git a/clippy_lints/src/non_expressive_names.rs b/clippy_lints/src/non_expressive_names.rs
index e3bc40c4b49..7f6b535c7b1 100644
--- a/clippy_lints/src/non_expressive_names.rs
+++ b/clippy_lints/src/non_expressive_names.rs
@@ -191,7 +191,7 @@ impl<'a, 'tcx, 'b> SimilarNamesNameVisitor<'a, 'tcx, 'b> {
         }
     }
 
-    #[allow(clippy::too_many_lines)]
+    #[expect(clippy::too_many_lines)]
     fn check_ident(&mut self, ident: Ident) {
         let interned_name = ident.name.as_str();
         if interned_name.chars().any(char::is_uppercase) {
diff --git a/clippy_lints/src/pass_by_ref_or_value.rs b/clippy_lints/src/pass_by_ref_or_value.rs
index 9af3059a37f..e3ded716341 100644
--- a/clippy_lints/src/pass_by_ref_or_value.rs
+++ b/clippy_lints/src/pass_by_ref_or_value.rs
@@ -52,7 +52,7 @@ declare_clippy_lint! {
     /// to a function that needs the memory address. For further details, refer to
     /// [this issue](https://github.com/rust-lang/rust-clippy/issues/5953)
     /// that explains a real case in which this false positive
-    /// led to an **undefined behaviour** introduced with unsafe code.
+    /// led to an **undefined behavior** introduced with unsafe code.
     ///
     /// ### Example
     ///
@@ -124,7 +124,7 @@ impl<'tcx> PassByRefOrValue {
             // Cap the calculated bit width at 32-bits to reduce
             // portability problems between 32 and 64-bit targets
             let bit_width = cmp::min(bit_width, 32);
-            #[allow(clippy::integer_division)]
+            #[expect(clippy::integer_division)]
             let byte_width = bit_width / 8;
             // Use a limit of 2 times the register byte width
             byte_width * 2
diff --git a/clippy_lints/src/pattern_type_mismatch.rs b/clippy_lints/src/pattern_type_mismatch.rs
index be319ee110d..a4d265111f9 100644
--- a/clippy_lints/src/pattern_type_mismatch.rs
+++ b/clippy_lints/src/pattern_type_mismatch.rs
@@ -163,7 +163,6 @@ enum Level {
     Lower,
 }
 
-#[allow(rustc::usage_of_ty_tykind)]
 fn find_first_mismatch<'tcx>(cx: &LateContext<'tcx>, pat: &Pat<'_>) -> Option<(Span, Mutability, Level)> {
     let mut result = None;
     pat.walk(|p| {
diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs
index c35eeeac67a..86460c1b27e 100644
--- a/clippy_lints/src/ptr.rs
+++ b/clippy_lints/src/ptr.rs
@@ -514,7 +514,7 @@ fn check_mut_from_ref<'tcx>(cx: &LateContext<'tcx>, sig: &FnSig<'_>, body: Optio
     }
 }
 
-#[allow(clippy::too_many_lines)]
+#[expect(clippy::too_many_lines)]
 fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args: &[PtrArg<'tcx>]) -> Vec<PtrArgResult> {
     struct V<'cx, 'tcx> {
         cx: &'cx LateContext<'tcx>,
diff --git a/clippy_lints/src/ranges.rs b/clippy_lints/src/ranges.rs
index be7610f365c..a47dc26f603 100644
--- a/clippy_lints/src/ranges.rs
+++ b/clippy_lints/src/ranges.rs
@@ -193,7 +193,7 @@ impl<'tcx> LateLintPass<'tcx> for Ranges {
                 check_range_zip_with_len(cx, path, args, expr.span);
             },
             ExprKind::Binary(ref op, l, r) => {
-                if meets_msrv(self.msrv.as_ref(), &msrvs::RANGE_CONTAINS) {
+                if meets_msrv(self.msrv, msrvs::RANGE_CONTAINS) {
                     check_possible_range_contains(cx, op.node, l, r, expr);
                 }
             },
@@ -207,7 +207,13 @@ impl<'tcx> LateLintPass<'tcx> for Ranges {
     extract_msrv_attr!(LateContext);
 }
 
-fn check_possible_range_contains(cx: &LateContext<'_>, op: BinOpKind, l: &Expr<'_>, r: &Expr<'_>, expr: &Expr<'_>) {
+fn check_possible_range_contains(
+    cx: &LateContext<'_>,
+    op: BinOpKind,
+    left: &Expr<'_>,
+    right: &Expr<'_>,
+    expr: &Expr<'_>,
+) {
     if in_constant(cx, expr.hir_id) {
         return;
     }
@@ -219,21 +225,19 @@ fn check_possible_range_contains(cx: &LateContext<'_>, op: BinOpKind, l: &Expr<'
         _ => return,
     };
     // value, name, order (higher/lower), inclusiveness
-    if let (Some((lval, lid, name_span, lval_span, lord, linc)), Some((rval, rid, _, rval_span, rord, rinc))) =
-        (check_range_bounds(cx, l), check_range_bounds(cx, r))
-    {
+    if let (Some(l), Some(r)) = (check_range_bounds(cx, left), check_range_bounds(cx, right)) {
         // we only lint comparisons on the same name and with different
         // direction
-        if lid != rid || lord == rord {
+        if l.id != r.id || l.ord == r.ord {
             return;
         }
-        let ord = Constant::partial_cmp(cx.tcx, cx.typeck_results().expr_ty(l), &lval, &rval);
-        if combine_and && ord == Some(rord) {
+        let ord = Constant::partial_cmp(cx.tcx, cx.typeck_results().expr_ty(l.expr), &l.val, &r.val);
+        if combine_and && ord == Some(r.ord) {
             // order lower bound and upper bound
-            let (l_span, u_span, l_inc, u_inc) = if rord == Ordering::Less {
-                (lval_span, rval_span, linc, rinc)
+            let (l_span, u_span, l_inc, u_inc) = if r.ord == Ordering::Less {
+                (l.val_span, r.val_span, l.inc, r.inc)
             } else {
-                (rval_span, lval_span, rinc, linc)
+                (r.val_span, l.val_span, r.inc, l.inc)
             };
             // we only lint inclusive lower bounds
             if !l_inc {
@@ -245,7 +249,7 @@ fn check_possible_range_contains(cx: &LateContext<'_>, op: BinOpKind, l: &Expr<'
                 ("Range", "..")
             };
             let mut applicability = Applicability::MachineApplicable;
-            let name = snippet_with_applicability(cx, name_span, "_", &mut applicability);
+            let name = snippet_with_applicability(cx, l.name_span, "_", &mut applicability);
             let lo = snippet_with_applicability(cx, l_span, "_", &mut applicability);
             let hi = snippet_with_applicability(cx, u_span, "_", &mut applicability);
             let space = if lo.ends_with('.') { " " } else { "" };
@@ -258,13 +262,13 @@ fn check_possible_range_contains(cx: &LateContext<'_>, op: BinOpKind, l: &Expr<'
                 format!("({}{}{}{}).contains(&{})", lo, space, range_op, hi, name),
                 applicability,
             );
-        } else if !combine_and && ord == Some(lord) {
+        } else if !combine_and && ord == Some(l.ord) {
             // `!_.contains(_)`
             // order lower bound and upper bound
-            let (l_span, u_span, l_inc, u_inc) = if lord == Ordering::Less {
-                (lval_span, rval_span, linc, rinc)
+            let (l_span, u_span, l_inc, u_inc) = if l.ord == Ordering::Less {
+                (l.val_span, r.val_span, l.inc, r.inc)
             } else {
-                (rval_span, lval_span, rinc, linc)
+                (r.val_span, l.val_span, r.inc, l.inc)
             };
             if l_inc {
                 return;
@@ -275,7 +279,7 @@ fn check_possible_range_contains(cx: &LateContext<'_>, op: BinOpKind, l: &Expr<'
                 ("RangeInclusive", "..=")
             };
             let mut applicability = Applicability::MachineApplicable;
-            let name = snippet_with_applicability(cx, name_span, "_", &mut applicability);
+            let name = snippet_with_applicability(cx, l.name_span, "_", &mut applicability);
             let lo = snippet_with_applicability(cx, l_span, "_", &mut applicability);
             let hi = snippet_with_applicability(cx, u_span, "_", &mut applicability);
             let space = if lo.ends_with('.') { " " } else { "" };
@@ -292,7 +296,20 @@ fn check_possible_range_contains(cx: &LateContext<'_>, op: BinOpKind, l: &Expr<'
     }
 }
 
-fn check_range_bounds(cx: &LateContext<'_>, ex: &Expr<'_>) -> Option<(Constant, HirId, Span, Span, Ordering, bool)> {
+struct RangeBounds<'a> {
+    val: Constant,
+    expr: &'a Expr<'a>,
+    id: HirId,
+    name_span: Span,
+    val_span: Span,
+    ord: Ordering,
+    inc: bool,
+}
+
+// Takes a binary expression such as x <= 2 as input
+// Breaks apart into various pieces, such as the value of the number,
+// hir id of the variable, and direction/inclusiveness of the operator
+fn check_range_bounds<'a>(cx: &'a LateContext<'_>, ex: &'a Expr<'_>) -> Option<RangeBounds<'a>> {
     if let ExprKind::Binary(ref op, l, r) = ex.kind {
         let (inclusive, ordering) = match op.node {
             BinOpKind::Gt => (false, Ordering::Greater),
@@ -303,11 +320,27 @@ fn check_range_bounds(cx: &LateContext<'_>, ex: &Expr<'_>) -> Option<(Constant,
         };
         if let Some(id) = path_to_local(l) {
             if let Some((c, _)) = constant(cx, cx.typeck_results(), r) {
-                return Some((c, id, l.span, r.span, ordering, inclusive));
+                return Some(RangeBounds {
+                    val: c,
+                    expr: r,
+                    id,
+                    name_span: l.span,
+                    val_span: r.span,
+                    ord: ordering,
+                    inc: inclusive,
+                });
             }
         } else if let Some(id) = path_to_local(r) {
             if let Some((c, _)) = constant(cx, cx.typeck_results(), l) {
-                return Some((c, id, r.span, l.span, ordering.reverse(), inclusive));
+                return Some(RangeBounds {
+                    val: c,
+                    expr: l,
+                    id,
+                    name_span: r.span,
+                    val_span: l.span,
+                    ord: ordering.reverse(),
+                    inc: inclusive,
+                });
             }
         }
     }
@@ -330,7 +363,7 @@ fn check_range_zip_with_len(cx: &LateContext<'_>, path: &PathSegment<'_>, args:
         // `.iter()` and `.len()` called on same `Path`
         if let ExprKind::Path(QPath::Resolved(_, iter_path)) = iter_args[0].kind;
         if let ExprKind::Path(QPath::Resolved(_, len_path)) = len_args[0].kind;
-        if SpanlessEq::new(cx).eq_path_segments(&iter_path.segments, &len_path.segments);
+        if SpanlessEq::new(cx).eq_path_segments(iter_path.segments, len_path.segments);
         then {
             span_lint(cx,
                 RANGE_ZIP_WITH_LEN,
diff --git a/clippy_lints/src/rc_clone_in_vec_init.rs b/clippy_lints/src/rc_clone_in_vec_init.rs
new file mode 100644
index 00000000000..110f58f3734
--- /dev/null
+++ b/clippy_lints/src/rc_clone_in_vec_init.rs
@@ -0,0 +1,141 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::higher::VecArgs;
+use clippy_utils::last_path_segment;
+use clippy_utils::macros::root_macro_call_first_node;
+use clippy_utils::source::{indent_of, snippet};
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind, QPath, TyKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::{sym, Span, Symbol};
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `Arc::new` or `Rc::new` in `vec![elem; len]`
+    ///
+    /// ### Why is this bad?
+    /// This will create `elem` once and clone it `len` times - doing so with `Arc` or `Rc`
+    /// is a bit misleading, as it will create references to the same pointer, rather
+    /// than different instances.
+    ///
+    /// ### Example
+    /// ```rust
+    /// let v = vec![std::sync::Arc::new("some data".to_string()); 100];
+    /// // or
+    /// let v = vec![std::rc::Rc::new("some data".to_string()); 100];
+    /// ```
+    /// Use instead:
+    /// ```rust
+    ///
+    /// // Initialize each value separately:
+    /// let mut data = Vec::with_capacity(100);
+    /// for _ in 0..100 {
+    ///     data.push(std::rc::Rc::new("some data".to_string()));
+    /// }
+    ///
+    /// // Or if you want clones of the same reference,
+    /// // Create the reference beforehand to clarify that
+    /// // it should be cloned for each value
+    /// let data = std::rc::Rc::new("some data".to_string());
+    /// let v = vec![data; 100];
+    /// ```
+    #[clippy::version = "1.62.0"]
+    pub RC_CLONE_IN_VEC_INIT,
+    suspicious,
+    "initializing `Arc` or `Rc` in `vec![elem; len]`"
+}
+declare_lint_pass!(RcCloneInVecInit => [RC_CLONE_IN_VEC_INIT]);
+
+impl LateLintPass<'_> for RcCloneInVecInit {
+    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+        let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return; };
+        let Some(VecArgs::Repeat(elem, len)) = VecArgs::hir(cx, expr) else { return; };
+        let Some(symbol) = new_reference_call(cx, elem) else { return; };
+
+        emit_lint(cx, symbol, macro_call.span, elem, len);
+    }
+}
+
+fn elem_snippet(cx: &LateContext<'_>, elem: &Expr<'_>, symbol_name: &str) -> String {
+    let elem_snippet = snippet(cx, elem.span, "..").to_string();
+    if elem_snippet.contains('\n') {
+        // This string must be found in `elem_snippet`, otherwise we won't be constructing
+        // the snippet in the first place.
+        let reference_creation = format!("{symbol_name}::new");
+        let (code_until_reference_creation, _right) = elem_snippet.split_once(&reference_creation).unwrap();
+
+        return format!("{code_until_reference_creation}{reference_creation}(..)");
+    }
+
+    elem_snippet
+}
+
+fn loop_init_suggestion(elem: &str, len: &str, indent: &str) -> String {
+    format!(
+        r#"{{
+{indent}    let mut v = Vec::with_capacity({len});
+{indent}    (0..{len}).for_each(|_| v.push({elem}));
+{indent}    v
+{indent}}}"#
+    )
+}
+
+fn extract_suggestion(elem: &str, len: &str, indent: &str) -> String {
+    format!(
+        "{{
+{indent}    let data = {elem};
+{indent}    vec![data; {len}]
+{indent}}}"
+    )
+}
+
+fn emit_lint(cx: &LateContext<'_>, symbol: Symbol, lint_span: Span, elem: &Expr<'_>, len: &Expr<'_>) {
+    let symbol_name = symbol.as_str();
+
+    span_lint_and_then(
+        cx,
+        RC_CLONE_IN_VEC_INIT,
+        lint_span,
+        &format!("calling `{symbol_name}::new` in `vec![elem; len]`"),
+        |diag| {
+            let len_snippet = snippet(cx, len.span, "..");
+            let elem_snippet = elem_snippet(cx, elem, symbol_name);
+            let indentation = " ".repeat(indent_of(cx, lint_span).unwrap_or(0));
+            let loop_init_suggestion = loop_init_suggestion(&elem_snippet, len_snippet.as_ref(), &indentation);
+            let extract_suggestion = extract_suggestion(&elem_snippet, len_snippet.as_ref(), &indentation);
+
+            diag.note(format!("each element will point to the same `{symbol_name}` instance"));
+            diag.span_suggestion(
+                lint_span,
+                format!("consider initializing each `{symbol_name}` element individually"),
+                loop_init_suggestion,
+                Applicability::Unspecified,
+            );
+            diag.span_suggestion(
+                lint_span,
+                format!(
+                    "or if this is intentional, consider extracting the `{symbol_name}` initialization to a variable"
+                ),
+                extract_suggestion,
+                Applicability::Unspecified,
+            );
+        },
+    );
+}
+
+/// Checks whether the given `expr` is a call to `Arc::new` or `Rc::new`
+fn new_reference_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Symbol> {
+    if_chain! {
+        if let ExprKind::Call(func, _args) = expr.kind;
+        if let ExprKind::Path(ref func_path @ QPath::TypeRelative(ty, _)) = func.kind;
+        if let TyKind::Path(ref ty_path) = ty.kind;
+        if let Some(def_id) = cx.qpath_res(ty_path, ty.hir_id).opt_def_id();
+        if last_path_segment(func_path).ident.name == sym::new;
+
+        then {
+            return cx.tcx.get_diagnostic_name(def_id).filter(|symbol| symbol == &sym::Arc || symbol == &sym::Rc);
+        }
+    }
+
+    None
+}
diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs
index 37aac8b2a49..0004b8afdd3 100644
--- a/clippy_lints/src/redundant_clone.rs
+++ b/clippy_lints/src/redundant_clone.rs
@@ -19,7 +19,6 @@ use rustc_mir_dataflow::{Analysis, AnalysisDomain, CallReturnPlaces, GenKill, Ge
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::{BytePos, Span};
 use rustc_span::sym;
-use std::convert::TryFrom;
 use std::ops::ControlFlow;
 
 macro_rules! unwrap_or_continue {
@@ -71,7 +70,7 @@ declare_clippy_lint! {
 declare_lint_pass!(RedundantClone => [REDUNDANT_CLONE]);
 
 impl<'tcx> LateLintPass<'tcx> for RedundantClone {
-    #[allow(clippy::too_many_lines)]
+    #[expect(clippy::too_many_lines)]
     fn check_fn(
         &mut self,
         cx: &LateContext<'tcx>,
@@ -633,7 +632,7 @@ impl<'a, 'tcx> mir::visit::Visitor<'tcx> for PossibleBorrowerVisitor<'a, 'tcx> {
 }
 
 /// Collect possible borrowed for every `&mut` local.
-/// For exampel, `_1 = &mut _2` generate _1: {_2,...}
+/// For example, `_1 = &mut _2` generate _1: {_2,...}
 /// Known Problems: not sure all borrowed are tracked
 struct PossibleOriginVisitor<'a, 'tcx> {
     possible_origin: TransitiveRelation,
diff --git a/clippy_lints/src/redundant_field_names.rs b/clippy_lints/src/redundant_field_names.rs
index 40a62fd6d20..40b03068f6c 100644
--- a/clippy_lints/src/redundant_field_names.rs
+++ b/clippy_lints/src/redundant_field_names.rs
@@ -51,7 +51,7 @@ impl_lint_pass!(RedundantFieldNames => [REDUNDANT_FIELD_NAMES]);
 
 impl EarlyLintPass for RedundantFieldNames {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
-        if !meets_msrv(self.msrv.as_ref(), &msrvs::FIELD_INIT_SHORTHAND) {
+        if !meets_msrv(self.msrv, msrvs::FIELD_INIT_SHORTHAND) {
             return;
         }
 
diff --git a/clippy_lints/src/redundant_static_lifetimes.rs b/clippy_lints/src/redundant_static_lifetimes.rs
index ea5064217ab..2d26c49252f 100644
--- a/clippy_lints/src/redundant_static_lifetimes.rs
+++ b/clippy_lints/src/redundant_static_lifetimes.rs
@@ -99,7 +99,7 @@ impl RedundantStaticLifetimes {
 
 impl EarlyLintPass for RedundantStaticLifetimes {
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) {
-        if !meets_msrv(self.msrv.as_ref(), &msrvs::STATIC_IN_CONST) {
+        if !meets_msrv(self.msrv, msrvs::STATIC_IN_CONST) {
             return;
         }
 
diff --git a/clippy_lints/src/reference.rs b/clippy_lints/src/reference.rs
index 811a7bb9c15..f789cec6d6a 100644
--- a/clippy_lints/src/reference.rs
+++ b/clippy_lints/src/reference.rs
@@ -54,13 +54,12 @@ impl EarlyLintPass for DerefAddrOf {
             then {
                 let mut applicability = Applicability::MachineApplicable;
                 let sugg = if e.span.from_expansion() {
-                    #[allow(clippy::option_if_let_else)]
                     if let Some(macro_source) = snippet_opt(cx, e.span) {
                         // Remove leading whitespace from the given span
                         // e.g: ` $visitor` turns into `$visitor`
                         let trim_leading_whitespaces = |span| {
                             snippet_opt(cx, span).and_then(|snip| {
-                                #[allow(clippy::cast_possible_truncation)]
+                                #[expect(clippy::cast_possible_truncation)]
                                 snip.find(|c: char| !c.is_whitespace()).map(|pos| {
                                     span.lo() + BytePos(pos as u32)
                                 })
@@ -68,7 +67,7 @@ impl EarlyLintPass for DerefAddrOf {
                         };
 
                         let mut generate_snippet = |pattern: &str| {
-                            #[allow(clippy::cast_possible_truncation)]
+                            #[expect(clippy::cast_possible_truncation)]
                             macro_source.rfind(pattern).map(|pattern_pos| {
                                 let rpos = pattern_pos + pattern.len();
                                 let span_after_ref = e.span.with_lo(BytePos(e.span.lo().0 + rpos as u32));
diff --git a/clippy_lints/src/regex.rs b/clippy_lints/src/regex.rs
index a92097e1d24..67129299e2f 100644
--- a/clippy_lints/src/regex.rs
+++ b/clippy_lints/src/regex.rs
@@ -7,7 +7,6 @@ use rustc_hir::{BorrowKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::{BytePos, Span};
-use std::convert::TryFrom;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -79,7 +78,6 @@ impl<'tcx> LateLintPass<'tcx> for Regex {
     }
 }
 
-#[allow(clippy::cast_possible_truncation)] // truncation very unlikely here
 #[must_use]
 fn str_span(base: Span, c: regex_syntax::ast::Span, offset: u8) -> Span {
     let offset = u32::from(offset);
diff --git a/clippy_lints/src/renamed_lints.rs b/clippy_lints/src/renamed_lints.rs
index bfc03116fe2..ba03ef93721 100644
--- a/clippy_lints/src/renamed_lints.rs
+++ b/clippy_lints/src/renamed_lints.rs
@@ -9,6 +9,7 @@ pub static RENAMED_LINTS: &[(&str, &str)] = &[
     ("clippy::cyclomatic_complexity", "clippy::cognitive_complexity"),
     ("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", "clippy::for_loops_over_fallibles"),
     ("clippy::for_loop_over_result", "clippy::for_loops_over_fallibles"),
     ("clippy::identity_conversion", "clippy::useless_conversion"),
diff --git a/clippy_lints/src/same_name_method.rs b/clippy_lints/src/same_name_method.rs
index c5c174cc8f6..9158cbcc04e 100644
--- a/clippy_lints/src/same_name_method.rs
+++ b/clippy_lints/src/same_name_method.rs
@@ -54,11 +54,11 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
             if matches!(cx.tcx.def_kind(id.def_id), DefKind::Impl)
                 && let item = cx.tcx.hir().item(id)
                 && let ItemKind::Impl(Impl {
-                  items,
-                  of_trait,
-                  self_ty,
-                  ..
-                                      }) = &item.kind
+                    items,
+                    of_trait,
+                    self_ty,
+                    ..
+                }) = &item.kind
                 && let TyKind::Path(QPath::Resolved(_, Path { res, .. })) = self_ty.kind
             {
                 if !map.contains_key(res) {
diff --git a/clippy_lints/src/tabs_in_doc_comments.rs b/clippy_lints/src/tabs_in_doc_comments.rs
index 15543b6a262..e223aea297f 100644
--- a/clippy_lints/src/tabs_in_doc_comments.rs
+++ b/clippy_lints/src/tabs_in_doc_comments.rs
@@ -4,7 +4,6 @@ use rustc_errors::Applicability;
 use rustc_lint::{EarlyContext, EarlyLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::{BytePos, Span};
-use std::convert::TryFrom;
 
 declare_clippy_lint! {
     /// ### What it does
diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs
index 911da3997ae..6c60fb4b8e0 100644
--- a/clippy_lints/src/trait_bounds.rs
+++ b/clippy_lints/src/trait_bounds.rs
@@ -36,7 +36,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.38.0"]
     pub TYPE_REPETITION_IN_BOUNDS,
-    pedantic,
+    nursery,
     "Types are repeated unnecessary in trait bounds use `+` instead of using `T: _, T: _`"
 }
 
@@ -66,7 +66,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.47.0"]
     pub TRAIT_DUPLICATION_IN_BOUNDS,
-    pedantic,
+    nursery,
     "Check if the same trait bounds are specified twice during a function declaration"
 }
 
diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs
index 342f23f030c..d2a040beb0c 100644
--- a/clippy_lints/src/transmute/mod.rs
+++ b/clippy_lints/src/transmute/mod.rs
@@ -27,7 +27,7 @@ declare_clippy_lint! {
     /// architecture.
     ///
     /// ### Why is this bad?
-    /// It's basically guaranteed to be undefined behaviour.
+    /// It's basically guaranteed to be undefined behavior.
     ///
     /// ### Known problems
     /// When accessing C, users might want to store pointer
@@ -40,7 +40,7 @@ declare_clippy_lint! {
     #[clippy::version = "pre 1.29.0"]
     pub WRONG_TRANSMUTE,
     correctness,
-    "transmutes that are confusing at best, undefined behaviour at worst and always useless"
+    "transmutes that are confusing at best, undefined behavior at worst and always useless"
 }
 
 // FIXME: Move this to `complexity` again, after #5343 is fixed
diff --git a/clippy_lints/src/types/redundant_allocation.rs b/clippy_lints/src/types/redundant_allocation.rs
index 10d2ae2eb1d..a1312fcda0b 100644
--- a/clippy_lints/src/types/redundant_allocation.rs
+++ b/clippy_lints/src/types/redundant_allocation.rs
@@ -5,6 +5,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{self as hir, def_id::DefId, QPath, TyKind};
 use rustc_lint::LateContext;
 use rustc_span::symbol::sym;
+use rustc_typeck::hir_ty_to_ty;
 
 use super::{utils, REDUNDANT_ALLOCATION};
 
@@ -54,8 +55,10 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
     };
     let inner_span = match qpath_generic_tys(inner_qpath).next() {
         Some(ty) => {
-            // Box<Box<dyn T>> is smaller than Box<dyn T> because of wide pointers
-            if matches!(ty.kind, TyKind::TraitObject(..)) {
+            // 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.at(ty.span), cx.param_env) {
                 return false;
             }
             ty.span
diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs
index 465d8a914fb..5a8677f90be 100644
--- a/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -1,17 +1,18 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::is_lint_allowed;
 use clippy_utils::source::walk_span_to_context;
+use clippy_utils::{get_parent_node, is_lint_allowed};
 use rustc_data_structures::sync::Lrc;
-use rustc_hir::{Block, BlockCheckMode, UnsafeSource};
+use rustc_hir as hir;
+use rustc_hir::{Block, BlockCheckMode, ItemKind, Node, UnsafeSource};
 use rustc_lexer::{tokenize, TokenKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::{BytePos, Pos, SyntaxContext};
+use rustc_span::{BytePos, Pos, Span, SyntaxContext};
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks for `unsafe` blocks without a `// SAFETY: ` comment
+    /// Checks for `unsafe` blocks and impls without a `// SAFETY: ` comment
     /// explaining why the unsafe operations performed inside
     /// the block are safe.
     ///
@@ -34,7 +35,7 @@ declare_clippy_lint! {
     /// ```
     ///
     /// ### Why is this bad?
-    /// Undocumented unsafe blocks can make it difficult to
+    /// Undocumented unsafe blocks and impls can make it difficult to
     /// read and maintain code, as well as uncover unsoundness
     /// and bugs.
     ///
@@ -66,7 +67,7 @@ impl LateLintPass<'_> for UndocumentedUnsafeBlocks {
         if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)
             && !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)
+            && !is_unsafe_from_proc_macro(cx, block.span)
             && !block_has_safety_comment(cx, block)
         {
             let source_map = cx.tcx.sess.source_map();
@@ -86,11 +87,37 @@ impl LateLintPass<'_> for UndocumentedUnsafeBlocks {
             );
         }
     }
+
+    fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
+        if let hir::ItemKind::Impl(imple) = item.kind
+            && imple.unsafety == hir::Unsafety::Unsafe
+            && !in_external_macro(cx.tcx.sess, item.span)
+            && !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, item.hir_id())
+            && !is_unsafe_from_proc_macro(cx, item.span)
+            && !item_has_safety_comment(cx, item)
+        {
+            let source_map = cx.tcx.sess.source_map();
+            let span = if source_map.is_multiline(item.span) {
+                source_map.span_until_char(item.span, '\n')
+            } else {
+                item.span
+            };
+
+            span_lint_and_help(
+                cx,
+                UNDOCUMENTED_UNSAFE_BLOCKS,
+                span,
+                "unsafe impl missing a safety comment",
+                None,
+                "consider adding a safety comment on the preceding line",
+            );
+        }
+    }
 }
 
-fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, block: &Block<'_>) -> bool {
+fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, span: Span) -> bool {
     let source_map = cx.sess().source_map();
-    let file_pos = source_map.lookup_byte_offset(block.span.lo());
+    let file_pos = source_map.lookup_byte_offset(span.lo());
     file_pos
         .sf
         .src
@@ -100,7 +127,7 @@ fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, block: &Block<'_>) -> bool {
 }
 
 /// Checks if the lines immediately preceding the block contain a safety comment.
-fn block_has_safety_comment(cx: &LateContext<'_>, block: &Block<'_>) -> bool {
+fn block_has_safety_comment(cx: &LateContext<'_>, block: &hir::Block<'_>) -> bool {
     // This intentionally ignores text before the start of a function so something like:
     // ```
     //     // SAFETY: reason
@@ -109,13 +136,115 @@ fn block_has_safety_comment(cx: &LateContext<'_>, block: &Block<'_>) -> bool {
     // 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)
+}
+
+/// Checks if the lines immediately preceding the item contain a safety comment.
+#[allow(clippy::collapsible_match)]
+fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> bool {
+    if span_from_macro_expansion_has_safety_comment(cx, item.span) {
+        return true;
+    }
+
+    if item.span.ctxt() == SyntaxContext::root() {
+        if let Some(parent_node) = get_parent_node(cx.tcx, item.hir_id()) {
+            let comment_start = match parent_node {
+                Node::Crate(parent_mod) => {
+                    comment_start_before_impl_in_mod(cx, parent_mod, parent_mod.spans.inner_span, item)
+                },
+                Node::Item(parent_item) => {
+                    if let ItemKind::Mod(parent_mod) = &parent_item.kind {
+                        comment_start_before_impl_in_mod(cx, parent_mod, parent_item.span, item)
+                    } else {
+                        // Doesn't support impls in this position. Pretend a comment was found.
+                        return true;
+                    }
+                },
+                Node::Stmt(stmt) => {
+                    if let Some(stmt_parent) = get_parent_node(cx.tcx, stmt.hir_id) {
+                        match stmt_parent {
+                            Node::Block(block) => walk_span_to_context(block.span, SyntaxContext::root()).map(Span::lo),
+                            _ => {
+                                // Doesn't support impls in this position. Pretend a comment was found.
+                                return true;
+                            },
+                        }
+                    } else {
+                        // Problem getting the parent node. Pretend a comment was found.
+                        return true;
+                    }
+                },
+                _ => {
+                    // Doesn't support impls in this position. Pretend a comment was found.
+                    return true;
+                },
+            };
+
+            let source_map = cx.sess().source_map();
+            if let Some(comment_start) = comment_start
+                && let Ok(unsafe_line) = source_map.lookup_line(item.span.lo())
+                && let Ok(comment_start_line) = source_map.lookup_line(comment_start)
+                && Lrc::ptr_eq(&unsafe_line.sf, &comment_start_line.sf)
+                && let Some(src) = unsafe_line.sf.src.as_deref()
+            {
+                comment_start_line.line < unsafe_line.line && text_has_safety_comment(
+                    src,
+                    &unsafe_line.sf.lines[comment_start_line.line + 1..=unsafe_line.line],
+                    unsafe_line.sf.start_pos.to_usize(),
+                )
+            } else {
+                // Problem getting source text. Pretend a comment was found.
+                true
+            }
+        } else {
+            // No parent node. Pretend a comment was found.
+            true
+        }
+    } else {
+        false
+    }
+}
+
+fn comment_start_before_impl_in_mod(
+    cx: &LateContext<'_>,
+    parent_mod: &hir::Mod<'_>,
+    parent_mod_span: Span,
+    imple: &hir::Item<'_>,
+) -> Option<BytePos> {
+    parent_mod.item_ids.iter().enumerate().find_map(|(idx, item_id)| {
+        if *item_id == imple.item_id() {
+            if idx == 0 {
+                // mod A { /* comment */ unsafe impl T {} ... }
+                // ^------------------------------------------^ returns the start of this span
+                // ^---------------------^ finally checks comments in this range
+                if let Some(sp) = walk_span_to_context(parent_mod_span, SyntaxContext::root()) {
+                    return Some(sp.lo());
+                }
+            } else {
+                // some_item /* comment */ unsafe impl T {}
+                // ^-------^ returns the end of this span
+                //         ^---------------^ finally checks comments in this range
+                let prev_item = cx.tcx.hir().item(parent_mod.item_ids[idx - 1]);
+                if let Some(sp) = walk_span_to_context(prev_item.span, SyntaxContext::root()) {
+                    return Some(sp.hi());
+                }
+            }
+        }
+        None
+    })
+}
+
+fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
     let source_map = cx.sess().source_map();
-    let ctxt = block.span.ctxt();
-    if ctxt != SyntaxContext::root() {
-        // From a macro expansion. Get the text from the start of the macro declaration to start of the unsafe block.
+    let ctxt = span.ctxt();
+    if ctxt == SyntaxContext::root() {
+        false
+    } else {
+        // From a macro expansion. Get the text from the start of the macro declaration to start of the
+        // unsafe block.
         //     macro_rules! foo { () => { stuff }; (x) => { unsafe { stuff } }; }
         //     ^--------------------------------------------^
-        if let Ok(unsafe_line) = source_map.lookup_line(block.span.lo())
+        if let Ok(unsafe_line) = source_map.lookup_line(span.lo())
             && let Ok(macro_line) = source_map.lookup_line(ctxt.outer_expn_data().def_site.lo())
             && Lrc::ptr_eq(&unsafe_line.sf, &macro_line.sf)
             && let Some(src) = unsafe_line.sf.src.as_deref()
@@ -129,24 +258,35 @@ fn block_has_safety_comment(cx: &LateContext<'_>, block: &Block<'_>) -> bool {
             // Problem getting source text. Pretend a comment was found.
             true
         }
-    } else if let Ok(unsafe_line) = source_map.lookup_line(block.span.lo())
+    }
+}
+
+fn span_in_body_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
+    let source_map = cx.sess().source_map();
+    let ctxt = span.ctxt();
+    if ctxt == SyntaxContext::root()
         && let Some(body) = cx.enclosing_body
-        && let Some(body_span) = walk_span_to_context(cx.tcx.hir().body(body).value.span, SyntaxContext::root())
-        && let Ok(body_line) = source_map.lookup_line(body_span.lo())
-        && Lrc::ptr_eq(&unsafe_line.sf, &body_line.sf)
-        && let Some(src) = unsafe_line.sf.src.as_deref()
     {
-        // Get the text from the start of function body to the unsafe block.
-        //     fn foo() { some_stuff; unsafe { stuff }; other_stuff; }
-        //              ^-------------^
-        body_line.line < unsafe_line.line && text_has_safety_comment(
-            src,
-            &unsafe_line.sf.lines[body_line.line + 1..=unsafe_line.line],
-            unsafe_line.sf.start_pos.to_usize(),
-        )
+        if let Ok(unsafe_line) = source_map.lookup_line(span.lo())
+            && let Some(body_span) = walk_span_to_context(cx.tcx.hir().body(body).value.span, SyntaxContext::root())
+            && let Ok(body_line) = source_map.lookup_line(body_span.lo())
+            && Lrc::ptr_eq(&unsafe_line.sf, &body_line.sf)
+            && let Some(src) = unsafe_line.sf.src.as_deref()
+        {
+            // Get the text from the start of function body to the unsafe block.
+            //     fn foo() { some_stuff; unsafe { stuff }; other_stuff; }
+            //              ^-------------^
+            body_line.line < unsafe_line.line && text_has_safety_comment(
+                src,
+                &unsafe_line.sf.lines[body_line.line + 1..=unsafe_line.line],
+                unsafe_line.sf.start_pos.to_usize(),
+            )
+        } else {
+            // Problem getting source text. Pretend a comment was found.
+            true
+        }
     } else {
-        // Problem getting source text. Pretend a comment was found.
-        true
+        false
     }
 }
 
diff --git a/clippy_lints/src/uninit_vec.rs b/clippy_lints/src/uninit_vec.rs
index 6d909c34690..9f4c5555f11 100644
--- a/clippy_lints/src/uninit_vec.rs
+++ b/clippy_lints/src/uninit_vec.rs
@@ -98,7 +98,7 @@ fn handle_uninit_vec_pair<'tcx>(
                 // Check T of Vec<T>
                 if !is_uninit_value_valid_for_ty(cx, substs.type_at(0)) {
                     // FIXME: #7698, false positive of the internal lints
-                    #[allow(clippy::collapsible_span_lint_calls)]
+                    #[expect(clippy::collapsible_span_lint_calls)]
                     span_lint_and_then(
                         cx,
                         UNINIT_VEC,
diff --git a/clippy_lints/src/unit_types/let_unit_value.rs b/clippy_lints/src/unit_types/let_unit_value.rs
index f3f1f53aac5..d86002c926e 100644
--- a/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/clippy_lints/src/unit_types/let_unit_value.rs
@@ -3,6 +3,7 @@ use clippy_utils::source::snippet_with_macro_callsite;
 use clippy_utils::visitors::for_each_value_source;
 use core::ops::ControlFlow;
 use rustc_errors::Applicability;
+use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Expr, ExprKind, PatKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
@@ -71,14 +72,18 @@ fn needs_inferred_result_ty(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
                 ..
             },
             _,
-        ) => cx.qpath_res(path, *hir_id).opt_def_id(),
-        ExprKind::MethodCall(..) => cx.typeck_results().type_dependent_def_id(e.hir_id),
+        ) => match cx.qpath_res(path, *hir_id) {
+            Res::Def(DefKind::AssocFn | DefKind::Fn, id) => id,
+            _ => return false,
+        },
+        ExprKind::MethodCall(..) => match cx.typeck_results().type_dependent_def_id(e.hir_id) {
+            Some(id) => id,
+            None => return false,
+        },
         _ => return false,
     };
-    if let Some(id) = id
-        && let sig = cx.tcx.fn_sig(id).skip_binder()
-        && let ty::Param(output_ty) = *sig.output().kind()
-    {
+    let sig = cx.tcx.fn_sig(id).skip_binder();
+    if let ty::Param(output_ty) = *sig.output().kind() {
         sig.inputs().iter().all(|&ty| !ty_contains_param(ty, output_ty.index))
     } else {
         false
diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs
index ae431aac83b..04e2f301bfd 100644
--- a/clippy_lints/src/unnested_or_patterns.rs
+++ b/clippy_lints/src/unnested_or_patterns.rs
@@ -61,13 +61,13 @@ impl_lint_pass!(UnnestedOrPatterns => [UNNESTED_OR_PATTERNS]);
 
 impl EarlyLintPass for UnnestedOrPatterns {
     fn check_arm(&mut self, cx: &EarlyContext<'_>, a: &ast::Arm) {
-        if meets_msrv(self.msrv.as_ref(), &msrvs::OR_PATTERNS) {
+        if meets_msrv(self.msrv, msrvs::OR_PATTERNS) {
             lint_unnested_or_patterns(cx, &a.pat);
         }
     }
 
     fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
-        if meets_msrv(self.msrv.as_ref(), &msrvs::OR_PATTERNS) {
+        if meets_msrv(self.msrv, msrvs::OR_PATTERNS) {
             if let ast::ExprKind::Let(pat, _, _) = &e.kind {
                 lint_unnested_or_patterns(cx, pat);
             }
@@ -75,13 +75,13 @@ impl EarlyLintPass for UnnestedOrPatterns {
     }
 
     fn check_param(&mut self, cx: &EarlyContext<'_>, p: &ast::Param) {
-        if meets_msrv(self.msrv.as_ref(), &msrvs::OR_PATTERNS) {
+        if meets_msrv(self.msrv, msrvs::OR_PATTERNS) {
             lint_unnested_or_patterns(cx, &p.pat);
         }
     }
 
     fn check_local(&mut self, cx: &EarlyContext<'_>, l: &ast::Local) {
-        if meets_msrv(self.msrv.as_ref(), &msrvs::OR_PATTERNS) {
+        if meets_msrv(self.msrv, msrvs::OR_PATTERNS) {
             lint_unnested_or_patterns(cx, &l.pat);
         }
     }
diff --git a/clippy_lints/src/unused_unit.rs b/clippy_lints/src/unused_unit.rs
index bfd17a68749..52585e59566 100644
--- a/clippy_lints/src/unused_unit.rs
+++ b/clippy_lints/src/unused_unit.rs
@@ -130,7 +130,7 @@ fn lint_unneeded_unit_return(cx: &EarlyContext<'_>, ty: &ast::Ty, span: Span) {
         snippet_opt(cx, span.with_hi(ty.span.hi())).map_or((ty.span, Applicability::MaybeIncorrect), |fn_source| {
             position_before_rarrow(&fn_source).map_or((ty.span, Applicability::MaybeIncorrect), |rpos| {
                 (
-                    #[allow(clippy::cast_possible_truncation)]
+                    #[expect(clippy::cast_possible_truncation)]
                     ty.span.with_lo(BytePos(span.lo().0 + rpos as u32)),
                     Applicability::MachineApplicable,
                 )
diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs
index 138f8bccb3f..66f7748e9e0 100644
--- a/clippy_lints/src/use_self.rs
+++ b/clippy_lints/src/use_self.rs
@@ -198,7 +198,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
     fn check_ty(&mut self, cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) {
         if_chain! {
             if !hir_ty.span.from_expansion();
-            if meets_msrv(self.msrv.as_ref(), &msrvs::TYPE_ALIAS_ENUM_VARIANTS);
+            if meets_msrv(self.msrv, msrvs::TYPE_ALIAS_ENUM_VARIANTS);
             if let Some(&StackItem::Check {
                 impl_id,
                 in_body,
@@ -225,7 +225,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
         if_chain! {
             if !expr.span.from_expansion();
-            if meets_msrv(self.msrv.as_ref(), &msrvs::TYPE_ALIAS_ENUM_VARIANTS);
+            if meets_msrv(self.msrv, msrvs::TYPE_ALIAS_ENUM_VARIANTS);
             if let Some(&StackItem::Check { impl_id, .. }) = self.stack.last();
             if cx.typeck_results().expr_ty(expr) == cx.tcx.type_of(impl_id);
             then {} else { return; }
@@ -256,7 +256,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
     fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) {
         if_chain! {
             if !pat.span.from_expansion();
-            if meets_msrv(self.msrv.as_ref(), &msrvs::TYPE_ALIAS_ENUM_VARIANTS);
+            if meets_msrv(self.msrv, msrvs::TYPE_ALIAS_ENUM_VARIANTS);
             if let Some(&StackItem::Check { impl_id, .. }) = self.stack.last();
             if let PatKind::Path(QPath::Resolved(_, path)) = pat.kind;
             if !matches!(path.res, Res::SelfTy { .. } | Res::Def(DefKind::TyParam, _));
diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs
index abd8a362370..4a3b5383c89 100644
--- a/clippy_lints/src/useless_conversion.rs
+++ b/clippy_lints/src/useless_conversion.rs
@@ -41,7 +41,7 @@ pub struct UselessConversion {
 
 impl_lint_pass!(UselessConversion => [USELESS_CONVERSION]);
 
-#[allow(clippy::too_many_lines)]
+#[expect(clippy::too_many_lines)]
 impl<'tcx> LateLintPass<'tcx> for UselessConversion {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
         if e.span.from_expansion() {
diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs
index 74b0168a179..cd4d16fe95f 100644
--- a/clippy_lints/src/utils/conf.rs
+++ b/clippy_lints/src/utils/conf.rs
@@ -6,7 +6,8 @@ use serde::de::{Deserializer, IgnoredAny, IntoDeserializer, MapAccess, Visitor};
 use serde::Deserialize;
 use std::error::Error;
 use std::path::{Path, PathBuf};
-use std::{env, fmt, fs, io};
+use std::str::FromStr;
+use std::{cmp, env, fmt, fs, io, iter};
 
 /// Holds information used by `MISSING_ENFORCED_IMPORT_RENAMES` lint.
 #[derive(Clone, Debug, Deserialize)]
@@ -43,18 +44,33 @@ pub enum DisallowedType {
 #[derive(Default)]
 pub struct TryConf {
     pub conf: Conf,
-    pub errors: Vec<String>,
+    pub errors: Vec<Box<dyn Error>>,
 }
 
 impl TryConf {
-    fn from_error(error: impl Error) -> Self {
+    fn from_error(error: impl Error + 'static) -> Self {
         Self {
             conf: Conf::default(),
-            errors: vec![error.to_string()],
+            errors: vec![Box::new(error)],
         }
     }
 }
 
+#[derive(Debug)]
+struct ConfError(String);
+
+impl fmt::Display for ConfError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        <String as fmt::Display>::fmt(&self.0, f)
+    }
+}
+
+impl Error for ConfError {}
+
+fn conf_error(s: String) -> Box<dyn Error> {
+    Box::new(ConfError(s))
+}
+
 macro_rules! define_Conf {
     ($(
         $(#[doc = $doc:literal])+
@@ -103,11 +119,11 @@ macro_rules! define_Conf {
                 while let Some(name) = map.next_key::<&str>()? {
                     match Field::deserialize(name.into_deserializer())? {
                         $(Field::$name => {
-                            $(errors.push(format!("deprecated field `{}`. {}", name, $dep));)?
+                            $(errors.push(conf_error(format!("deprecated field `{}`. {}", name, $dep)));)?
                             match map.next_value() {
-                                Err(e) => errors.push(e.to_string()),
+                                Err(e) => errors.push(conf_error(e.to_string())),
                                 Ok(value) => match $name {
-                                    Some(_) => errors.push(format!("duplicate field `{}`", name)),
+                                    Some(_) => errors.push(conf_error(format!("duplicate field `{}`", name))),
                                     None => $name = Some(value),
                                 }
                             }
@@ -316,6 +332,14 @@ define_Conf! {
     ///
     /// The maximum size of a file included via `include_bytes!()` or `include_str!()`, in bytes
     (max_include_file_size: u64 = 1_000_000),
+    /// Lint: EXPECT_USED.
+    ///
+    /// Whether `expect` should be allowed in test functions
+    (allow_expect_in_tests: bool = false),
+    /// Lint: UNWRAP_USED.
+    ///
+    /// Whether `unwrap` should be allowed in test functions
+    (allow_unwrap_in_tests: bool = false),
 }
 
 /// Search for the configuration file.
@@ -375,3 +399,102 @@ pub fn read(path: &Path) -> TryConf {
     };
     toml::from_str(&content).unwrap_or_else(TryConf::from_error)
 }
+
+const SEPARATOR_WIDTH: usize = 4;
+
+// Check whether the error is "unknown field" and, if so, list the available fields sorted and at
+// least one per line, more if `CLIPPY_TERMINAL_WIDTH` is set and allows it.
+pub fn format_error(error: Box<dyn Error>) -> String {
+    let s = error.to_string();
+
+    if_chain! {
+        if error.downcast::<toml::de::Error>().is_ok();
+        if let Some((prefix, mut fields, suffix)) = parse_unknown_field_message(&s);
+        then {
+            use fmt::Write;
+
+            fields.sort_unstable();
+
+            let (rows, column_widths) = calculate_dimensions(&fields);
+
+            let mut msg = String::from(prefix);
+            for row in 0..rows {
+                write!(msg, "\n").unwrap();
+                for (column, column_width) in column_widths.iter().copied().enumerate() {
+                    let index = column * rows + row;
+                    let field = fields.get(index).copied().unwrap_or_default();
+                    write!(
+                        msg,
+                        "{:separator_width$}{:field_width$}",
+                        " ",
+                        field,
+                        separator_width = SEPARATOR_WIDTH,
+                        field_width = column_width
+                    )
+                    .unwrap();
+                }
+            }
+            write!(msg, "\n{}", suffix).unwrap();
+            msg
+        } else {
+            s
+        }
+    }
+}
+
+// `parse_unknown_field_message` will become unnecessary if
+// https://github.com/alexcrichton/toml-rs/pull/364 is merged.
+fn parse_unknown_field_message(s: &str) -> Option<(&str, Vec<&str>, &str)> {
+    // An "unknown field" message has the following form:
+    //   unknown field `UNKNOWN`, expected one of `FIELD0`, `FIELD1`, ..., `FIELDN` at line X column Y
+    //                                           ^^      ^^^^                     ^^
+    if_chain! {
+        if s.starts_with("unknown field");
+        let slices = s.split("`, `").collect::<Vec<_>>();
+        let n = slices.len();
+        if n >= 2;
+        if let Some((prefix, first_field)) = slices[0].rsplit_once(" `");
+        if let Some((last_field, suffix)) = slices[n - 1].split_once("` ");
+        then {
+            let fields = iter::once(first_field)
+                .chain(slices[1..n - 1].iter().copied())
+                .chain(iter::once(last_field))
+                .collect::<Vec<_>>();
+            Some((prefix, fields, suffix))
+        } else {
+            None
+        }
+    }
+}
+
+fn calculate_dimensions(fields: &[&str]) -> (usize, Vec<usize>) {
+    let columns = env::var("CLIPPY_TERMINAL_WIDTH")
+        .ok()
+        .and_then(|s| <usize as FromStr>::from_str(&s).ok())
+        .map_or(1, |terminal_width| {
+            let max_field_width = fields.iter().map(|field| field.len()).max().unwrap();
+            cmp::max(1, terminal_width / (SEPARATOR_WIDTH + max_field_width))
+        });
+
+    let rows = (fields.len() + (columns - 1)) / columns;
+
+    let column_widths = (0..columns)
+        .map(|column| {
+            if column < columns - 1 {
+                (0..rows)
+                    .map(|row| {
+                        let index = column * rows + row;
+                        let field = fields.get(index).copied().unwrap_or_default();
+                        field.len()
+                    })
+                    .max()
+                    .unwrap()
+            } else {
+                // Avoid adding extra space to the last column.
+                0
+            }
+        })
+        .collect::<Vec<_>>();
+
+    (rows, column_widths)
+}
diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs
index 79e7410c3a8..ba1ff65479d 100644
--- a/clippy_lints/src/vec.rs
+++ b/clippy_lints/src/vec.rs
@@ -12,7 +12,7 @@ use rustc_middle::ty::{self, Ty};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::source_map::Span;
 
-#[allow(clippy::module_name_repetitions)]
+#[expect(clippy::module_name_repetitions)]
 #[derive(Copy, Clone)]
 pub struct UselessVec {
     pub too_large_for_stack: u64,
@@ -83,7 +83,7 @@ impl UselessVec {
         let snippet = match *vec_args {
             higher::VecArgs::Repeat(elem, len) => {
                 if let Some((Constant::Int(len_constant), _)) = constant(cx, cx.typeck_results(), len) {
-                    #[allow(clippy::cast_possible_truncation)]
+                    #[expect(clippy::cast_possible_truncation)]
                     if len_constant as u64 * size_of(cx, elem) > self.too_large_for_stack {
                         return;
                     }
@@ -110,7 +110,6 @@ impl UselessVec {
             },
             higher::VecArgs::Vec(args) => {
                 if let Some(last) = args.iter().last() {
-                    #[allow(clippy::cast_possible_truncation)]
                     if args.len() as u64 * size_of(cx, last) > self.too_large_for_stack {
                         return;
                     }
diff --git a/clippy_lints/src/vec_init_then_push.rs b/clippy_lints/src/vec_init_then_push.rs
index fbf2b3e081b..35db45e2b0c 100644
--- a/clippy_lints/src/vec_init_then_push.rs
+++ b/clippy_lints/src/vec_init_then_push.rs
@@ -1,19 +1,30 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::higher::{get_vec_init_kind, VecInitKind};
 use clippy_utils::source::snippet;
-use clippy_utils::{path_to_local, path_to_local_id};
-use if_chain::if_chain;
+use clippy_utils::visitors::for_each_local_use_after_expr;
+use clippy_utils::{get_parent_expr, path_to_local_id};
+use core::ops::ControlFlow;
 use rustc_errors::Applicability;
-use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, Local, PatKind, Stmt, StmtKind};
+use rustc_hir::def::Res;
+use rustc_hir::{
+    BindingAnnotation, Block, Expr, ExprKind, HirId, Local, Mutability, PatKind, QPath, Stmt, StmtKind, UnOp,
+};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::Span;
+use rustc_span::{Span, Symbol};
 
 declare_clippy_lint! {
     /// ### What it does
     /// Checks for calls to `push` immediately after creating a new `Vec`.
     ///
+    /// If the `Vec` is created using `with_capacity` this will only lint if the capacity is a
+    /// constant and the number of pushes is greater than or equal to the initial capacity.
+    ///
+    /// If the `Vec` is extended after the initial sequence of pushes and it was default initialized
+    /// then this will only lint after there were at least four pushes. This number may change in
+    /// the future.
+    ///
     /// ### Why is this bad?
     /// The `vec![]` macro is both more performant and easier to read than
     /// multiple `push` calls.
@@ -43,26 +54,88 @@ pub struct VecInitThenPush {
 struct VecPushSearcher {
     local_id: HirId,
     init: VecInitKind,
-    lhs_is_local: bool,
-    lhs_span: Span,
+    lhs_is_let: bool,
+    let_ty_span: Option<Span>,
+    name: Symbol,
     err_span: Span,
-    found: u64,
+    found: u128,
+    last_push_expr: HirId,
 }
 impl VecPushSearcher {
     fn display_err(&self, cx: &LateContext<'_>) {
-        match self.init {
+        let required_pushes_before_extension = match self.init {
             _ if self.found == 0 => return,
-            VecInitKind::WithLiteralCapacity(x) if x > self.found => return,
+            VecInitKind::WithConstCapacity(x) if x > self.found => return,
+            VecInitKind::WithConstCapacity(x) => x,
             VecInitKind::WithExprCapacity(_) => return,
-            _ => (),
+            _ => 3,
         };
 
-        let mut s = if self.lhs_is_local {
+        let mut needs_mut = false;
+        let res = for_each_local_use_after_expr(cx, self.local_id, self.last_push_expr, |e| {
+            let Some(parent) = get_parent_expr(cx, e) else {
+                return ControlFlow::Continue(())
+            };
+            let adjusted_ty = cx.typeck_results().expr_ty_adjusted(e);
+            let adjusted_mut = adjusted_ty.ref_mutability().unwrap_or(Mutability::Not);
+            needs_mut |= adjusted_mut == Mutability::Mut;
+            match parent.kind {
+                ExprKind::AddrOf(_, Mutability::Mut, _) => {
+                    needs_mut = true;
+                    return ControlFlow::Break(true);
+                },
+                ExprKind::Unary(UnOp::Deref, _) | ExprKind::Index(..) if !needs_mut => {
+                    let mut last_place = parent;
+                    while let Some(parent) = get_parent_expr(cx, parent) {
+                        if matches!(parent.kind, ExprKind::Unary(UnOp::Deref, _) | ExprKind::Field(..))
+                            || matches!(parent.kind, ExprKind::Index(e, _) if e.hir_id == last_place.hir_id)
+                        {
+                            last_place = parent;
+                        } else {
+                            break;
+                        }
+                    }
+                    needs_mut |= cx.typeck_results().expr_ty_adjusted(last_place).ref_mutability()
+                        == Some(Mutability::Mut)
+                        || get_parent_expr(cx, last_place)
+                            .map_or(false, |e| matches!(e.kind, ExprKind::AddrOf(_, Mutability::Mut, _)));
+                },
+                ExprKind::MethodCall(_, [recv, ..], _)
+                    if recv.hir_id == e.hir_id
+                        && adjusted_mut == Mutability::Mut
+                        && !adjusted_ty.peel_refs().is_slice() =>
+                {
+                    // No need to set `needs_mut` to true. The receiver will be either explicitly borrowed, or it will
+                    // be implicitly borrowed via an adjustment. Both of these cases are already handled by this point.
+                    return ControlFlow::Break(true);
+                },
+                ExprKind::Assign(lhs, ..) if e.hir_id == lhs.hir_id => {
+                    needs_mut = true;
+                    return ControlFlow::Break(false);
+                },
+                _ => (),
+            }
+            ControlFlow::Continue(())
+        });
+
+        // Avoid allocating small `Vec`s when they'll be extended right after.
+        if res == ControlFlow::Break(true) && self.found <= required_pushes_before_extension {
+            return;
+        }
+
+        let mut s = if self.lhs_is_let {
             String::from("let ")
         } else {
             String::new()
         };
-        s.push_str(&snippet(cx, self.lhs_span, ".."));
+        if needs_mut {
+            s.push_str("mut ");
+        }
+        s.push_str(self.name.as_str());
+        if let Some(span) = self.let_ty_span {
+            s.push_str(": ");
+            s.push_str(&snippet(cx, span, "_"));
+        }
         s.push_str(" = vec![..];");
 
         span_lint_and_sugg(
@@ -83,60 +156,63 @@ impl<'tcx> LateLintPass<'tcx> for VecInitThenPush {
     }
 
     fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) {
-        if_chain! {
-            if !in_external_macro(cx.sess(), local.span);
-            if let Some(init) = local.init;
-            if let PatKind::Binding(BindingAnnotation::Mutable, id, _, None) = local.pat.kind;
-            if let Some(init_kind) = get_vec_init_kind(cx, init);
-            then {
-                self.searcher = Some(VecPushSearcher {
-                        local_id: id,
-                        init: init_kind,
-                        lhs_is_local: true,
-                        lhs_span: local.ty.map_or(local.pat.span, |t| local.pat.span.to(t.span)),
-                        err_span: local.span,
-                        found: 0,
-                    });
-            }
+        if let Some(init_expr) = local.init
+            && let PatKind::Binding(BindingAnnotation::Mutable, id, name, None) = local.pat.kind
+            && !in_external_macro(cx.sess(), local.span)
+            && let Some(init) = get_vec_init_kind(cx, init_expr)
+            && !matches!(init, VecInitKind::WithExprCapacity(_))
+        {
+            self.searcher = Some(VecPushSearcher {
+                local_id: id,
+                init,
+                lhs_is_let: true,
+                name: name.name,
+                let_ty_span: local.ty.map(|ty| ty.span),
+                err_span: local.span,
+                found: 0,
+                last_push_expr: init_expr.hir_id,
+            });
         }
     }
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if_chain! {
-            if self.searcher.is_none();
-            if !in_external_macro(cx.sess(), expr.span);
-            if let ExprKind::Assign(left, right, _) = expr.kind;
-            if let Some(id) = path_to_local(left);
-            if let Some(init_kind) = get_vec_init_kind(cx, right);
-            then {
-                self.searcher = Some(VecPushSearcher {
-                    local_id: id,
-                    init: init_kind,
-                    lhs_is_local: false,
-                    lhs_span: left.span,
-                    err_span: expr.span,
-                    found: 0,
-                });
-            }
+        if self.searcher.is_none()
+            && let ExprKind::Assign(left, right, _) = expr.kind
+            && let ExprKind::Path(QPath::Resolved(None, path)) = left.kind
+            && let [name] = &path.segments
+            && let Res::Local(id) = path.res
+            && !in_external_macro(cx.sess(), expr.span)
+            && let Some(init) = get_vec_init_kind(cx, right)
+            && !matches!(init, VecInitKind::WithExprCapacity(_))
+        {
+            self.searcher = Some(VecPushSearcher {
+                local_id: id,
+                init,
+                lhs_is_let: false,
+                let_ty_span: None,
+                name: name.ident.name,
+                err_span: expr.span,
+                found: 0,
+                last_push_expr: expr.hir_id,
+            });
         }
     }
 
     fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
         if let Some(searcher) = self.searcher.take() {
-            if_chain! {
-                if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = stmt.kind;
-                if let ExprKind::MethodCall(path, [self_arg, _], _) = expr.kind;
-                if path_to_local_id(self_arg, searcher.local_id);
-                if path.ident.name.as_str() == "push";
-                then {
-                    self.searcher = Some(VecPushSearcher {
-                        found: searcher.found + 1,
-                        err_span: searcher.err_span.to(stmt.span),
-                        .. searcher
-                    });
-                } else {
-                    searcher.display_err(cx);
-                }
+            if let StmtKind::Expr(expr) | StmtKind::Semi(expr) = stmt.kind
+                && let ExprKind::MethodCall(name, [self_arg, _], _) = expr.kind
+                && path_to_local_id(self_arg, searcher.local_id)
+                && name.ident.as_str() == "push"
+            {
+                self.searcher = Some(VecPushSearcher {
+                    found: searcher.found + 1,
+                    err_span: searcher.err_span.to(stmt.span),
+                    last_push_expr: expr.hir_id,
+                    .. searcher
+                });
+            } else {
+                searcher.display_err(cx);
             }
         }
     }
diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs
index 54b93a20a05..d2493c055a5 100644
--- a/clippy_lints/src/write.rs
+++ b/clippy_lints/src/write.rs
@@ -342,8 +342,6 @@ impl EarlyLintPass for Write {
             if let (Some(fmt_str), expr) = self.check_tts(cx, mac.args.inner_tokens(), true) {
                 if fmt_str.symbol == kw::Empty {
                     let mut applicability = Applicability::MachineApplicable;
-                    // FIXME: remove this `#[allow(...)]` once the issue #5822 gets fixed
-                    #[allow(clippy::option_if_let_else)]
                     let suggestion = if let Some(e) = expr {
                         snippet_with_applicability(cx, e.span, "v", &mut applicability)
                     } else {
@@ -528,7 +526,6 @@ impl Write {
     /// ```rust,ignore
     /// (Some("string to write: {}"), Some(buf))
     /// ```
-    #[allow(clippy::too_many_lines)]
     fn check_tts<'a>(&self, cx: &EarlyContext<'a>, tts: TokenStream, is_write: bool) -> (Option<StrLit>, Option<Expr>) {
         let mut parser = parser::Parser::new(&cx.sess().parse_sess, tts, false, None);
         let expr = if is_write {