about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-04-04 17:50:22 +0000
committerbors <bors@rust-lang.org>2024-04-04 17:50:22 +0000
commit9725c4a162502a02c1c67fdca6b797fe09b2b73c (patch)
tree6c46b3f31a18f2773ae2683c588898c4fa4d9415
parent5a9e9b0e65d27bb294a5e13ca554878b43af6224 (diff)
parentbb023e90d8dfbdee714aa33cfa44b91753a99a03 (diff)
downloadrust-9725c4a162502a02c1c67fdca6b797fe09b2b73c.tar.gz
rust-9725c4a162502a02c1c67fdca6b797fe09b2b73c.zip
Auto merge of #12632 - flip1995:rustup, r=flip1995
Rustup

r? `@ghost`

changelog: none
-rw-r--r--book/src/development/type_checking.md10
-rw-r--r--clippy_config/src/conf.rs5
-rw-r--r--clippy_config/src/msrvs.rs4
-rw-r--r--clippy_lints/src/assigning_clones.rs2
-rw-r--r--clippy_lints/src/attrs/duplicated_attributes.rs4
-rw-r--r--clippy_lints/src/box_default.rs4
-rw-r--r--clippy_lints/src/casts/as_ptr_cast_mut.rs11
-rw-r--r--clippy_lints/src/casts/cast_ptr_alignment.rs10
-rw-r--r--clippy_lints/src/casts/cast_slice_different_sizes.rs2
-rw-r--r--clippy_lints/src/casts/cast_slice_from_raw_parts.rs4
-rw-r--r--clippy_lints/src/casts/ptr_as_ptr.rs6
-rw-r--r--clippy_lints/src/casts/ptr_cast_constness.rs12
-rw-r--r--clippy_lints/src/casts/ref_as_ptr.rs6
-rw-r--r--clippy_lints/src/casts/unnecessary_cast.rs4
-rw-r--r--clippy_lints/src/cognitive_complexity.rs4
-rw-r--r--clippy_lints/src/collection_is_never_read.rs6
-rw-r--r--clippy_lints/src/derive.rs5
-rw-r--r--clippy_lints/src/equatable_if_let.rs2
-rw-r--r--clippy_lints/src/eta_reduction.rs6
-rw-r--r--clippy_lints/src/float_literal.rs11
-rw-r--r--clippy_lints/src/from_raw_with_void_ptr.rs4
-rw-r--r--clippy_lints/src/functions/misnamed_getters.rs4
-rw-r--r--clippy_lints/src/functions/must_use.rs4
-rw-r--r--clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs2
-rw-r--r--clippy_lints/src/future_not_send.rs2
-rw-r--r--clippy_lints/src/ignored_unit_patterns.rs2
-rw-r--r--clippy_lints/src/implicit_hasher.rs4
-rw-r--r--clippy_lints/src/implied_bounds_in_impls.rs4
-rw-r--r--clippy_lints/src/index_refutable_slice.rs4
-rw-r--r--clippy_lints/src/iter_without_into_iter.rs4
-rw-r--r--clippy_lints/src/len_zero.rs8
-rw-r--r--clippy_lints/src/let_underscore.rs4
-rw-r--r--clippy_lints/src/let_with_type_underscore.rs4
-rw-r--r--clippy_lints/src/loops/explicit_iter_loop.rs6
-rw-r--r--clippy_lints/src/loops/same_item_push.rs2
-rw-r--r--clippy_lints/src/loops/utils.rs4
-rw-r--r--clippy_lints/src/loops/while_let_loop.rs4
-rw-r--r--clippy_lints/src/loops/while_let_on_iterator.rs4
-rw-r--r--clippy_lints/src/manual_hash_one.rs4
-rw-r--r--clippy_lints/src/manual_rem_euclid.rs2
-rw-r--r--clippy_lints/src/matches/infallible_destructuring_match.rs6
-rw-r--r--clippy_lints/src/matches/match_as_ref.rs2
-rw-r--r--clippy_lints/src/matches/match_same_arms.rs2
-rw-r--r--clippy_lints/src/matches/match_single_binding.rs2
-rw-r--r--clippy_lints/src/matches/mod.rs4
-rw-r--r--clippy_lints/src/matches/needless_match.rs4
-rw-r--r--clippy_lints/src/matches/redundant_guards.rs2
-rw-r--r--clippy_lints/src/matches/significant_drop_in_scrutinee.rs2
-rw-r--r--clippy_lints/src/methods/clone_on_copy.rs2
-rw-r--r--clippy_lints/src/methods/iter_kv_map.rs5
-rw-r--r--clippy_lints/src/methods/iter_on_single_or_empty_collections.rs2
-rw-r--r--clippy_lints/src/methods/needless_collect.rs6
-rw-r--r--clippy_lints/src/methods/readonly_write_lock.rs2
-rw-r--r--clippy_lints/src/methods/str_splitn.rs6
-rw-r--r--clippy_lints/src/methods/unnecessary_fold.rs2
-rw-r--r--clippy_lints/src/methods/unnecessary_to_owned.rs18
-rw-r--r--clippy_lints/src/methods/zst_offset.rs2
-rw-r--r--clippy_lints/src/misc.rs4
-rw-r--r--clippy_lints/src/missing_doc.rs4
-rw-r--r--clippy_lints/src/mixed_read_write_in_expression.rs4
-rw-r--r--clippy_lints/src/mut_key.rs2
-rw-r--r--clippy_lints/src/mut_reference.rs5
-rw-r--r--clippy_lints/src/mutex_atomic.rs2
-rw-r--r--clippy_lints/src/needless_late_init.rs10
-rw-r--r--clippy_lints/src/non_send_fields_in_send_ty.rs4
-rw-r--r--clippy_lints/src/pattern_type_mismatch.rs6
-rw-r--r--clippy_lints/src/ptr.rs2
-rw-r--r--clippy_lints/src/question_mark.rs17
-rw-r--r--clippy_lints/src/raw_strings.rs6
-rw-r--r--clippy_lints/src/read_zero_byte_vec.rs4
-rw-r--r--clippy_lints/src/redundant_else.rs2
-rw-r--r--clippy_lints/src/redundant_locals.rs4
-rw-r--r--clippy_lints/src/redundant_type_annotations.rs2
-rw-r--r--clippy_lints/src/reserve_after_initialization.rs4
-rw-r--r--clippy_lints/src/shadow.rs6
-rw-r--r--clippy_lints/src/significant_drop_tightening.rs4
-rw-r--r--clippy_lints/src/size_of_in_element_count.rs4
-rw-r--r--clippy_lints/src/suspicious_operation_groupings.rs2
-rw-r--r--clippy_lints/src/swap.rs4
-rw-r--r--clippy_lints/src/transmute/crosspointer_transmute.rs6
-rw-r--r--clippy_lints/src/transmute/missing_transmute_annotations.rs6
-rw-r--r--clippy_lints/src/transmute/transmute_ptr_to_ptr.rs4
-rw-r--r--clippy_lints/src/transmute/transmute_ptr_to_ref.rs4
-rw-r--r--clippy_lints/src/transmute/transmute_ref_to_ref.rs18
-rw-r--r--clippy_lints/src/transmute/transmute_undefined_repr.rs18
-rw-r--r--clippy_lints/src/transmute/useless_transmute.rs15
-rw-r--r--clippy_lints/src/transmute/utils.rs6
-rw-r--r--clippy_lints/src/transmute/wrong_transmute.rs2
-rw-r--r--clippy_lints/src/tuple_array_conversions.rs4
-rw-r--r--clippy_lints/src/types/mod.rs4
-rw-r--r--clippy_lints/src/types/redundant_allocation.rs6
-rw-r--r--clippy_lints/src/types/vec_box.rs6
-rw-r--r--clippy_lints/src/unconditional_recursion.rs4
-rw-r--r--clippy_lints/src/undocumented_unsafe_blocks.rs10
-rw-r--r--clippy_lints/src/uninhabited_references.rs4
-rw-r--r--clippy_lints/src/unit_types/let_unit_value.rs6
-rw-r--r--clippy_lints/src/unit_types/mod.rs4
-rw-r--r--clippy_lints/src/unnested_or_patterns.rs2
-rw-r--r--clippy_lints/src/unused_io_amount.rs2
-rw-r--r--clippy_lints/src/unused_peekable.rs4
-rw-r--r--clippy_lints/src/use_self.rs6
-rw-r--r--clippy_lints/src/utils/author.rs7
-rw-r--r--clippy_lints/src/utils/internal_lints/metadata_collector.rs6
-rw-r--r--clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs2
-rw-r--r--clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs4
-rw-r--r--clippy_lints/src/vec.rs6
-rw-r--r--clippy_lints/src/vec_init_then_push.rs4
-rw-r--r--clippy_lints/src/zero_repeat_side_effects.rs2
-rw-r--r--clippy_lints/src/zero_sized_map_values.rs4
-rw-r--r--clippy_utils/src/ast_utils.rs2
-rw-r--r--clippy_utils/src/consts.rs12
-rw-r--r--clippy_utils/src/higher.rs4
-rw-r--r--clippy_utils/src/hir_utils.rs6
-rw-r--r--clippy_utils/src/lib.rs52
-rw-r--r--clippy_utils/src/qualify_min_const_fn.rs6
-rw-r--r--clippy_utils/src/ty.rs12
-rw-r--r--clippy_utils/src/ty/type_certainty/mod.rs2
-rw-r--r--clippy_utils/src/visitors.rs4
-rw-r--r--rust-toolchain2
-rw-r--r--tests/ui-toml/needless_raw_string_hashes_one_allowed/clippy.toml1
-rw-r--r--tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.fixed9
-rw-r--r--tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs9
-rw-r--r--tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.stderr40
-rw-r--r--tests/ui/builtin_type_shadow.stderr1
-rw-r--r--tests/ui/crashes/ice-6179.rs2
-rw-r--r--tests/ui/use_self.fixed1
-rw-r--r--tests/ui/use_self.rs1
-rw-r--r--tests/ui/use_self.stderr86
128 files changed, 417 insertions, 376 deletions
diff --git a/book/src/development/type_checking.md b/book/src/development/type_checking.md
index 136b3fd0270..e6da4322a17 100644
--- a/book/src/development/type_checking.md
+++ b/book/src/development/type_checking.md
@@ -118,10 +118,10 @@ Here the HIR sees the types without "thinking" about them, it knows that the fun
 an `u32`. As far as `hir::Ty` is concerned those might be different types. But at the `ty::Ty` level the compiler
 understands that they're the same type, in-depth lifetimes, etc...
 
-To get from a `hir::Ty` to a `ty::Ty`, you can use the [`hir_ty_to_ty`][hir_ty_to_ty] function outside of bodies or
+To get from a `hir::Ty` to a `ty::Ty`, you can use the [`lower_ty`][lower_ty] function outside of bodies or
 the [`TypeckResults::node_type()`][node_type] method inside of bodies.
 
-> **Warning**: Don't use `hir_ty_to_ty` inside of bodies, because this can cause ICEs.
+> **Warning**: Don't use `lower_ty` inside of bodies, because this can cause ICEs.
 
 ## Creating Types programmatically
 
@@ -162,6 +162,6 @@ in this chapter:
 [Ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
 [TyKind]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_type_ir/ty_kind/enum.TyKind.html
 [TypeckResults]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TypeckResults.html
-[middle_ty]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_middle/ty/struct.Ty.html
-[hir_ty]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir/struct.Ty.html
-[hir_ty_to_ty]: https://doc.rust-lang.org/beta/nightly-rustc/rustc_hir_analysis/fn.hir_ty_to_ty.html
+[middle_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html
+[hir_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/struct.Ty.html
+[lower_ty]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir_analysis/fn.lower_ty.html
diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs
index 3b5de2c16ff..53c10f7cee8 100644
--- a/clippy_config/src/conf.rs
+++ b/clippy_config/src/conf.rs
@@ -857,11 +857,6 @@ mod tests {
         }
 
         assert!(
-            names.remove("allow-one-hash-in-raw-strings"),
-            "remove this when #11481 is fixed"
-        );
-
-        assert!(
             names.is_empty(),
             "Configuration variable lacks test: {names:?}\nAdd a test to `tests/ui-toml`"
         );
diff --git a/clippy_config/src/msrvs.rs b/clippy_config/src/msrvs.rs
index 32107ded305..59dd5b334b8 100644
--- a/clippy_config/src/msrvs.rs
+++ b/clippy_config/src/msrvs.rs
@@ -143,13 +143,13 @@ impl Msrv {
         None
     }
 
-    pub fn enter_lint_attrs(&mut self, sess: &Session, attrs: &[Attribute]) {
+    pub fn check_attributes(&mut self, sess: &Session, attrs: &[Attribute]) {
         if let Some(version) = Self::parse_attr(sess, attrs) {
             self.stack.push(version);
         }
     }
 
-    pub fn exit_lint_attrs(&mut self, sess: &Session, attrs: &[Attribute]) {
+    pub fn check_attributes_post(&mut self, sess: &Session, attrs: &[Attribute]) {
         if Self::parse_attr(sess, attrs).is_some() {
             self.stack.pop();
         }
diff --git a/clippy_lints/src/assigning_clones.rs b/clippy_lints/src/assigning_clones.rs
index e1e7d406cd0..dc7f44af2b7 100644
--- a/clippy_lints/src/assigning_clones.rs
+++ b/clippy_lints/src/assigning_clones.rs
@@ -163,7 +163,7 @@ fn is_ok_to_suggest<'tcx>(cx: &LateContext<'tcx>, lhs: &Expr<'tcx>, call: &CallC
         // TODO: This check currently bails if the local variable has no initializer.
         // That is overly conservative - the lint should fire even if there was no initializer,
         // but the variable has been initialized before `lhs` was evaluated.
-        if let Some(Node::Local(local)) = cx.tcx.hir().parent_id_iter(local).next().map(|p| cx.tcx.hir_node(p))
+        if let Some(Node::LetStmt(local)) = cx.tcx.hir().parent_id_iter(local).next().map(|p| cx.tcx.hir_node(p))
             && local.init.is_none()
         {
             return false;
diff --git a/clippy_lints/src/attrs/duplicated_attributes.rs b/clippy_lints/src/attrs/duplicated_attributes.rs
index d0ccfc4c36d..3a8844d0754 100644
--- a/clippy_lints/src/attrs/duplicated_attributes.rs
+++ b/clippy_lints/src/attrs/duplicated_attributes.rs
@@ -25,7 +25,6 @@ fn emit_if_duplicated(
     }
 }
 
-#[allow(clippy::needless_return)]
 fn check_duplicated_attr(
     cx: &EarlyContext<'_>,
     attr: &MetaItem,
@@ -49,7 +48,8 @@ fn check_duplicated_attr(
         // FIXME: We don't correctly check `cfg`s for now, so if it's more complex than just a one
         // level `cfg`, we leave.
         return;
-    } else if let Some(value) = attr.value_str() {
+    }
+    if let Some(value) = attr.value_str() {
         emit_if_duplicated(cx, attr, attr_paths, format!("{}:{name}={value}", parent.join(":")));
     } else if let Some(sub_attrs) = attr.meta_item_list() {
         parent.push(name.as_str().to_string());
diff --git a/clippy_lints/src/box_default.rs b/clippy_lints/src/box_default.rs
index c7b0006c8cb..4062212f408 100644
--- a/clippy_lints/src/box_default.rs
+++ b/clippy_lints/src/box_default.rs
@@ -5,7 +5,7 @@ use clippy_utils::{is_default_equivalent, path_def_id};
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::intravisit::{walk_ty, Visitor};
-use rustc_hir::{Block, Expr, ExprKind, Local, Node, QPath, Ty, TyKind};
+use rustc_hir::{Block, Expr, ExprKind, LetStmt, Node, QPath, Ty, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
@@ -102,7 +102,7 @@ impl<'tcx> Visitor<'tcx> for InferVisitor {
 
 fn given_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     match cx.tcx.parent_hir_node(expr.hir_id) {
-        Node::Local(Local { ty: Some(ty), .. }) => {
+        Node::LetStmt(LetStmt { ty: Some(ty), .. }) => {
             let mut v = InferVisitor::default();
             v.visit_ty(ty);
             !v.0
diff --git a/clippy_lints/src/casts/as_ptr_cast_mut.rs b/clippy_lints/src/casts/as_ptr_cast_mut.rs
index 2209ae3cad9..f05fd3fcde5 100644
--- a/clippy_lints/src/casts/as_ptr_cast_mut.rs
+++ b/clippy_lints/src/casts/as_ptr_cast_mut.rs
@@ -4,18 +4,13 @@ use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
 use rustc_middle::mir::Mutability;
-use rustc_middle::ty::{self, Ty, TypeAndMut};
+use rustc_middle::ty::{self, Ty};
 
 use super::AS_PTR_CAST_MUT;
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>) {
-    if let ty::RawPtr(TypeAndMut {
-        mutbl: Mutability::Mut,
-        ty: ptrty,
-    }) = cast_to.kind()
-        && let ty::RawPtr(TypeAndMut {
-            mutbl: Mutability::Not, ..
-        }) = cx.typeck_results().node_type(cast_expr.hir_id).kind()
+    if let ty::RawPtr(ptrty, Mutability::Mut) = cast_to.kind()
+        && let ty::RawPtr(_, Mutability::Not) = cx.typeck_results().node_type(cast_expr.hir_id).kind()
         && let ExprKind::MethodCall(method_name, receiver, [], _) = cast_expr.peel_blocks().kind
         && method_name.ident.name == rustc_span::sym::as_ptr
         && let Some(as_ptr_did) = cx
diff --git a/clippy_lints/src/casts/cast_ptr_alignment.rs b/clippy_lints/src/casts/cast_ptr_alignment.rs
index 83fe324fc7e..960c81045e3 100644
--- a/clippy_lints/src/casts/cast_ptr_alignment.rs
+++ b/clippy_lints/src/casts/cast_ptr_alignment.rs
@@ -33,13 +33,13 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
 }
 
 fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_from: Ty<'tcx>, cast_to: Ty<'tcx>) {
-    if let ty::RawPtr(from_ptr_ty) = &cast_from.kind()
-        && let ty::RawPtr(to_ptr_ty) = &cast_to.kind()
-        && let Ok(from_layout) = cx.layout_of(from_ptr_ty.ty)
-        && let Ok(to_layout) = cx.layout_of(to_ptr_ty.ty)
+    if let ty::RawPtr(from_ptr_ty, _) = *cast_from.kind()
+        && let ty::RawPtr(to_ptr_ty, _) = *cast_to.kind()
+        && let Ok(from_layout) = cx.layout_of(from_ptr_ty)
+        && let Ok(to_layout) = cx.layout_of(to_ptr_ty)
         && from_layout.align.abi < to_layout.align.abi
         // with c_void, we inherently need to trust the user
-        && !is_c_void(cx, from_ptr_ty.ty)
+        && !is_c_void(cx, from_ptr_ty)
         // when casting from a ZST, we don't know enough to properly lint
         && !from_layout.is_zst()
         && !is_used_as_unaligned(cx, expr)
diff --git a/clippy_lints/src/casts/cast_slice_different_sizes.rs b/clippy_lints/src/casts/cast_slice_different_sizes.rs
index 79dbc99bbf3..285f0357112 100644
--- a/clippy_lints/src/casts/cast_slice_different_sizes.rs
+++ b/clippy_lints/src/casts/cast_slice_different_sizes.rs
@@ -87,7 +87,7 @@ fn is_child_of_cast(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
 /// the type is one of those slices
 fn get_raw_slice_ty_mut(ty: Ty<'_>) -> Option<TypeAndMut<'_>> {
     match ty.kind() {
-        ty::RawPtr(TypeAndMut { ty: slice_ty, mutbl }) => match slice_ty.kind() {
+        ty::RawPtr(slice_ty, mutbl) => match slice_ty.kind() {
             ty::Slice(ty) => Some(TypeAndMut { ty: *ty, mutbl: *mutbl }),
             _ => None,
         },
diff --git a/clippy_lints/src/casts/cast_slice_from_raw_parts.rs b/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
index c70adc544d4..1d89f6c75e1 100644
--- a/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
+++ b/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
@@ -25,8 +25,8 @@ fn raw_parts_kind(cx: &LateContext<'_>, did: DefId) -> Option<RawPartsKind> {
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>, msrv: &Msrv) {
     if msrv.meets(msrvs::PTR_SLICE_RAW_PARTS)
-        && let ty::RawPtr(ptrty) = cast_to.kind()
-        && let ty::Slice(_) = ptrty.ty.kind()
+        && let ty::RawPtr(ptrty, _) = cast_to.kind()
+        && let ty::Slice(_) = ptrty.kind()
         && let ExprKind::Call(fun, [ptr_arg, len_arg]) = cast_expr.peel_blocks().kind
         && let ExprKind::Path(ref qpath) = fun.kind
         && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()
diff --git a/clippy_lints/src/casts/ptr_as_ptr.rs b/clippy_lints/src/casts/ptr_as_ptr.rs
index 16de9313685..68841076f77 100644
--- a/clippy_lints/src/casts/ptr_as_ptr.rs
+++ b/clippy_lints/src/casts/ptr_as_ptr.rs
@@ -6,7 +6,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, Mutability, QPath, TyKind};
 use rustc_hir_pretty::qpath_to_string;
 use rustc_lint::LateContext;
-use rustc_middle::ty::{self, TypeAndMut};
+use rustc_middle::ty;
 use rustc_span::sym;
 
 use super::PTR_AS_PTR;
@@ -33,8 +33,8 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) {
 
     if let ExprKind::Cast(cast_expr, cast_to_hir_ty) = expr.kind
         && let (cast_from, cast_to) = (cx.typeck_results().expr_ty(cast_expr), cx.typeck_results().expr_ty(expr))
-        && let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, .. }) = cast_from.kind()
-        && let ty::RawPtr(TypeAndMut { ty: to_pointee_ty, mutbl: to_mutbl }) = cast_to.kind()
+        && let ty::RawPtr(_, from_mutbl) = cast_from.kind()
+        && let ty::RawPtr(to_pointee_ty, to_mutbl) = cast_to.kind()
         && matches!((from_mutbl, to_mutbl),
             (Mutability::Not, Mutability::Not) | (Mutability::Mut, Mutability::Mut))
         // The `U` in `pointer::cast` have to be `Sized`
diff --git a/clippy_lints/src/casts/ptr_cast_constness.rs b/clippy_lints/src/casts/ptr_cast_constness.rs
index c807788b7bc..921693567fc 100644
--- a/clippy_lints/src/casts/ptr_cast_constness.rs
+++ b/clippy_lints/src/casts/ptr_cast_constness.rs
@@ -4,7 +4,7 @@ use clippy_utils::sugg::Sugg;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, Mutability};
 use rustc_lint::LateContext;
-use rustc_middle::ty::{self, Ty, TypeAndMut};
+use rustc_middle::ty::{self, Ty};
 
 use super::PTR_CAST_CONSTNESS;
 
@@ -17,14 +17,8 @@ pub(super) fn check<'tcx>(
     msrv: &Msrv,
 ) {
     if msrv.meets(msrvs::POINTER_CAST_CONSTNESS)
-        && let ty::RawPtr(TypeAndMut {
-            mutbl: from_mutbl,
-            ty: from_ty,
-        }) = cast_from.kind()
-        && let ty::RawPtr(TypeAndMut {
-            mutbl: to_mutbl,
-            ty: to_ty,
-        }) = cast_to.kind()
+        && let ty::RawPtr(from_ty, from_mutbl) = cast_from.kind()
+        && let ty::RawPtr(to_ty, to_mutbl) = cast_to.kind()
         && matches!(
             (from_mutbl, to_mutbl),
             (Mutability::Not, Mutability::Mut) | (Mutability::Mut, Mutability::Not)
diff --git a/clippy_lints/src/casts/ref_as_ptr.rs b/clippy_lints/src/casts/ref_as_ptr.rs
index 9d5a486336d..f42bafce4dd 100644
--- a/clippy_lints/src/casts/ref_as_ptr.rs
+++ b/clippy_lints/src/casts/ref_as_ptr.rs
@@ -5,7 +5,7 @@ use clippy_utils::{expr_use_ctxt, is_no_std_crate, ExprUseNode};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, Mutability, Ty, TyKind};
 use rustc_lint::LateContext;
-use rustc_middle::ty::{self, TypeAndMut};
+use rustc_middle::ty;
 
 use super::REF_AS_PTR;
 
@@ -21,10 +21,10 @@ pub(super) fn check<'tcx>(
     );
 
     if matches!(cast_from.kind(), ty::Ref(..))
-        && let ty::RawPtr(TypeAndMut { mutbl: to_mutbl, .. }) = cast_to.kind()
+        && let ty::RawPtr(_, to_mutbl) = cast_to.kind()
         && let Some(use_cx) = expr_use_ctxt(cx, expr)
         // TODO: only block the lint if `cast_expr` is a temporary
-        && !matches!(use_cx.node, ExprUseNode::Local(_) | ExprUseNode::ConstStatic(_))
+        && !matches!(use_cx.node, ExprUseNode::LetStmt(_) | ExprUseNode::ConstStatic(_))
     {
         let core_or_std = if is_no_std_crate(cx) { "core" } else { "std" };
         let fn_name = match to_mutbl {
diff --git a/clippy_lints/src/casts/unnecessary_cast.rs b/clippy_lints/src/casts/unnecessary_cast.rs
index d63f5ac6655..a7f7bf7854e 100644
--- a/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/clippy_lints/src/casts/unnecessary_cast.rs
@@ -66,7 +66,7 @@ pub(super) fn check<'tcx>(
         && let QPath::Resolved(None, Path { res, .. }) = qpath
         && let Res::Local(hir_id) = res
         && let parent = cx.tcx.parent_hir_node(*hir_id)
-        && let Node::Local(local) = parent
+        && let Node::LetStmt(local) = parent
     {
         if let Some(ty) = local.ty
             && let TyKind::Path(qpath) = ty.kind
@@ -275,7 +275,7 @@ fn is_cast_from_ty_alias<'tcx>(cx: &LateContext<'tcx>, expr: impl Visitable<'tcx
                 }
             // Local usage
             } else if let Res::Local(hir_id) = res
-                && let Node::Local(l) = cx.tcx.parent_hir_node(hir_id)
+                && let Node::LetStmt(l) = cx.tcx.parent_hir_node(hir_id)
             {
                 if let Some(e) = l.init
                     && is_cast_from_ty_alias(cx, e, cast_from)
diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs
index 4ac2da19145..ee1bb63b50d 100644
--- a/clippy_lints/src/cognitive_complexity.rs
+++ b/clippy_lints/src/cognitive_complexity.rs
@@ -158,10 +158,10 @@ impl<'tcx> LateLintPass<'tcx> for CognitiveComplexity {
         }
     }
 
-    fn enter_lint_attrs(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) {
+    fn check_attributes(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) {
         self.limit.push_attrs(cx.sess(), attrs, "cognitive_complexity");
     }
-    fn exit_lint_attrs(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) {
+    fn check_attributes_post(&mut self, cx: &LateContext<'tcx>, attrs: &'tcx [Attribute]) {
         self.limit.pop_attrs(cx.sess(), attrs, "cognitive_complexity");
     }
 }
diff --git a/clippy_lints/src/collection_is_never_read.rs b/clippy_lints/src/collection_is_never_read.rs
index 83660bf2691..6942ca53640 100644
--- a/clippy_lints/src/collection_is_never_read.rs
+++ b/clippy_lints/src/collection_is_never_read.rs
@@ -3,7 +3,7 @@ use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
 use clippy_utils::visitors::for_each_expr_with_closures;
 use clippy_utils::{get_enclosing_block, path_to_local_id};
 use core::ops::ControlFlow;
-use rustc_hir::{Block, ExprKind, HirId, LangItem, Local, Node, PatKind};
+use rustc_hir::{Block, ExprKind, HirId, LangItem, LetStmt, Node, PatKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::sym;
@@ -58,7 +58,7 @@ static COLLECTIONS: [Symbol; 9] = [
 ];
 
 impl<'tcx> LateLintPass<'tcx> for CollectionIsNeverRead {
-    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) {
+    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
         // Look for local variables whose type is a container. Search surrounding bock for read access.
         if match_acceptable_type(cx, local, &COLLECTIONS)
             && let PatKind::Binding(_, local_id, _, _) = local.pat.kind
@@ -70,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for CollectionIsNeverRead {
     }
 }
 
-fn match_acceptable_type(cx: &LateContext<'_>, local: &Local<'_>, collections: &[Symbol]) -> bool {
+fn match_acceptable_type(cx: &LateContext<'_>, local: &LetStmt<'_>, collections: &[Symbol]) -> bool {
     let ty = cx.typeck_results().pat_ty(local.pat);
     collections.iter().any(|&sym| is_type_diagnostic_item(cx, ty, sym))
     // String type is a lang item but not a diagnostic item for now so we need a separate check
diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs
index f0f2c7d6658..5f9700b76d9 100644
--- a/clippy_lints/src/derive.rs
+++ b/clippy_lints/src/derive.rs
@@ -11,8 +11,7 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::traits::Reveal;
 use rustc_middle::ty::{
-    self, ClauseKind, GenericArgKind, GenericParamDefKind, ImplPolarity, ParamEnv, ToPredicate, TraitPredicate, Ty,
-    TyCtxt,
+    self, ClauseKind, GenericArgKind, GenericParamDefKind, ParamEnv, ToPredicate, TraitPredicate, Ty, TyCtxt,
 };
 use rustc_session::declare_lint_pass;
 use rustc_span::def_id::LocalDefId;
@@ -502,7 +501,7 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) ->
             params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| {
                 ClauseKind::Trait(TraitPredicate {
                     trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]),
-                    polarity: ImplPolarity::Positive,
+                    polarity: ty::PredicatePolarity::Positive,
                 })
                 .to_predicate(tcx)
             }),
diff --git a/clippy_lints/src/equatable_if_let.rs b/clippy_lints/src/equatable_if_let.rs
index 4e728d61b85..37442bf3e28 100644
--- a/clippy_lints/src/equatable_if_let.rs
+++ b/clippy_lints/src/equatable_if_let.rs
@@ -55,7 +55,7 @@ fn unary_pattern(pat: &Pat<'_>) -> bool {
         | PatKind::Err(_) => false,
         PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)),
         PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => etc.as_opt_usize().is_none() && array_rec(a),
-        PatKind::Ref(x, _) | PatKind::Box(x) => unary_pattern(x),
+        PatKind::Ref(x, _) | PatKind::Box(x) | PatKind::Deref(x) => unary_pattern(x),
         PatKind::Path(_) | PatKind::Lit(_) => true,
     }
 }
diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs
index 18d54bd94cc..850a4f0eec8 100644
--- a/clippy_lints/src/eta_reduction.rs
+++ b/clippy_lints/src/eta_reduction.rs
@@ -9,8 +9,8 @@ use rustc_hir::{BindingAnnotation, Expr, ExprKind, FnRetTy, Param, PatKind, QPat
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{
-    self, Binder, ClosureArgs, ClosureKind, FnSig, GenericArg, GenericArgKind, ImplPolarity, List, Region, RegionKind,
-    Ty, TypeVisitableExt, TypeckResults,
+    self, Binder, ClosureArgs, ClosureKind, FnSig, GenericArg, GenericArgKind, List, Region, RegionKind, Ty,
+    TypeVisitableExt, TypeckResults,
 };
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::sym;
@@ -173,7 +173,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
                             if let Ok((ClosureKind::FnMut, _)) = cx.tcx.infer_ctxt().build().type_implements_fn_trait(
                                 cx.param_env,
                                 Binder::bind_with_vars(callee_ty_adjusted, List::empty()),
-                                ImplPolarity::Positive,
+                                ty::PredicatePolarity::Positive,
                             ) && path_to_local(callee).map_or(false, |l| {
                                 local_used_in(cx, l, args) || local_used_after_expr(cx, l, expr)
                             }) {
diff --git a/clippy_lints/src/float_literal.rs b/clippy_lints/src/float_literal.rs
index 07fbb1cb5c9..2cd4e9e99a5 100644
--- a/clippy_lints/src/float_literal.rs
+++ b/clippy_lints/src/float_literal.rs
@@ -83,7 +83,10 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral {
                 LitFloatType::Unsuffixed => None,
             };
             let (is_whole, is_inf, mut float_str) = match fty {
-                FloatTy::F16 => unimplemented!("f16_f128"),
+                FloatTy::F16 | FloatTy::F128 => {
+                    // FIXME(f16_f128): do a check like the others when parsing is available
+                    return;
+                },
                 FloatTy::F32 => {
                     let value = sym_str.parse::<f32>().unwrap();
 
@@ -94,7 +97,6 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral {
 
                     (value.fract() == 0.0, value.is_infinite(), formatter.format(value))
                 },
-                FloatTy::F128 => unimplemented!("f16_f128"),
             };
 
             if is_inf {
@@ -139,10 +141,11 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral {
 #[must_use]
 fn max_digits(fty: FloatTy) -> u32 {
     match fty {
-        FloatTy::F16 => unimplemented!("f16_f128"),
+        // FIXME(f16_f128): replace the magic numbers once `{f16,f128}::DIGITS` are available
+        FloatTy::F16 => 3,
         FloatTy::F32 => f32::DIGITS,
         FloatTy::F64 => f64::DIGITS,
-        FloatTy::F128 => unimplemented!("f16_f128"),
+        FloatTy::F128 => 33,
     }
 }
 
diff --git a/clippy_lints/src/from_raw_with_void_ptr.rs b/clippy_lints/src/from_raw_with_void_ptr.rs
index b6d7cb87480..ba2495c17a2 100644
--- a/clippy_lints/src/from_raw_with_void_ptr.rs
+++ b/clippy_lints/src/from_raw_with_void_ptr.rs
@@ -4,7 +4,7 @@ use clippy_utils::ty::is_c_void;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{Expr, ExprKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::{RawPtr, TypeAndMut};
+use rustc_middle::ty::RawPtr;
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
 
@@ -44,7 +44,7 @@ impl LateLintPass<'_> for FromRawWithVoidPtr {
             && seg.ident.name == sym!(from_raw)
             && let Some(type_str) = path_def_id(cx, ty).and_then(|id| def_id_matches_type(cx, id))
             && let arg_kind = cx.typeck_results().expr_ty(arg).kind()
-            && let RawPtr(TypeAndMut { ty, .. }) = arg_kind
+            && let RawPtr(ty, _) = arg_kind
             && is_c_void(cx, *ty)
         {
             let msg = format!("creating a `{type_str}` from a void raw pointer");
diff --git a/clippy_lints/src/functions/misnamed_getters.rs b/clippy_lints/src/functions/misnamed_getters.rs
index bf96c0d62b0..8ac17e17688 100644
--- a/clippy_lints/src/functions/misnamed_getters.rs
+++ b/clippy_lints/src/functions/misnamed_getters.rs
@@ -24,13 +24,13 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body:
     let name = ident.name.as_str();
 
     let name = match decl.implicit_self {
-        ImplicitSelfKind::MutRef => {
+        ImplicitSelfKind::RefMut => {
             let Some(name) = name.strip_suffix("_mut") else {
                 return;
             };
             name
         },
-        ImplicitSelfKind::Imm | ImplicitSelfKind::Mut | ImplicitSelfKind::ImmRef => name,
+        ImplicitSelfKind::Imm | ImplicitSelfKind::Mut | ImplicitSelfKind::RefImm => name,
         ImplicitSelfKind::None => return,
     };
 
diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs
index d0d81c06950..d0c66900c00 100644
--- a/clippy_lints/src/functions/must_use.rs
+++ b/clippy_lints/src/functions/must_use.rs
@@ -207,9 +207,7 @@ fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, tys: &mut DefIdSet)
         },
         ty::Tuple(args) => args.iter().any(|ty| is_mutable_ty(cx, ty, tys)),
         ty::Array(ty, _) | ty::Slice(ty) => is_mutable_ty(cx, ty, tys),
-        ty::RawPtr(ty::TypeAndMut { ty, mutbl }) | ty::Ref(_, ty, mutbl) => {
-            mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, tys)
-        },
+        ty::RawPtr(ty, mutbl) | ty::Ref(_, ty, mutbl) => mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, tys),
         // calling something constitutes a side effect, so return true on all callables
         // also never calls need not be used, so return true for them, too
         _ => true,
diff --git a/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
index f2aa7b597a7..2d757883f26 100644
--- a/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
+++ b/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs
@@ -75,7 +75,7 @@ fn check_raw_ptr<'tcx>(
 }
 
 fn raw_ptr_arg(cx: &LateContext<'_>, arg: &hir::Param<'_>) -> Option<hir::HirId> {
-    if let (&hir::PatKind::Binding(_, id, _, _), Some(&ty::RawPtr(_))) = (
+    if let (&hir::PatKind::Binding(_, id, _, _), Some(&ty::RawPtr(_, _))) = (
         &arg.pat.kind,
         cx.maybe_typeck_results()
             .map(|typeck_results| typeck_results.pat_ty(arg.pat).kind()),
diff --git a/clippy_lints/src/future_not_send.rs b/clippy_lints/src/future_not_send.rs
index 9fb59a320d4..18f4e51ebd6 100644
--- a/clippy_lints/src/future_not_send.rs
+++ b/clippy_lints/src/future_not_send.rs
@@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend {
         }
         let ret_ty = return_ty(cx, cx.tcx.local_def_id_to_hir_id(fn_def_id).expect_owner());
         if let ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) = *ret_ty.kind() {
-            let preds = cx.tcx.explicit_item_bounds(def_id);
+            let preds = cx.tcx.explicit_item_super_predicates(def_id);
             let mut is_future = false;
             for (p, _span) in preds.iter_instantiated_copied(cx.tcx, args) {
                 if let Some(trait_pred) = p.as_trait_clause() {
diff --git a/clippy_lints/src/ignored_unit_patterns.rs b/clippy_lints/src/ignored_unit_patterns.rs
index 80a537b9f94..a32201d8079 100644
--- a/clippy_lints/src/ignored_unit_patterns.rs
+++ b/clippy_lints/src/ignored_unit_patterns.rs
@@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for IgnoredUnitPatterns {
                 // Ignore function parameters
                 return;
             },
-            Node::Local(local) if local.ty.is_some() => {
+            Node::LetStmt(local) if local.ty.is_some() => {
                 // Ignore let bindings with explicit type
                 return;
             },
diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs
index e1950d6218c..a46aae36d5c 100644
--- a/clippy_lints/src/implicit_hasher.rs
+++ b/clippy_lints/src/implicit_hasher.rs
@@ -5,7 +5,7 @@ use rustc_errors::Diag;
 use rustc_hir as hir;
 use rustc_hir::intravisit::{walk_body, walk_expr, walk_inf, walk_ty, Visitor};
 use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind};
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{Ty, TypeckResults};
@@ -227,7 +227,7 @@ impl<'tcx> ImplicitHasherType<'tcx> {
                 .collect();
             let params_len = params.len();
 
-            let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+            let ty = lower_ty(cx.tcx, hir_ty);
 
             if is_type_diagnostic_item(cx, ty, sym::HashMap) && params_len == 2 {
                 Some(ImplicitHasherType::HashMap(
diff --git a/clippy_lints/src/implied_bounds_in_impls.rs b/clippy_lints/src/implied_bounds_in_impls.rs
index fb4ba175233..7b97fc15caa 100644
--- a/clippy_lints/src/implied_bounds_in_impls.rs
+++ b/clippy_lints/src/implied_bounds_in_impls.rs
@@ -6,7 +6,7 @@ use rustc_hir::{
     GenericArg, GenericBound, GenericBounds, ItemKind, PredicateOrigin, TraitBoundModifier, TyKind, TypeBinding,
     WherePredicate,
 };
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, ClauseKind, Generics, Ty, TyCtxt};
 use rustc_session::declare_lint_pass;
@@ -146,7 +146,7 @@ fn try_resolve_type<'tcx>(
     index: usize,
 ) -> Option<Ty<'tcx>> {
     match args.get(index - 1) {
-        Some(GenericArg::Type(ty)) => Some(hir_ty_to_ty(tcx, ty)),
+        Some(GenericArg::Type(ty)) => Some(lower_ty(tcx, ty)),
         Some(_) => None,
         None => Some(tcx.type_of(generics.params[index].def_id).skip_binder()),
     }
diff --git a/clippy_lints/src/index_refutable_slice.rs b/clippy_lints/src/index_refutable_slice.rs
index 5b5eb355f86..4d1f89b1d9d 100644
--- a/clippy_lints/src/index_refutable_slice.rs
+++ b/clippy_lints/src/index_refutable_slice.rs
@@ -97,7 +97,7 @@ fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap<hir
             value_hir_id,
             ident,
             sub_pat,
-        ) = pat.kind
+        ) = pat.kind && by_ref != hir::ByRef::Yes(hir::Mutability::Mut)
         {
             // This block catches bindings with sub patterns. It would be hard to build a correct suggestion
             // for them and it's likely that the user knows what they are doing in such a case.
@@ -115,7 +115,7 @@ fn find_slice_values(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> FxIndexMap<hir
             if let ty::Slice(inner_ty) | ty::Array(inner_ty, _) = bound_ty.peel_refs().kind() {
                 // The values need to use the `ref` keyword if they can't be copied.
                 // This will need to be adjusted if the lint want to support mutable access in the future
-                let src_is_ref = bound_ty.is_ref() && by_ref != hir::ByRef::Yes;
+                let src_is_ref = bound_ty.is_ref() && by_ref == hir::ByRef::No;
                 let needs_ref = !(src_is_ref || is_copy(cx, *inner_ty));
 
                 let slice_info = slices
diff --git a/clippy_lints/src/iter_without_into_iter.rs b/clippy_lints/src/iter_without_into_iter.rs
index 1dd9b1515a9..c749a712330 100644
--- a/clippy_lints/src/iter_without_into_iter.rs
+++ b/clippy_lints/src/iter_without_into_iter.rs
@@ -216,8 +216,8 @@ impl {self_ty_without_ref} {{
     fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'_>) {
         let item_did = item.owner_id.to_def_id();
         let (borrow_prefix, expected_implicit_self) = match item.ident.name {
-            sym::iter => ("&", ImplicitSelfKind::ImmRef),
-            sym::iter_mut => ("&mut ", ImplicitSelfKind::MutRef),
+            sym::iter => ("&", ImplicitSelfKind::RefImm),
+            sym::iter_mut => ("&mut ", ImplicitSelfKind::RefMut),
             _ => return,
         };
 
diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs
index 5aa4e99121e..97a245b76d4 100644
--- a/clippy_lints/src/len_zero.rs
+++ b/clippy_lints/src/len_zero.rs
@@ -398,8 +398,8 @@ impl LenOutput {
 
     fn expected_sig(self, self_kind: ImplicitSelfKind) -> String {
         let self_ref = match self_kind {
-            ImplicitSelfKind::ImmRef => "&",
-            ImplicitSelfKind::MutRef => "&mut ",
+            ImplicitSelfKind::RefImm => "&",
+            ImplicitSelfKind::RefMut => "&mut ",
             _ => "",
         };
         match self {
@@ -425,8 +425,8 @@ fn check_is_empty_sig<'tcx>(
         [arg, res] if len_output.matches_is_empty_output(cx, *res) => {
             matches!(
                 (arg.kind(), self_kind),
-                (ty::Ref(_, _, Mutability::Not), ImplicitSelfKind::ImmRef)
-                    | (ty::Ref(_, _, Mutability::Mut), ImplicitSelfKind::MutRef)
+                (ty::Ref(_, _, Mutability::Not), ImplicitSelfKind::RefImm)
+                    | (ty::Ref(_, _, Mutability::Mut), ImplicitSelfKind::RefMut)
             ) || (!arg.is_ref() && matches!(self_kind, ImplicitSelfKind::Imm | ImplicitSelfKind::Mut))
         },
         _ => false,
diff --git a/clippy_lints/src/let_underscore.rs b/clippy_lints/src/let_underscore.rs
index 0ea53c39280..619e933b4ff 100644
--- a/clippy_lints/src/let_underscore.rs
+++ b/clippy_lints/src/let_underscore.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::ty::{implements_trait, is_must_use_ty, match_type};
 use clippy_utils::{is_from_proc_macro, is_must_use_func_call, paths};
-use rustc_hir::{Local, LocalSource, PatKind};
+use rustc_hir::{LetStmt, LocalSource, PatKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{GenericArgKind, IsSuggestable};
@@ -138,7 +138,7 @@ const SYNC_GUARD_PATHS: [&[&str]; 3] = [
 ];
 
 impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
-    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &Local<'tcx>) {
+    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &LetStmt<'tcx>) {
         if matches!(local.source, LocalSource::Normal)
             && !in_external_macro(cx.tcx.sess, local.span)
             && let PatKind::Wild = local.pat.kind
diff --git a/clippy_lints/src/let_with_type_underscore.rs b/clippy_lints/src/let_with_type_underscore.rs
index 5f3f9b43f45..593b29154b4 100644
--- a/clippy_lints/src/let_with_type_underscore.rs
+++ b/clippy_lints/src/let_with_type_underscore.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::source::snippet;
-use rustc_hir::{Local, TyKind};
+use rustc_hir::{LetStmt, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
@@ -26,7 +26,7 @@ declare_clippy_lint! {
 declare_lint_pass!(UnderscoreTyped => [LET_WITH_TYPE_UNDERSCORE]);
 
 impl LateLintPass<'_> for UnderscoreTyped {
-    fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) {
+    fn check_local(&mut self, cx: &LateContext<'_>, local: &LetStmt<'_>) {
         if !in_external_macro(cx.tcx.sess, local.span)
             && let Some(ty) = local.ty // Ensure that it has a type defined
             && let TyKind::Infer = &ty.kind // that type is '_'
diff --git a/clippy_lints/src/loops/explicit_iter_loop.rs b/clippy_lints/src/loops/explicit_iter_loop.rs
index 814ccaa36f5..eea5f2a94ea 100644
--- a/clippy_lints/src/loops/explicit_iter_loop.rs
+++ b/clippy_lints/src/loops/explicit_iter_loop.rs
@@ -10,7 +10,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{Expr, Mutability};
 use rustc_lint::LateContext;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
-use rustc_middle::ty::{self, EarlyBinder, Ty, TypeAndMut};
+use rustc_middle::ty::{self, EarlyBinder, Ty};
 use rustc_span::sym;
 
 pub(super) fn check(
@@ -160,7 +160,7 @@ fn is_ref_iterable<'tcx>(
                 let self_ty = if mutbl.is_mut() {
                     self_ty
                 } else {
-                    Ty::new_ref(cx.tcx, region, TypeAndMut { ty, mutbl })
+                    Ty::new_ref(cx.tcx, region, ty, mutbl)
                 };
                 if implements_trait(cx, self_ty, trait_id, &[])
                     && let Some(ty) =
@@ -175,7 +175,7 @@ fn is_ref_iterable<'tcx>(
             && !self_ty.is_ref()
         {
             // Attempt to borrow
-            let self_ty = Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, TypeAndMut { ty: self_ty, mutbl });
+            let self_ty = Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, self_ty, mutbl);
             if implements_trait(cx, self_ty, trait_id, &[])
                 && let Some(ty) = make_normalized_projection(cx.tcx, cx.param_env, trait_id, sym!(IntoIter), [self_ty])
                 && ty == res_ty
diff --git a/clippy_lints/src/loops/same_item_push.rs b/clippy_lints/src/loops/same_item_push.rs
index dd400a661a5..1d90d4a58f5 100644
--- a/clippy_lints/src/loops/same_item_push.rs
+++ b/clippy_lints/src/loops/same_item_push.rs
@@ -62,7 +62,7 @@ pub(super) fn check<'tcx>(
                         if let Node::Pat(pat) = node
                             && let PatKind::Binding(bind_ann, ..) = pat.kind
                             && !matches!(bind_ann, BindingAnnotation(_, Mutability::Mut))
-                            && let Node::Local(parent_let_expr) = cx.tcx.parent_hir_node(hir_id)
+                            && let Node::LetStmt(parent_let_expr) = cx.tcx.parent_hir_node(hir_id)
                             && let Some(init) = parent_let_expr.init
                         {
                             match init.kind {
diff --git a/clippy_lints/src/loops/utils.rs b/clippy_lints/src/loops/utils.rs
index 8bca33754e8..7b45cc95431 100644
--- a/clippy_lints/src/loops/utils.rs
+++ b/clippy_lints/src/loops/utils.rs
@@ -3,7 +3,7 @@ use clippy_utils::{get_parent_expr, is_integer_const, path_to_local, path_to_loc
 use rustc_ast::ast::{LitIntType, LitKind};
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_expr, walk_local, Visitor};
-use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, HirIdMap, Local, Mutability, PatKind};
+use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, HirIdMap, LetStmt, Mutability, PatKind};
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, Ty};
@@ -141,7 +141,7 @@ impl<'a, 'tcx> InitializeVisitor<'a, 'tcx> {
 impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
-    fn visit_local(&mut self, l: &'tcx Local<'_>) {
+    fn visit_local(&mut self, l: &'tcx LetStmt<'_>) {
         // Look for declarations of the variable
         if l.pat.hir_id == self.var_id
             && let PatKind::Binding(.., ident, _) = l.pat.kind
diff --git a/clippy_lints/src/loops/while_let_loop.rs b/clippy_lints/src/loops/while_let_loop.rs
index 93774b89768..bd04827a1f0 100644
--- a/clippy_lints/src/loops/while_let_loop.rs
+++ b/clippy_lints/src/loops/while_let_loop.rs
@@ -5,13 +5,13 @@ use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::needs_ordered_drop;
 use clippy_utils::visitors::any_temporaries_need_ordered_drop;
 use rustc_errors::Applicability;
-use rustc_hir::{Block, Expr, ExprKind, Local, MatchSource, Pat, StmtKind};
+use rustc_hir::{Block, Expr, ExprKind, LetStmt, MatchSource, Pat, StmtKind};
 use rustc_lint::LateContext;
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_block: &'tcx Block<'_>) {
     let (init, has_trailing_exprs) = match (loop_block.stmts, loop_block.expr) {
         ([stmt, stmts @ ..], expr) => {
-            if let StmtKind::Let(&Local {
+            if let StmtKind::Let(&LetStmt {
                 init: Some(e),
                 els: None,
                 ..
diff --git a/clippy_lints/src/loops/while_let_on_iterator.rs b/clippy_lints/src/loops/while_let_on_iterator.rs
index d070ee74985..194dd4752f9 100644
--- a/clippy_lints/src/loops/while_let_on_iterator.rs
+++ b/clippy_lints/src/loops/while_let_on_iterator.rs
@@ -6,7 +6,7 @@ use clippy_utils::{get_enclosing_loop_or_multi_call_closure, higher, is_refutabl
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::intravisit::{walk_expr, Visitor};
-use rustc_hir::{Closure, Expr, ExprKind, HirId, LangItem, Local, Mutability, PatKind, UnOp};
+use rustc_hir::{Closure, Expr, ExprKind, HirId, LangItem, LetStmt, Mutability, PatKind, UnOp};
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter::OnlyBodies;
 use rustc_middle::ty::adjustment::Adjust;
@@ -286,7 +286,7 @@ fn needs_mutable_borrow(cx: &LateContext<'_>, iter_expr: &IterExpr, loop_expr: &
             self.cx.tcx.hir()
         }
 
-        fn visit_local(&mut self, l: &'tcx Local<'_>) {
+        fn visit_local(&mut self, l: &'tcx LetStmt<'_>) {
             if !self.after_loop {
                 l.pat.each_binding_or_first(&mut |_, id, _, _| {
                     if id == self.local_id {
diff --git a/clippy_lints/src/manual_hash_one.rs b/clippy_lints/src/manual_hash_one.rs
index 5cbab0ec977..f8f33cfc82e 100644
--- a/clippy_lints/src/manual_hash_one.rs
+++ b/clippy_lints/src/manual_hash_one.rs
@@ -4,7 +4,7 @@ use clippy_utils::source::snippet_opt;
 use clippy_utils::visitors::{is_local_used, local_used_once};
 use clippy_utils::{is_trait_method, path_to_local_id};
 use rustc_errors::Applicability;
-use rustc_hir::{BindingAnnotation, ExprKind, Local, Node, PatKind, StmtKind};
+use rustc_hir::{BindingAnnotation, ExprKind, LetStmt, Node, PatKind, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::sym;
@@ -60,7 +60,7 @@ impl ManualHashOne {
 impl_lint_pass!(ManualHashOne => [MANUAL_HASH_ONE]);
 
 impl LateLintPass<'_> for ManualHashOne {
-    fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) {
+    fn check_local(&mut self, cx: &LateContext<'_>, local: &LetStmt<'_>) {
         // `let mut hasher = seg.build_hasher();`
         if let PatKind::Binding(BindingAnnotation::MUT, hasher, _, None) = local.pat.kind
             && let Some(init) = local.init
diff --git a/clippy_lints/src/manual_rem_euclid.rs b/clippy_lints/src/manual_rem_euclid.rs
index 0bde62bd554..ab9bca170cf 100644
--- a/clippy_lints/src/manual_rem_euclid.rs
+++ b/clippy_lints/src/manual_rem_euclid.rs
@@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
             // Apply only to params or locals with annotated types
             match cx.tcx.parent_hir_node(hir_id) {
                 Node::Param(..) => (),
-                Node::Local(local) => {
+                Node::LetStmt(local) => {
                     let Some(ty) = local.ty else { return };
                     if matches!(ty.kind, TyKind::Infer) {
                         return;
diff --git a/clippy_lints/src/matches/infallible_destructuring_match.rs b/clippy_lints/src/matches/infallible_destructuring_match.rs
index c8a48246e67..93d7683d2af 100644
--- a/clippy_lints/src/matches/infallible_destructuring_match.rs
+++ b/clippy_lints/src/matches/infallible_destructuring_match.rs
@@ -2,12 +2,12 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::{path_to_local_id, peel_blocks, strip_pat_refs};
 use rustc_errors::Applicability;
-use rustc_hir::{ByRef, ExprKind, Local, MatchSource, PatKind, QPath};
+use rustc_hir::{ExprKind, LetStmt, MatchSource, PatKind, QPath};
 use rustc_lint::LateContext;
 
 use super::INFALLIBLE_DESTRUCTURING_MATCH;
 
-pub(crate) fn check(cx: &LateContext<'_>, local: &Local<'_>) -> bool {
+pub(crate) fn check(cx: &LateContext<'_>, local: &LetStmt<'_>) -> bool {
     if !local.span.from_expansion()
         && let Some(expr) = local.init
         && let ExprKind::Match(target, arms, MatchSource::Normal) = expr.kind
@@ -30,7 +30,7 @@ pub(crate) fn check(cx: &LateContext<'_>, local: &Local<'_>) -> bool {
             format!(
                 "let {}({}{}) = {};",
                 snippet_with_applicability(cx, variant_name.span, "..", &mut applicability),
-                if binding.0 == ByRef::Yes { "ref " } else { "" },
+                binding.prefix_str(),
                 snippet_with_applicability(cx, local.pat.span, "..", &mut applicability),
                 snippet_with_applicability(cx, target.span, "..", &mut applicability),
             ),
diff --git a/clippy_lints/src/matches/match_as_ref.rs b/clippy_lints/src/matches/match_as_ref.rs
index a5079f46f5e..f5da8ec6187 100644
--- a/clippy_lints/src/matches/match_as_ref.rs
+++ b/clippy_lints/src/matches/match_as_ref.rs
@@ -67,7 +67,7 @@ fn is_none_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {
 fn is_ref_some_arm(cx: &LateContext<'_>, arm: &Arm<'_>) -> Option<Mutability> {
     if let PatKind::TupleStruct(ref qpath, [first_pat, ..], _) = arm.pat.kind
         && is_res_lang_ctor(cx, cx.qpath_res(qpath, arm.pat.hir_id), LangItem::OptionSome)
-        && let PatKind::Binding(BindingAnnotation(ByRef::Yes, mutabl), .., ident, _) = first_pat.kind
+        && let PatKind::Binding(BindingAnnotation(ByRef::Yes(mutabl), _), .., ident, _) = first_pat.kind
         && let ExprKind::Call(e, [arg]) = peel_blocks(arm.body).kind
         && is_res_lang_ctor(cx, path_res(cx, e), LangItem::OptionSome)
         && let ExprKind::Path(QPath::Resolved(_, path2)) = arg.kind
diff --git a/clippy_lints/src/matches/match_same_arms.rs b/clippy_lints/src/matches/match_same_arms.rs
index c7c453b7f6e..cd61e733694 100644
--- a/clippy_lints/src/matches/match_same_arms.rs
+++ b/clippy_lints/src/matches/match_same_arms.rs
@@ -243,7 +243,7 @@ impl<'a> NormalizedPat<'a> {
     fn from_pat(cx: &LateContext<'_>, arena: &'a DroplessArena, pat: &'a Pat<'_>) -> Self {
         match pat.kind {
             PatKind::Wild | PatKind::Binding(.., None) => Self::Wild,
-            PatKind::Binding(.., Some(pat)) | PatKind::Box(pat) | PatKind::Ref(pat, _) => {
+            PatKind::Binding(.., Some(pat)) | PatKind::Box(pat) | PatKind::Deref(pat) | PatKind::Ref(pat, _) => {
                 Self::from_pat(cx, arena, pat)
             },
             PatKind::Never => Self::Never,
diff --git a/clippy_lints/src/matches/match_single_binding.rs b/clippy_lints/src/matches/match_single_binding.rs
index 61977045fd4..864923b2773 100644
--- a/clippy_lints/src/matches/match_single_binding.rs
+++ b/clippy_lints/src/matches/match_single_binding.rs
@@ -148,7 +148,7 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e
 fn opt_parent_assign_span<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option<AssignmentExpr> {
     if let Node::Expr(parent_arm_expr) = cx.tcx.parent_hir_node(ex.hir_id) {
         return match cx.tcx.parent_hir_node(parent_arm_expr.hir_id) {
-            Node::Local(parent_let_expr) => Some(AssignmentExpr::Local {
+            Node::LetStmt(parent_let_expr) => Some(AssignmentExpr::Local {
                 span: parent_let_expr.span,
                 pat_span: parent_let_expr.pat.span(),
             }),
diff --git a/clippy_lints/src/matches/mod.rs b/clippy_lints/src/matches/mod.rs
index dd83e32a943..fae2c4e4af9 100644
--- a/clippy_lints/src/matches/mod.rs
+++ b/clippy_lints/src/matches/mod.rs
@@ -27,7 +27,7 @@ mod wild_in_or_pats;
 use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::source::walk_span_to_context;
 use clippy_utils::{higher, in_constant, is_direct_expn_of, is_span_match, span_contains_cfg};
-use rustc_hir::{Arm, Expr, ExprKind, Local, MatchSource, Pat};
+use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
@@ -1123,7 +1123,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
         }
     }
 
-    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'_>) {
+    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) {
         self.infallible_destructuring_match_linted |=
             local.els.is_none() && infallible_destructuring_match::check(cx, local);
     }
diff --git a/clippy_lints/src/matches/needless_match.rs b/clippy_lints/src/matches/needless_match.rs
index 3d3f29e5fc6..fe83e784c3c 100644
--- a/clippy_lints/src/matches/needless_match.rs
+++ b/clippy_lints/src/matches/needless_match.rs
@@ -125,7 +125,7 @@ fn strip_return<'hir>(expr: &'hir Expr<'hir>) -> &'hir Expr<'hir> {
 fn expr_ty_matches_p_ty(cx: &LateContext<'_>, expr: &Expr<'_>, p_expr: &Expr<'_>) -> bool {
     match cx.tcx.parent_hir_node(p_expr.hir_id) {
         // Compare match_expr ty with local in `let local = match match_expr {..}`
-        Node::Local(local) => {
+        Node::LetStmt(local) => {
             let results = cx.typeck_results();
             return same_type_and_consts(results.node_type(local.hir_id), results.expr_ty(expr));
         },
@@ -178,7 +178,7 @@ fn pat_same_as_expr(pat: &Pat<'_>, expr: &Expr<'_>) -> bool {
                 },
             )),
         ) => {
-            return !matches!(annot, BindingAnnotation(ByRef::Yes, _)) && pat_ident.name == first_seg.ident.name;
+            return !matches!(annot, BindingAnnotation(ByRef::Yes(_), _)) && pat_ident.name == first_seg.ident.name;
         },
         // Example: `Custom::TypeA => Custom::TypeB`, or `None => None`
         (PatKind::Path(QPath::Resolved(_, p_path)), ExprKind::Path(QPath::Resolved(_, e_path))) => {
diff --git a/clippy_lints/src/matches/redundant_guards.rs b/clippy_lints/src/matches/redundant_guards.rs
index 6bae51b45b8..50cbccc3968 100644
--- a/clippy_lints/src/matches/redundant_guards.rs
+++ b/clippy_lints/src/matches/redundant_guards.rs
@@ -182,7 +182,7 @@ fn get_pat_binding<'tcx>(
             if let PatKind::Binding(bind_annot, hir_id, ident, _) = pat.kind
                 && hir_id == local
             {
-                if matches!(bind_annot.0, rustc_ast::ByRef::Yes) {
+                if matches!(bind_annot.0, rustc_ast::ByRef::Yes(_)) {
                     let _ = byref_ident.insert(ident);
                 }
                 // the second call of `replace()` returns a `Some(span)`, meaning a multi-binding pattern
diff --git a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
index b770ad0ddb5..10c3203725a 100644
--- a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
+++ b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs
@@ -149,7 +149,7 @@ impl<'a, 'tcx> SigDropChecker<'a, 'tcx> {
                 false
             },
             rustc_middle::ty::Array(ty, _)
-            | rustc_middle::ty::RawPtr(TypeAndMut { ty, .. })
+            | rustc_middle::ty::RawPtr(ty, _)
             | rustc_middle::ty::Ref(_, ty, _)
             | rustc_middle::ty::Slice(ty) => self.has_sig_drop_attr(cx, *ty),
             _ => false,
diff --git a/clippy_lints/src/methods/clone_on_copy.rs b/clippy_lints/src/methods/clone_on_copy.rs
index 4965b396b8c..4e6823e8220 100644
--- a/clippy_lints/src/methods/clone_on_copy.rs
+++ b/clippy_lints/src/methods/clone_on_copy.rs
@@ -69,7 +69,7 @@ pub(super) fn check(
                 _ => false,
             },
             // local binding capturing a reference
-            Node::Local(l) if matches!(l.pat.kind, PatKind::Binding(BindingAnnotation(ByRef::Yes, _), ..)) => {
+            Node::LetStmt(l) if matches!(l.pat.kind, PatKind::Binding(BindingAnnotation(ByRef::Yes(_), _), ..)) => {
                 return;
             },
             _ => false,
diff --git a/clippy_lints/src/methods/iter_kv_map.rs b/clippy_lints/src/methods/iter_kv_map.rs
index 84fa4c03757..b9fec0c4f80 100644
--- a/clippy_lints/src/methods/iter_kv_map.rs
+++ b/clippy_lints/src/methods/iter_kv_map.rs
@@ -60,8 +60,6 @@ pub(super) fn check<'tcx>(
                 applicability,
             );
         } else {
-            let ref_annotation = if annotation.0 == ByRef::Yes { "ref " } else { "" };
-            let mut_annotation = if annotation.1 == Mutability::Mut { "mut " } else { "" };
             span_lint_and_sugg(
                 cx,
                 ITER_KV_MAP,
@@ -69,7 +67,8 @@ pub(super) fn check<'tcx>(
                 format!("iterating on a map's {replacement_kind}s"),
                 "try",
                 format!(
-                    "{recv_snippet}.{into_prefix}{replacement_kind}s().map(|{ref_annotation}{mut_annotation}{bound_ident}| {})",
+                    "{recv_snippet}.{into_prefix}{replacement_kind}s().map(|{}{bound_ident}| {})",
+                    annotation.prefix_str(),
                     snippet_with_applicability(cx, body_expr.span, "/* body */", &mut applicability)
                 ),
                 applicability,
diff --git a/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs b/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
index 2c789827f80..6c9bdcff826 100644
--- a/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
+++ b/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
@@ -50,7 +50,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: &str, re
             | ExprKind::Break(_, _) => true,
             _ => false,
         },
-        Some((Node::Stmt(_) | Node::Local(_), _)) => false,
+        Some((Node::Stmt(_) | Node::LetStmt(_), _)) => false,
         _ => true,
     };
 
diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs
index 747da125b68..662e7746496 100644
--- a/clippy_lints/src/methods/needless_collect.rs
+++ b/clippy_lints/src/methods/needless_collect.rs
@@ -11,7 +11,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Applicability, MultiSpan};
 use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
 use rustc_hir::{
-    BindingAnnotation, Block, Expr, ExprKind, HirId, HirIdSet, Local, Mutability, Node, PatKind, Stmt, StmtKind,
+    BindingAnnotation, Block, Expr, ExprKind, HirId, HirIdSet, LetStmt, Mutability, Node, PatKind, Stmt, StmtKind,
 };
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
@@ -85,7 +85,7 @@ pub(super) fn check<'tcx>(
                 );
             }
         },
-        Node::Local(l) => {
+        Node::LetStmt(l) => {
             if let PatKind::Binding(BindingAnnotation::NONE | BindingAnnotation::MUT, id, _, None) = l.pat.kind
                 && let ty = cx.typeck_results().expr_ty(collect_expr)
                 && [sym::Vec, sym::VecDeque, sym::BinaryHeap, sym::LinkedList]
@@ -424,7 +424,7 @@ fn get_expr_and_hir_id_from_stmt<'v>(stmt: &'v Stmt<'v>) -> Option<(&'v Expr<'v>
     match stmt.kind {
         StmtKind::Expr(expr) | StmtKind::Semi(expr) => Some((expr, None)),
         StmtKind::Item(..) => None,
-        StmtKind::Let(Local { init, pat, .. }) => {
+        StmtKind::Let(LetStmt { init, pat, .. }) => {
             if let PatKind::Binding(_, hir_id, ..) = pat.kind {
                 init.map(|init_expr| (init_expr, Some(hir_id)))
             } else {
diff --git a/clippy_lints/src/methods/readonly_write_lock.rs b/clippy_lints/src/methods/readonly_write_lock.rs
index 6c6846c4b47..9b0180d9369 100644
--- a/clippy_lints/src/methods/readonly_write_lock.rs
+++ b/clippy_lints/src/methods/readonly_write_lock.rs
@@ -24,7 +24,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, receiver
         && let Node::Expr(unwrap_call_expr) = cx.tcx.parent_hir_node(expr.hir_id)
         && is_unwrap_call(cx, unwrap_call_expr)
         && let parent = cx.tcx.parent_hir_node(unwrap_call_expr.hir_id)
-        && let Node::Local(local) = parent
+        && let Node::LetStmt(local) = parent
         && let Some(mir) = enclosing_mir(cx.tcx, expr.hir_id)
         && let Some((local, _)) = mir
             .local_decls
diff --git a/clippy_lints/src/methods/str_splitn.rs b/clippy_lints/src/methods/str_splitn.rs
index 955330237bf..55ae9746298 100644
--- a/clippy_lints/src/methods/str_splitn.rs
+++ b/clippy_lints/src/methods/str_splitn.rs
@@ -8,7 +8,7 @@ use clippy_utils::{is_diag_item_method, match_def_path, path_to_local_id, paths}
 use core::ops::ControlFlow;
 use rustc_errors::Applicability;
 use rustc_hir::{
-    BindingAnnotation, Expr, ExprKind, HirId, LangItem, Local, MatchSource, Node, Pat, PatKind, QPath, Stmt, StmtKind,
+    BindingAnnotation, Expr, ExprKind, HirId, LangItem, LetStmt, MatchSource, Node, Pat, PatKind, QPath, Stmt, StmtKind,
 };
 use rustc_lint::LateContext;
 use rustc_middle::ty;
@@ -128,7 +128,7 @@ fn check_manual_split_once_indirect(
 ) -> Option<()> {
     let ctxt = expr.span.ctxt();
     let mut parents = cx.tcx.hir().parent_iter(expr.hir_id);
-    if let (_, Node::Local(local)) = parents.next()?
+    if let (_, Node::LetStmt(local)) = parents.next()?
         && let PatKind::Binding(BindingAnnotation::MUT, iter_binding_id, iter_ident, None) = local.pat.kind
         && let (iter_stmt_id, Node::Stmt(_)) = parents.next()?
         && let (_, Node::Block(enclosing_block)) = parents.next()?
@@ -198,7 +198,7 @@ fn indirect_usage<'tcx>(
     binding: HirId,
     ctxt: SyntaxContext,
 ) -> Option<IndirectUsage<'tcx>> {
-    if let StmtKind::Let(&Local {
+    if let StmtKind::Let(&LetStmt {
         pat: Pat {
             kind: PatKind::Binding(BindingAnnotation::NONE, _, ident, None),
             ..
diff --git a/clippy_lints/src/methods/unnecessary_fold.rs b/clippy_lints/src/methods/unnecessary_fold.rs
index 988f3e86fcf..ccc8d17970e 100644
--- a/clippy_lints/src/methods/unnecessary_fold.rs
+++ b/clippy_lints/src/methods/unnecessary_fold.rs
@@ -20,7 +20,7 @@ fn needs_turbofish(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
 
     // some common cases where turbofish isn't needed:
     // - assigned to a local variable with a type annotation
-    if let hir::Node::Local(local) = parent
+    if let hir::Node::LetStmt(local) = parent
         && local.ty.is_some()
     {
         return false;
diff --git a/clippy_lints/src/methods/unnecessary_to_owned.rs b/clippy_lints/src/methods/unnecessary_to_owned.rs
index 0762115d212..23fc323446e 100644
--- a/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -12,14 +12,13 @@ use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BorrowKind, Expr, ExprKind, ItemKind, LangItem, Node};
-use rustc_hir_typeck::{FnCtxt, Inherited};
+use rustc_hir_typeck::{FnCtxt, TypeckRootCtxt};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::LateContext;
 use rustc_middle::mir::Mutability;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
 use rustc_middle::ty::{
-    self, ClauseKind, GenericArg, GenericArgKind, GenericArgsRef, ImplPolarity, ParamTy, ProjectionPredicate,
-    TraitPredicate, Ty,
+    self, ClauseKind, GenericArg, GenericArgKind, GenericArgsRef, ParamTy, ProjectionPredicate, TraitPredicate, Ty,
 };
 use rustc_span::{sym, Symbol};
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
@@ -336,12 +335,9 @@ fn check_other_call_arg<'tcx>(
         && let Some((n_refs, receiver_ty)) = if n_refs > 0 || is_copy(cx, receiver_ty) {
             Some((n_refs, receiver_ty))
         } else if trait_predicate.def_id() != deref_trait_id {
-            Some((1, Ty::new_ref(cx.tcx,
+            Some((1, Ty::new_imm_ref(cx.tcx,
                 cx.tcx.lifetimes.re_erased,
-                ty::TypeAndMut {
-                    ty: receiver_ty,
-                    mutbl: Mutability::Not,
-                },
+                receiver_ty,
             )))
         } else {
             None
@@ -441,8 +437,8 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
             Node::Item(item) => {
                 if let ItemKind::Fn(_, _, body_id) = &item.kind
                     && let output_ty = return_ty(cx, item.owner_id)
-                    && let inherited = Inherited::new(cx.tcx, item.owner_id.def_id)
-                    && let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, item.owner_id.def_id)
+                    && let root_ctxt = TypeckRootCtxt::new(cx.tcx, item.owner_id.def_id)
+                    && let fn_ctxt = FnCtxt::new(&root_ctxt, cx.param_env, item.owner_id.def_id)
                     && fn_ctxt.can_coerce(ty, output_ty)
                 {
                     if has_lifetime(output_ty) && has_lifetime(ty) {
@@ -669,7 +665,7 @@ fn check_borrow_predicate<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
         && let Some(borrow_id) = cx.tcx.get_diagnostic_item(sym::Borrow)
         && cx.tcx.predicates_of(method_def_id).predicates.iter().any(|(pred, _)| {
             if let ClauseKind::Trait(trait_pred) = pred.kind().skip_binder()
-                && trait_pred.polarity == ImplPolarity::Positive
+                && trait_pred.polarity == ty::PredicatePolarity::Positive
                 && trait_pred.trait_ref.def_id == borrow_id
             {
                 true
diff --git a/clippy_lints/src/methods/zst_offset.rs b/clippy_lints/src/methods/zst_offset.rs
index 0b829d99aef..d33021c2a7b 100644
--- a/clippy_lints/src/methods/zst_offset.rs
+++ b/clippy_lints/src/methods/zst_offset.rs
@@ -6,7 +6,7 @@ use rustc_middle::ty;
 use super::ZST_OFFSET;
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) {
-    if let ty::RawPtr(ty::TypeAndMut { ty, .. }) = cx.typeck_results().expr_ty(recv).kind()
+    if let ty::RawPtr(ty, _) = cx.typeck_results().expr_ty(recv).kind()
         && let Ok(layout) = cx.tcx.layout_of(cx.param_env.and(*ty))
         && layout.is_zst()
     {
diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs
index 0c0d440a81b..f5ce8dd29b1 100644
--- a/clippy_lints/src/misc.rs
+++ b/clippy_lints/src/misc.rs
@@ -129,7 +129,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
             if !is_lint_allowed(cx, REF_PATTERNS, arg.pat.hir_id) {
                 return;
             }
-            if let PatKind::Binding(BindingAnnotation(ByRef::Yes, _), ..) = arg.pat.kind {
+            if let PatKind::Binding(BindingAnnotation(ByRef::Yes(_), _), ..) = arg.pat.kind {
                 span_lint(
                     cx,
                     TOPLEVEL_REF_ARG,
@@ -144,7 +144,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
     fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
         if !in_external_macro(cx.tcx.sess, stmt.span)
             && let StmtKind::Let(local) = stmt.kind
-            && let PatKind::Binding(BindingAnnotation(ByRef::Yes, mutabl), .., name, None) = local.pat.kind
+            && let PatKind::Binding(BindingAnnotation(ByRef::Yes(mutabl), _), .., name, None) = local.pat.kind
             && let Some(init) = local.init
             // Do not emit if clippy::ref_patterns is not allowed to avoid having two lints for the same issue.
             && is_lint_allowed(cx, REF_PATTERNS, local.pat.hir_id)
diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs
index d9379ec89df..2fb784dae1c 100644
--- a/clippy_lints/src/missing_doc.rs
+++ b/clippy_lints/src/missing_doc.rs
@@ -162,12 +162,12 @@ impl MissingDoc {
 impl_lint_pass!(MissingDoc => [MISSING_DOCS_IN_PRIVATE_ITEMS]);
 
 impl<'tcx> LateLintPass<'tcx> for MissingDoc {
-    fn enter_lint_attrs(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [ast::Attribute]) {
+    fn check_attributes(&mut self, _: &LateContext<'tcx>, attrs: &'tcx [ast::Attribute]) {
         let doc_hidden = self.doc_hidden() || is_doc_hidden(attrs);
         self.doc_hidden_stack.push(doc_hidden);
     }
 
-    fn exit_lint_attrs(&mut self, _: &LateContext<'tcx>, _: &'tcx [ast::Attribute]) {
+    fn check_attributes_post(&mut self, _: &LateContext<'tcx>, _: &'tcx [ast::Attribute]) {
         self.doc_hidden_stack.pop().expect("empty doc_hidden_stack");
     }
 
diff --git a/clippy_lints/src/mixed_read_write_in_expression.rs b/clippy_lints/src/mixed_read_write_in_expression.rs
index 0a65c768c66..181351910db 100644
--- a/clippy_lints/src/mixed_read_write_in_expression.rs
+++ b/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_note};
 use clippy_utils::{get_parent_expr, path_to_local, path_to_local_id};
 use rustc_hir::intravisit::{walk_expr, Visitor};
-use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, Local, Node, Stmt, StmtKind};
+use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, LetStmt, Node, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
@@ -98,7 +98,7 @@ impl<'tcx> LateLintPass<'tcx> for EvalOrderDependence {
     fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
         match stmt.kind {
             StmtKind::Let(local) => {
-                if let Local { init: Some(e), .. } = local {
+                if let LetStmt { init: Some(e), .. } = local {
                     DivergenceVisitor { cx }.visit_expr(e);
                 }
             },
diff --git a/clippy_lints/src/mut_key.rs b/clippy_lints/src/mut_key.rs
index c32025fcbb6..79f0a398d55 100644
--- a/clippy_lints/src/mut_key.rs
+++ b/clippy_lints/src/mut_key.rs
@@ -121,7 +121,7 @@ impl<'tcx> LateLintPass<'tcx> for MutableKeyType {
         }
     }
 
-    fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::Local<'_>) {
+    fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::LetStmt<'_>) {
         if let hir::PatKind::Wild = local.pat.kind {
             return;
         }
diff --git a/clippy_lints/src/mut_reference.rs b/clippy_lints/src/mut_reference.rs
index 11ab36bb056..6867f76a723 100644
--- a/clippy_lints/src/mut_reference.rs
+++ b/clippy_lints/src/mut_reference.rs
@@ -83,10 +83,7 @@ fn check_arguments<'tcx>(
             let parameters = type_definition.fn_sig(cx.tcx).skip_binder().inputs();
             for (argument, parameter) in iter::zip(arguments, parameters) {
                 match parameter.kind() {
-                    ty::Ref(_, _, Mutability::Not)
-                    | ty::RawPtr(ty::TypeAndMut {
-                        mutbl: Mutability::Not, ..
-                    }) => {
+                    ty::Ref(_, _, Mutability::Not) | ty::RawPtr(_, Mutability::Not) => {
                         if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, _) = argument.kind {
                             span_lint(
                                 cx,
diff --git a/clippy_lints/src/mutex_atomic.rs b/clippy_lints/src/mutex_atomic.rs
index 0c7f7e44edf..7ecc8617694 100644
--- a/clippy_lints/src/mutex_atomic.rs
+++ b/clippy_lints/src/mutex_atomic.rs
@@ -127,7 +127,7 @@ fn get_atomic_name(ty: Ty<'_>) -> Option<&'static str> {
                 IntTy::I128 => None,
             }
         },
-        ty::RawPtr(_) => Some("AtomicPtr"),
+        ty::RawPtr(_, _) => Some("AtomicPtr"),
         _ => None,
     }
 }
diff --git a/clippy_lints/src/needless_late_init.rs b/clippy_lints/src/needless_late_init.rs
index 4cda4b171e3..810799acb2e 100644
--- a/clippy_lints/src/needless_late_init.rs
+++ b/clippy_lints/src/needless_late_init.rs
@@ -6,7 +6,7 @@ use clippy_utils::visitors::{for_each_expr, for_each_expr_with_closures, is_loca
 use core::ops::ControlFlow;
 use rustc_errors::{Applicability, MultiSpan};
 use rustc_hir::{
-    BindingAnnotation, Block, Expr, ExprKind, HirId, Local, LocalSource, MatchSource, Node, Pat, PatKind, Stmt,
+    BindingAnnotation, Block, Expr, ExprKind, HirId, LetStmt, LocalSource, MatchSource, Node, Pat, PatKind, Stmt,
     StmtKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
@@ -237,7 +237,7 @@ fn first_usage<'tcx>(
         })
 }
 
-fn local_snippet_without_semicolon(cx: &LateContext<'_>, local: &Local<'_>) -> Option<String> {
+fn local_snippet_without_semicolon(cx: &LateContext<'_>, local: &LetStmt<'_>) -> Option<String> {
     let span = local.span.with_hi(match local.ty {
         // let <pat>: <ty>;
         // ~~~~~~~~~~~~~~~
@@ -252,7 +252,7 @@ fn local_snippet_without_semicolon(cx: &LateContext<'_>, local: &Local<'_>) -> O
 
 fn check<'tcx>(
     cx: &LateContext<'tcx>,
-    local: &'tcx Local<'tcx>,
+    local: &'tcx LetStmt<'tcx>,
     local_stmt: &'tcx Stmt<'tcx>,
     block: &'tcx Block<'tcx>,
     binding_id: HirId,
@@ -363,9 +363,9 @@ fn check<'tcx>(
 }
 
 impl<'tcx> LateLintPass<'tcx> for NeedlessLateInit {
-    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) {
+    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
         let mut parents = cx.tcx.hir().parent_iter(local.hir_id);
-        if let Local {
+        if let LetStmt {
             init: None,
             pat:
                 &Pat {
diff --git a/clippy_lints/src/non_send_fields_in_send_ty.rs b/clippy_lints/src/non_send_fields_in_send_ty.rs
index d64190daecb..74e6c57b52d 100644
--- a/clippy_lints/src/non_send_fields_in_send_ty.rs
+++ b/clippy_lints/src/non_send_fields_in_send_ty.rs
@@ -219,7 +219,7 @@ fn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t
             }
         },
         // Raw pointers are `!Send` but allowed by the heuristic
-        ty::RawPtr(_) => true,
+        ty::RawPtr(_, _) => true,
         _ => false,
     }
 }
@@ -229,7 +229,7 @@ fn contains_pointer_like<'tcx>(cx: &LateContext<'tcx>, target_ty: Ty<'tcx>) -> b
     for ty_node in target_ty.walk() {
         if let GenericArgKind::Type(inner_ty) = ty_node.unpack() {
             match inner_ty.kind() {
-                ty::RawPtr(_) => {
+                ty::RawPtr(_, _) => {
                     return true;
                 },
                 ty::Adt(adt_def, _) => {
diff --git a/clippy_lints/src/pattern_type_mismatch.rs b/clippy_lints/src/pattern_type_mismatch.rs
index 582b9de43ae..44db061b8be 100644
--- a/clippy_lints/src/pattern_type_mismatch.rs
+++ b/clippy_lints/src/pattern_type_mismatch.rs
@@ -1,5 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use rustc_hir::{intravisit, Body, Expr, ExprKind, FnDecl, Let, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind};
+use rustc_hir::{
+    intravisit, Body, Expr, ExprKind, FnDecl, LetExpr, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind,
+};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
@@ -103,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch {
                 }
             }
         }
-        if let ExprKind::Let(Let { pat, .. }) = expr.kind {
+        if let ExprKind::Let(LetExpr { pat, .. }) = expr.kind {
             apply_lint(cx, pat, DerefPossible::Possible);
         }
     }
diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs
index d180d4fe327..83b32000a9f 100644
--- a/clippy_lints/src/ptr.rs
+++ b/clippy_lints/src/ptr.rs
@@ -604,7 +604,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
 
             match get_expr_use_or_unification_node(self.cx.tcx, e) {
                 Some((Node::Stmt(_), _)) => (),
-                Some((Node::Local(l), _)) => {
+                Some((Node::LetStmt(l), _)) => {
                     // Only trace simple bindings. e.g `let x = y;`
                     if let PatKind::Binding(BindingAnnotation::NONE, id, _, None) = l.pat.kind {
                         self.bindings.insert(id, args_idx);
diff --git a/clippy_lints/src/question_mark.rs b/clippy_lints/src/question_mark.rs
index 771ea33d1bf..927c6f1d519 100644
--- a/clippy_lints/src/question_mark.rs
+++ b/clippy_lints/src/question_mark.rs
@@ -14,7 +14,8 @@ use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::LangItem::{self, OptionNone, OptionSome, ResultErr, ResultOk};
 use rustc_hir::{
-    BindingAnnotation, Block, ByRef, Expr, ExprKind, Local, Node, PatKind, PathSegment, QPath, Stmt, StmtKind,
+    BindingAnnotation, Block, Body, ByRef, Expr, ExprKind, LetStmt, Mutability, Node, PatKind, PathSegment, QPath,
+    Stmt, StmtKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::Ty;
@@ -127,7 +128,7 @@ fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
             .map_or(false, |did| implements_trait(cx, init_ty, did, &[]))
     }
 
-    if let StmtKind::Let(Local {
+    if let StmtKind::Let(LetStmt {
         pat,
         init: Some(init_expr),
         els: Some(els),
@@ -302,9 +303,13 @@ fn check_if_let_some_or_err_and_early_return<'tcx>(cx: &LateContext<'tcx>, expr:
         let mut applicability = Applicability::MachineApplicable;
         let receiver_str = snippet_with_applicability(cx, let_expr.span, "..", &mut applicability);
         let requires_semi = matches!(cx.tcx.parent_hir_node(expr.hir_id), Node::Stmt(_));
+        let method_call_str = match by_ref {
+            ByRef::Yes(Mutability::Mut) => ".as_mut()",
+            ByRef::Yes(Mutability::Not) => ".as_ref()",
+            ByRef::No => "",
+        };
         let sugg = format!(
-            "{receiver_str}{}?{}",
-            if by_ref == ByRef::Yes { ".as_ref()" } else { "" },
+            "{receiver_str}{method_call_str}?{}",
             if requires_semi { ";" } else { "" }
         );
         span_lint_and_sugg(
@@ -365,11 +370,11 @@ impl<'tcx> LateLintPass<'tcx> for QuestionMark {
         }
     }
 
-    fn check_body(&mut self, _: &LateContext<'tcx>, _: &'tcx rustc_hir::Body<'tcx>) {
+    fn check_body(&mut self, _: &LateContext<'tcx>, _: &'tcx Body<'tcx>) {
         self.try_block_depth_stack.push(0);
     }
 
-    fn check_body_post(&mut self, _: &LateContext<'tcx>, _: &'tcx rustc_hir::Body<'tcx>) {
+    fn check_body_post(&mut self, _: &LateContext<'tcx>, _: &'tcx Body<'tcx>) {
         self.try_block_depth_stack.pop();
     }
 
diff --git a/clippy_lints/src/raw_strings.rs b/clippy_lints/src/raw_strings.rs
index ac29d27303c..7e71f48c6d9 100644
--- a/clippy_lints/src/raw_strings.rs
+++ b/clippy_lints/src/raw_strings.rs
@@ -108,7 +108,7 @@ impl EarlyLintPass for RawStrings {
                 }
             }
 
-            let req = {
+            let mut req = {
                 let mut following_quote = false;
                 let mut req = 0;
                 // `once` so a raw string ending in hashes is still checked
@@ -136,7 +136,9 @@ impl EarlyLintPass for RawStrings {
                     ControlFlow::Continue(num) | ControlFlow::Break(num) => num,
                 }
             };
-
+            if self.allow_one_hash_in_raw_strings {
+                req = req.max(1);
+            }
             if req < max {
                 span_lint_and_then(
                     cx,
diff --git a/clippy_lints/src/read_zero_byte_vec.rs b/clippy_lints/src/read_zero_byte_vec.rs
index 0ebdb031d5a..7f4735c6a88 100644
--- a/clippy_lints/src/read_zero_byte_vec.rs
+++ b/clippy_lints/src/read_zero_byte_vec.rs
@@ -3,7 +3,7 @@ use clippy_utils::get_enclosing_block;
 use clippy_utils::higher::{get_vec_init_kind, VecInitKind};
 use clippy_utils::source::snippet;
 
-use hir::{Expr, ExprKind, HirId, Local, PatKind, PathSegment, QPath, StmtKind};
+use hir::{Expr, ExprKind, HirId, LetStmt, PatKind, PathSegment, QPath, StmtKind};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::def::Res;
@@ -57,7 +57,7 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
             }
 
             if let StmtKind::Let(local) = stmt.kind
-                && let Local {
+                && let LetStmt {
                     pat, init: Some(init), ..
                 } = local
                 && let PatKind::Binding(_, id, ident, _) = pat.kind
diff --git a/clippy_lints/src/redundant_else.rs b/clippy_lints/src/redundant_else.rs
index fb434fb7450..3bdf13dbbea 100644
--- a/clippy_lints/src/redundant_else.rs
+++ b/clippy_lints/src/redundant_else.rs
@@ -105,7 +105,7 @@ impl<'ast> Visitor<'ast> for BreakVisitor {
     fn visit_expr(&mut self, expr: &'ast Expr) {
         self.is_break = match expr.kind {
             ExprKind::Break(..) | ExprKind::Continue(..) | ExprKind::Ret(..) => true,
-            ExprKind::Match(_, ref arms) => arms.iter().all(|arm|
+            ExprKind::Match(_, ref arms, _) => arms.iter().all(|arm|
                 arm.body.is_none() || arm.body.as_deref().is_some_and(|body| self.check_expr(body))
             ),
             ExprKind::If(_, ref then, Some(ref els)) => self.check_block(then) && self.check_expr(els),
diff --git a/clippy_lints/src/redundant_locals.rs b/clippy_lints/src/redundant_locals.rs
index 8bc5d081a20..7202266deeb 100644
--- a/clippy_lints/src/redundant_locals.rs
+++ b/clippy_lints/src/redundant_locals.rs
@@ -3,7 +3,7 @@ use clippy_utils::is_from_proc_macro;
 use clippy_utils::ty::needs_ordered_drop;
 use rustc_ast::Mutability;
 use rustc_hir::def::Res;
-use rustc_hir::{BindingAnnotation, ByRef, ExprKind, HirId, Local, Node, Pat, PatKind, QPath};
+use rustc_hir::{BindingAnnotation, ByRef, ExprKind, HirId, LetStmt, Node, Pat, PatKind, QPath};
 use rustc_hir_typeck::expr_use_visitor::PlaceBase;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
@@ -47,7 +47,7 @@ declare_clippy_lint! {
 declare_lint_pass!(RedundantLocals => [REDUNDANT_LOCALS]);
 
 impl<'tcx> LateLintPass<'tcx> for RedundantLocals {
-    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) {
+    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
         if !local.span.is_desugaring(DesugaringKind::Async)
             // the pattern is a single by-value binding
             && let PatKind::Binding(BindingAnnotation(ByRef::No, mutability), _, ident, None) = local.pat.kind
diff --git a/clippy_lints/src/redundant_type_annotations.rs b/clippy_lints/src/redundant_type_annotations.rs
index c28468e52a2..11b95ee3a54 100644
--- a/clippy_lints/src/redundant_type_annotations.rs
+++ b/clippy_lints/src/redundant_type_annotations.rs
@@ -131,7 +131,7 @@ fn extract_primty(ty_kind: &hir::TyKind<'_>) -> Option<hir::PrimTy> {
 }
 
 impl LateLintPass<'_> for RedundantTypeAnnotations {
-    fn check_local<'tcx>(&mut self, cx: &LateContext<'tcx>, local: &'tcx rustc_hir::Local<'tcx>) {
+    fn check_local<'tcx>(&mut self, cx: &LateContext<'tcx>, local: &'tcx rustc_hir::LetStmt<'tcx>) {
         if !is_lint_allowed(cx, REDUNDANT_TYPE_ANNOTATIONS, local.hir_id)
             // type annotation part
             && !local.span.from_expansion()
diff --git a/clippy_lints/src/reserve_after_initialization.rs b/clippy_lints/src/reserve_after_initialization.rs
index ca7a0c7c87b..c227b5b22f4 100644
--- a/clippy_lints/src/reserve_after_initialization.rs
+++ b/clippy_lints/src/reserve_after_initialization.rs
@@ -4,7 +4,7 @@ use clippy_utils::source::snippet;
 use clippy_utils::{is_from_proc_macro, path_to_local_id};
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
-use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, Local, PatKind, QPath, Stmt, StmtKind};
+use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, LetStmt, PatKind, QPath, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
@@ -69,7 +69,7 @@ impl<'tcx> LateLintPass<'tcx> for ReserveAfterInitialization {
         self.searcher = None;
     }
 
-    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) {
+    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
         if let Some(init_expr) = local.init
             && let PatKind::Binding(BindingAnnotation::MUT, id, _, None) = local.pat.kind
             && !in_external_macro(cx.sess(), local.span)
diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs
index 0fb7666dd9c..9db08acb03b 100644
--- a/clippy_lints/src/shadow.rs
+++ b/clippy_lints/src/shadow.rs
@@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::hir_id::ItemLocalId;
-use rustc_hir::{Block, Body, BodyOwnerKind, Expr, ExprKind, HirId, Let, Node, Pat, PatKind, QPath, UnOp};
+use rustc_hir::{Block, Body, BodyOwnerKind, Expr, ExprKind, HirId, LetExpr, Node, Pat, PatKind, QPath, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::{Span, Symbol};
@@ -238,10 +238,10 @@ fn find_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'
         let init = match node {
             Node::Arm(_) | Node::Pat(_) => continue,
             Node::Expr(expr) => match expr.kind {
-                ExprKind::Match(e, _, _) | ExprKind::Let(&Let { init: e, .. }) => Some(e),
+                ExprKind::Match(e, _, _) | ExprKind::Let(&LetExpr { init: e, .. }) => Some(e),
                 _ => None,
             },
-            Node::Local(local) => local.init,
+            Node::LetStmt(local) => local.init,
             _ => None,
         };
         return init;
diff --git a/clippy_lints/src/significant_drop_tightening.rs b/clippy_lints/src/significant_drop_tightening.rs
index f8726aa173a..d3540bc8e1c 100644
--- a/clippy_lints/src/significant_drop_tightening.rs
+++ b/clippy_lints/src/significant_drop_tightening.rs
@@ -7,7 +7,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{walk_expr, Visitor};
 use rustc_hir::{self as hir};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::ty::{GenericArgKind, Ty, TypeAndMut};
+use rustc_middle::ty::{GenericArgKind, Ty};
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::Ident;
 use rustc_span::{sym, Span, DUMMY_SP};
@@ -199,7 +199,7 @@ impl<'cx, 'others, 'tcx> AttrChecker<'cx, 'others, 'tcx> {
                 false
             },
             rustc_middle::ty::Array(ty, _)
-            | rustc_middle::ty::RawPtr(TypeAndMut { ty, .. })
+            | rustc_middle::ty::RawPtr(ty, _)
             | rustc_middle::ty::Ref(_, ty, _)
             | rustc_middle::ty::Slice(ty) => self.has_sig_drop_attr(*ty),
             _ => false,
diff --git a/clippy_lints/src/size_of_in_element_count.rs b/clippy_lints/src/size_of_in_element_count.rs
index 756e47cbdf0..01f0e3cfadb 100644
--- a/clippy_lints/src/size_of_in_element_count.rs
+++ b/clippy_lints/src/size_of_in_element_count.rs
@@ -4,7 +4,7 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::{self, Ty, TypeAndMut};
+use rustc_middle::ty::{self, Ty};
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
 
@@ -107,7 +107,7 @@ fn get_pointee_ty_and_count_expr<'tcx>(
         && METHODS.iter().any(|m| *m == method_ident)
 
         // Get the pointee type
-        && let ty::RawPtr(TypeAndMut { ty: pointee_ty, .. }) =
+        && let ty::RawPtr(pointee_ty, _) =
             cx.typeck_results().expr_ty(ptr_self).kind()
     {
         return Some((*pointee_ty, count));
diff --git a/clippy_lints/src/suspicious_operation_groupings.rs b/clippy_lints/src/suspicious_operation_groupings.rs
index 60e9d262e7e..ab1b3043f0c 100644
--- a/clippy_lints/src/suspicious_operation_groupings.rs
+++ b/clippy_lints/src/suspicious_operation_groupings.rs
@@ -552,7 +552,7 @@ fn ident_difference_expr_with_base_location(
         | (Gen(_, _, _), Gen(_, _, _))
         | (Block(_, _), Block(_, _))
         | (Closure(_), Closure(_))
-        | (Match(_, _), Match(_, _))
+        | (Match(_, _, _), Match(_, _, _))
         | (Loop(_, _, _), Loop(_, _, _))
         | (ForLoop { .. }, ForLoop { .. })
         | (While(_, _, _), While(_, _, _))
diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs
index 422fb6dfc4d..93bad865809 100644
--- a/clippy_lints/src/swap.rs
+++ b/clippy_lints/src/swap.rs
@@ -10,7 +10,7 @@ use rustc_hir::intravisit::{walk_expr, Visitor};
 
 use crate::FxHashSet;
 use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Block, Expr, ExprKind, PatKind, QPath, Stmt, StmtKind};
+use rustc_hir::{BinOpKind, Block, Expr, ExprKind, LetStmt, PatKind, QPath, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
@@ -392,7 +392,7 @@ impl<'a, 'tcx> IndexBinding<'a, 'tcx> {
         for stmt in self.block.stmts {
             match stmt.kind {
                 StmtKind::Expr(expr) | StmtKind::Semi(expr) => v.visit_expr(expr),
-                StmtKind::Let(rustc_hir::Local { ref init, .. }) => {
+                StmtKind::Let(LetStmt { ref init, .. }) => {
                     if let Some(init) = init.as_ref() {
                         v.visit_expr(init);
                     }
diff --git a/clippy_lints/src/transmute/crosspointer_transmute.rs b/clippy_lints/src/transmute/crosspointer_transmute.rs
index 72f1529eb00..c8f959a9854 100644
--- a/clippy_lints/src/transmute/crosspointer_transmute.rs
+++ b/clippy_lints/src/transmute/crosspointer_transmute.rs
@@ -7,8 +7,8 @@ use rustc_middle::ty::{self, Ty};
 /// Checks for `crosspointer_transmute` lint.
 /// Returns `true` if it's triggered, otherwise returns `false`.
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool {
-    match (&from_ty.kind(), &to_ty.kind()) {
-        (ty::RawPtr(from_ptr), _) if from_ptr.ty == to_ty => {
+    match (*from_ty.kind(), *to_ty.kind()) {
+        (ty::RawPtr(from_ptr_ty, _), _) if from_ptr_ty == to_ty => {
             span_lint(
                 cx,
                 CROSSPOINTER_TRANSMUTE,
@@ -17,7 +17,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty
             );
             true
         },
-        (_, ty::RawPtr(to_ptr)) if to_ptr.ty == from_ty => {
+        (_, ty::RawPtr(to_ptr_ty, _)) if to_ptr_ty == from_ty => {
             span_lint(
                 cx,
                 CROSSPOINTER_TRANSMUTE,
diff --git a/clippy_lints/src/transmute/missing_transmute_annotations.rs b/clippy_lints/src/transmute/missing_transmute_annotations.rs
index ec7041b945b..cc6ff1cf3b4 100644
--- a/clippy_lints/src/transmute/missing_transmute_annotations.rs
+++ b/clippy_lints/src/transmute/missing_transmute_annotations.rs
@@ -1,17 +1,17 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use rustc_errors::Applicability;
-use rustc_hir::{GenericArg, HirId, Local, Node, Path, TyKind};
+use rustc_hir::{GenericArg, HirId, LetStmt, Node, Path, TyKind};
 use rustc_lint::LateContext;
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::Ty;
 
 use crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS;
 
-fn get_parent_local_binding_ty<'tcx>(cx: &LateContext<'tcx>, expr_hir_id: HirId) -> Option<Local<'tcx>> {
+fn get_parent_local_binding_ty<'tcx>(cx: &LateContext<'tcx>, expr_hir_id: HirId) -> Option<LetStmt<'tcx>> {
     let mut parent_iter = cx.tcx.hir().parent_iter(expr_hir_id);
     if let Some((_, node)) = parent_iter.next() {
         match node {
-            Node::Local(local) => Some(*local),
+            Node::LetStmt(local) => Some(*local),
             Node::Block(_) => {
                 if let Some((parent_hir_id, Node::Expr(expr))) = parent_iter.next()
                     && matches!(expr.kind, rustc_hir::ExprKind::Block(_, _))
diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs
index 4ae4359eea0..1476ea8e7a4 100644
--- a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs
+++ b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs
@@ -16,7 +16,7 @@ pub(super) fn check<'tcx>(
     arg: &'tcx Expr<'_>,
 ) -> bool {
     match (&from_ty.kind(), &to_ty.kind()) {
-        (ty::RawPtr(_), ty::RawPtr(to_ty)) => {
+        (ty::RawPtr(_, _), ty::RawPtr(to_ty, to_mutbl)) => {
             span_lint_and_then(
                 cx,
                 TRANSMUTE_PTR_TO_PTR,
@@ -24,7 +24,7 @@ pub(super) fn check<'tcx>(
                 "transmute from a pointer to a pointer",
                 |diag| {
                     if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
-                        let sugg = arg.as_ty(Ty::new_ptr(cx.tcx, *to_ty));
+                        let sugg = arg.as_ty(Ty::new_ptr(cx.tcx, *to_ty, *to_mutbl));
                         diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified);
                     }
                 },
diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs
index 65d89c1fe43..eaf927c0005 100644
--- a/clippy_lints/src/transmute/transmute_ptr_to_ref.rs
+++ b/clippy_lints/src/transmute/transmute_ptr_to_ref.rs
@@ -20,7 +20,7 @@ pub(super) fn check<'tcx>(
     msrv: &Msrv,
 ) -> bool {
     match (&from_ty.kind(), &to_ty.kind()) {
-        (ty::RawPtr(from_ptr_ty), ty::Ref(_, to_ref_ty, mutbl)) => {
+        (ty::RawPtr(from_ptr_ty, _), ty::Ref(_, to_ref_ty, mutbl)) => {
             span_lint_and_then(
                 cx,
                 TRANSMUTE_PTR_TO_REF,
@@ -44,7 +44,7 @@ pub(super) fn check<'tcx>(
                         } else {
                             sugg::make_unop(deref, arg.as_ty(format!("{cast} {ty_snip}"))).to_string()
                         }
-                    } else if from_ptr_ty.ty == *to_ref_ty {
+                    } else if *from_ptr_ty == *to_ref_ty {
                         if from_ptr_ty.has_erased_regions() {
                             if msrv.meets(msrvs::POINTER_CAST) {
                                 format!("{deref}{}.cast::<{to_ref_ty}>()", arg.maybe_par())
diff --git a/clippy_lints/src/transmute/transmute_ref_to_ref.rs b/clippy_lints/src/transmute/transmute_ref_to_ref.rs
index 5de2d7fc2e5..3842c4eb60e 100644
--- a/clippy_lints/src/transmute/transmute_ref_to_ref.rs
+++ b/clippy_lints/src/transmute/transmute_ref_to_ref.rs
@@ -19,7 +19,7 @@ pub(super) fn check<'tcx>(
 ) -> bool {
     let mut triggered = false;
 
-    if let (ty::Ref(_, ty_from, from_mutbl), ty::Ref(_, ty_to, to_mutbl)) = (&from_ty.kind(), &to_ty.kind()) {
+    if let (ty::Ref(_, ty_from, from_mutbl), ty::Ref(_, ty_to, to_mutbl)) = (*from_ty.kind(), *to_ty.kind()) {
         if let ty::Slice(slice_ty) = *ty_from.kind()
             && ty_to.is_str()
             && let ty::Uint(ty::UintTy::U8) = slice_ty.kind()
@@ -27,7 +27,7 @@ pub(super) fn check<'tcx>(
         {
             let Some(top_crate) = std_or_core(cx) else { return true };
 
-            let postfix = if *from_mutbl == Mutability::Mut { "_mut" } else { "" };
+            let postfix = if from_mutbl == Mutability::Mut { "_mut" } else { "" };
 
             let snippet = snippet(cx, arg.span, "..");
 
@@ -53,18 +53,10 @@ pub(super) fn check<'tcx>(
                 "transmute from a reference to a reference",
                 |diag| {
                     if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
-                        let ty_from_and_mut = ty::TypeAndMut {
-                            ty: *ty_from,
-                            mutbl: *from_mutbl,
-                        };
-                        let ty_to_and_mut = ty::TypeAndMut {
-                            ty: *ty_to,
-                            mutbl: *to_mutbl,
-                        };
                         let sugg_paren = arg
-                            .as_ty(Ty::new_ptr(cx.tcx, ty_from_and_mut))
-                            .as_ty(Ty::new_ptr(cx.tcx, ty_to_and_mut));
-                        let sugg = if *to_mutbl == Mutability::Mut {
+                            .as_ty(Ty::new_ptr(cx.tcx, ty_from, from_mutbl))
+                            .as_ty(Ty::new_ptr(cx.tcx, ty_to, to_mutbl));
+                        let sugg = if to_mutbl == Mutability::Mut {
                             sugg_paren.mut_addr_deref()
                         } else {
                             sugg_paren.addr_deref()
diff --git a/clippy_lints/src/transmute/transmute_undefined_repr.rs b/clippy_lints/src/transmute/transmute_undefined_repr.rs
index 275cab2af9b..9c8dd37d53d 100644
--- a/clippy_lints/src/transmute/transmute_undefined_repr.rs
+++ b/clippy_lints/src/transmute/transmute_undefined_repr.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::ty::is_c_void;
 use rustc_hir::Expr;
 use rustc_lint::LateContext;
-use rustc_middle::ty::{self, GenericArgsRef, IntTy, Ty, TypeAndMut, UintTy};
+use rustc_middle::ty::{self, GenericArgsRef, IntTy, Ty, UintTy};
 
 #[expect(clippy::too_many_lines)]
 pub(super) fn check<'tcx>(
@@ -45,8 +45,8 @@ pub(super) fn check<'tcx>(
 
             // ptr <-> ptr
             (ReducedTy::Other(from_sub_ty), ReducedTy::Other(to_sub_ty))
-                if matches!(from_sub_ty.kind(), ty::Ref(..) | ty::RawPtr(_))
-                    && matches!(to_sub_ty.kind(), ty::Ref(..) | ty::RawPtr(_)) =>
+                if matches!(from_sub_ty.kind(), ty::Ref(..) | ty::RawPtr(_, _))
+                    && matches!(to_sub_ty.kind(), ty::Ref(..) | ty::RawPtr(_, _)) =>
             {
                 from_ty = from_sub_ty;
                 to_ty = to_sub_ty;
@@ -196,21 +196,21 @@ fn reduce_refs<'tcx>(cx: &LateContext<'tcx>, mut from_ty: Ty<'tcx>, mut to_ty: T
     let (from_fat_ptr, to_fat_ptr) = loop {
         break match (from_ty.kind(), to_ty.kind()) {
             (
-                &(ty::Ref(_, from_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: from_sub_ty, .. })),
-                &(ty::Ref(_, to_sub_ty, _) | ty::RawPtr(TypeAndMut { ty: to_sub_ty, .. })),
+                &(ty::Ref(_, from_sub_ty, _) | ty::RawPtr(from_sub_ty, _)),
+                &(ty::Ref(_, to_sub_ty, _) | ty::RawPtr(to_sub_ty, _)),
             ) => {
-                from_raw_ptr = matches!(*from_ty.kind(), ty::RawPtr(_));
+                from_raw_ptr = matches!(*from_ty.kind(), ty::RawPtr(_, _));
                 from_ty = from_sub_ty;
-                to_raw_ptr = matches!(*to_ty.kind(), ty::RawPtr(_));
+                to_raw_ptr = matches!(*to_ty.kind(), ty::RawPtr(_, _));
                 to_ty = to_sub_ty;
                 continue;
             },
-            (&(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })), _)
+            (&(ty::Ref(_, unsized_ty, _) | ty::RawPtr(unsized_ty, _)), _)
                 if !unsized_ty.is_sized(cx.tcx, cx.param_env) =>
             {
                 (true, false)
             },
-            (_, &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(TypeAndMut { ty: unsized_ty, .. })))
+            (_, &(ty::Ref(_, unsized_ty, _) | ty::RawPtr(unsized_ty, _)))
                 if !unsized_ty.is_sized(cx.tcx, cx.param_env) =>
             {
                 (false, true)
diff --git a/clippy_lints/src/transmute/useless_transmute.rs b/clippy_lints/src/transmute/useless_transmute.rs
index 0d5fbff0605..ec5fb2793f9 100644
--- a/clippy_lints/src/transmute/useless_transmute.rs
+++ b/clippy_lints/src/transmute/useless_transmute.rs
@@ -15,7 +15,7 @@ pub(super) fn check<'tcx>(
     to_ty: Ty<'tcx>,
     arg: &'tcx Expr<'_>,
 ) -> bool {
-    match (&from_ty.kind(), &to_ty.kind()) {
+    match (*from_ty.kind(), *to_ty.kind()) {
         _ if from_ty == to_ty && !from_ty.has_erased_regions() => {
             span_lint(
                 cx,
@@ -25,7 +25,7 @@ pub(super) fn check<'tcx>(
             );
             true
         },
-        (ty::Ref(_, rty, rty_mutbl), ty::RawPtr(ptr_ty)) => {
+        (ty::Ref(_, rty, rty_mutbl), ty::RawPtr(ptr_ty, ptr_mutbl)) => {
             // No way to give the correct suggestion here. Avoid linting for now.
             if !rty.has_erased_regions() {
                 span_lint_and_then(
@@ -35,15 +35,10 @@ pub(super) fn check<'tcx>(
                     "transmute from a reference to a pointer",
                     |diag| {
                         if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
-                            let rty_and_mut = ty::TypeAndMut {
-                                ty: *rty,
-                                mutbl: *rty_mutbl,
-                            };
-
-                            let sugg = if *ptr_ty == rty_and_mut {
+                            let sugg = if ptr_ty == rty && rty_mutbl == ptr_mutbl {
                                 arg.as_ty(to_ty)
                             } else {
-                                arg.as_ty(Ty::new_ptr(cx.tcx, rty_and_mut)).as_ty(to_ty)
+                                arg.as_ty(Ty::new_ptr(cx.tcx, rty, rty_mutbl)).as_ty(to_ty)
                             };
 
                             diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified);
@@ -53,7 +48,7 @@ pub(super) fn check<'tcx>(
             }
             true
         },
-        (ty::Int(_) | ty::Uint(_), ty::RawPtr(_)) => {
+        (ty::Int(_) | ty::Uint(_), ty::RawPtr(_, _)) => {
             span_lint_and_then(
                 cx,
                 USELESS_TRANSMUTE,
diff --git a/clippy_lints/src/transmute/utils.rs b/clippy_lints/src/transmute/utils.rs
index 7a7bb9f9c94..15f1890aa39 100644
--- a/clippy_lints/src/transmute/utils.rs
+++ b/clippy_lints/src/transmute/utils.rs
@@ -1,6 +1,6 @@
 use rustc_hir as hir;
 use rustc_hir::Expr;
-use rustc_hir_typeck::{cast, FnCtxt, Inherited};
+use rustc_hir_typeck::{cast, FnCtxt, TypeckRootCtxt};
 use rustc_lint::LateContext;
 use rustc_middle::ty::cast::CastKind;
 use rustc_middle::ty::Ty;
@@ -34,8 +34,8 @@ pub(super) fn check_cast<'tcx>(
     let hir_id = e.hir_id;
     let local_def_id = hir_id.owner.def_id;
 
-    let inherited = Inherited::new(cx.tcx, local_def_id);
-    let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, local_def_id);
+    let root_ctxt = TypeckRootCtxt::new(cx.tcx, local_def_id);
+    let fn_ctxt = FnCtxt::new(&root_ctxt, cx.param_env, local_def_id);
 
     if let Ok(check) = cast::CastCheck::new(
         &fn_ctxt,
diff --git a/clippy_lints/src/transmute/wrong_transmute.rs b/clippy_lints/src/transmute/wrong_transmute.rs
index 53c479b54d5..14a5a308a64 100644
--- a/clippy_lints/src/transmute/wrong_transmute.rs
+++ b/clippy_lints/src/transmute/wrong_transmute.rs
@@ -8,7 +8,7 @@ use rustc_middle::ty::{self, Ty};
 /// Returns `true` if it's triggered, otherwise returns `false`.
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool {
     match (&from_ty.kind(), &to_ty.kind()) {
-        (ty::Float(_) | ty::Char, ty::Ref(..) | ty::RawPtr(_)) => {
+        (ty::Float(_) | ty::Char, ty::Ref(..) | ty::RawPtr(_, _)) => {
             span_lint(
                 cx,
                 WRONG_TRANSMUTE,
diff --git a/clippy_lints/src/tuple_array_conversions.rs b/clippy_lints/src/tuple_array_conversions.rs
index 0d84a9ab395..564b065d0ba 100644
--- a/clippy_lints/src/tuple_array_conversions.rs
+++ b/clippy_lints/src/tuple_array_conversions.rs
@@ -159,7 +159,7 @@ fn all_bindings_are_for_conv<'tcx>(
         .iter()
         .map(|node| match node {
             Node::Pat(pat) => kind.eq(&pat.kind).then_some(pat.hir_id),
-            Node::Local(l) => Some(l.hir_id),
+            Node::LetStmt(l) => Some(l.hir_id),
             _ => None,
         })
         .all_equal()
@@ -170,7 +170,7 @@ fn all_bindings_are_for_conv<'tcx>(
         && local_parents.first().is_some_and(|node| {
             let Some(ty) = match node {
                 Node::Pat(pat) => Some(pat.hir_id),
-                Node::Local(l) => Some(l.hir_id),
+                Node::LetStmt(l) => Some(l.hir_id),
                 _ => None,
             }
             .map(|hir_id| cx.typeck_results().node_type(hir_id)) else {
diff --git a/clippy_lints/src/types/mod.rs b/clippy_lints/src/types/mod.rs
index 2ad15ac8312..0802cb2b7c7 100644
--- a/clippy_lints/src/types/mod.rs
+++ b/clippy_lints/src/types/mod.rs
@@ -12,7 +12,7 @@ mod vec_box;
 use rustc_hir as hir;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
-    Body, FnDecl, FnRetTy, GenericArg, ImplItem, ImplItemKind, Item, ItemKind, Local, MutTy, QPath, TraitItem,
+    Body, FnDecl, FnRetTy, GenericArg, ImplItem, ImplItemKind, Item, ItemKind, LetStmt, MutTy, QPath, TraitItem,
     TraitItemKind, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
@@ -425,7 +425,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
         }
     }
 
-    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &Local<'tcx>) {
+    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &LetStmt<'tcx>) {
         if let Some(ty) = local.ty {
             self.check_ty(
                 cx,
diff --git a/clippy_lints/src/types/redundant_allocation.rs b/clippy_lints/src/types/redundant_allocation.rs
index 893faafc2c0..0801eace4fc 100644
--- a/clippy_lints/src/types/redundant_allocation.rs
+++ b/clippy_lints/src/types/redundant_allocation.rs
@@ -4,7 +4,7 @@ use clippy_utils::{path_def_id, qpath_generic_tys};
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{self as hir, QPath, TyKind};
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir_analysis::lower_ty;
 use rustc_lint::LateContext;
 use rustc_middle::ty::TypeVisitableExt;
 use rustc_span::symbol::sym;
@@ -56,10 +56,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, qpath:
     };
     let inner_span = match qpath_generic_tys(inner_qpath).next() {
         Some(hir_ty) => {
-            // Reallocation of a fat pointer causes it to become thin. `hir_ty_to_ty` is safe to use
+            // Reallocation of a fat pointer causes it to become thin. `lower_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.
-            let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+            let ty = lower_ty(cx.tcx, hir_ty);
             if ty.has_escaping_bound_vars() || !ty.is_sized(cx.tcx, cx.param_env) {
                 return false;
             }
diff --git a/clippy_lints/src/types/vec_box.rs b/clippy_lints/src/types/vec_box.rs
index 7926738d68f..29996a6f783 100644
--- a/clippy_lints/src/types/vec_box.rs
+++ b/clippy_lints/src/types/vec_box.rs
@@ -4,7 +4,7 @@ use clippy_utils::source::snippet;
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{self as hir, GenericArg, LangItem, QPath, TyKind};
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir_analysis::lower_ty;
 use rustc_lint::LateContext;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::TypeVisitableExt;
@@ -35,7 +35,7 @@ pub(super) fn check<'tcx>(
             && let Some(GenericArg::Type(boxed_ty)) = last.args.first()
             // extract allocator from the Box for later
             && let boxed_alloc_ty = last.args.get(1)
-            && let ty_ty = hir_ty_to_ty(cx.tcx, boxed_ty)
+            && let ty_ty = lower_ty(cx.tcx, boxed_ty)
             && !ty_ty.has_escaping_bound_vars()
             && ty_ty.is_sized(cx.tcx, cx.param_env)
             && let Ok(ty_ty_size) = cx.layout_of(ty_ty).map(|l| l.size.bytes())
@@ -55,7 +55,7 @@ pub(super) fn check<'tcx>(
                     }
                 },
                 (Some(GenericArg::Type(l)), Some(GenericArg::Type(r))) =>
-                    hir_ty_to_ty(cx.tcx, l) == hir_ty_to_ty(cx.tcx, r),
+                    lower_ty(cx.tcx, l) == lower_ty(cx.tcx, r),
                 _ => false
             }
         {
diff --git a/clippy_lints/src/unconditional_recursion.rs b/clippy_lints/src/unconditional_recursion.rs
index 52338027dea..0c4e2c91aec 100644
--- a/clippy_lints/src/unconditional_recursion.rs
+++ b/clippy_lints/src/unconditional_recursion.rs
@@ -7,7 +7,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{walk_body, walk_expr, FnKind, Visitor};
 use rustc_hir::{Body, Expr, ExprKind, FnDecl, HirId, Item, ItemKind, Node, QPath, TyKind};
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::map::Map;
 use rustc_middle::hir::nested_filter;
@@ -74,7 +74,7 @@ fn get_hir_ty_def_id<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: rustc_hir::Ty<'tcx>) -> Op
     match qpath {
         QPath::Resolved(_, path) => path.res.opt_def_id(),
         QPath::TypeRelative(_, _) => {
-            let ty = hir_ty_to_ty(tcx, &hir_ty);
+            let ty = lower_ty(tcx, &hir_ty);
 
             match ty.kind() {
                 ty::Alias(ty::Projection, proj) => {
diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs
index 8106694c43b..cbd16180077 100644
--- a/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -158,7 +158,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
     }
 
     fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &hir::Stmt<'tcx>) {
-        let (hir::StmtKind::Let(&hir::Local { init: Some(expr), .. })
+        let (hir::StmtKind::Let(&hir::LetStmt { init: Some(expr), .. })
         | hir::StmtKind::Expr(expr)
         | hir::StmtKind::Semi(expr)) = stmt.kind
         else {
@@ -342,7 +342,7 @@ fn block_parents_have_safety_comment(
 ) -> bool {
     let (span, hir_id) = match cx.tcx.parent_hir_node(id) {
         Node::Expr(expr) => match cx.tcx.parent_hir_node(expr.hir_id) {
-            Node::Local(hir::Local { span, hir_id, .. }) => (*span, *hir_id),
+            Node::LetStmt(hir::LetStmt { span, hir_id, .. }) => (*span, *hir_id),
             Node::Item(hir::Item {
                 kind: ItemKind::Const(..) | ItemKind::Static(..),
                 span,
@@ -358,12 +358,12 @@ fn block_parents_have_safety_comment(
         },
         Node::Stmt(hir::Stmt {
             kind:
-                hir::StmtKind::Let(hir::Local { span, hir_id, .. })
+                hir::StmtKind::Let(hir::LetStmt { span, hir_id, .. })
                 | hir::StmtKind::Expr(hir::Expr { span, hir_id, .. })
                 | hir::StmtKind::Semi(hir::Expr { span, hir_id, .. }),
             ..
         })
-        | Node::Local(hir::Local { span, hir_id, .. }) => (*span, *hir_id),
+        | Node::LetStmt(hir::LetStmt { span, hir_id, .. }) => (*span, *hir_id),
         Node::Item(hir::Item {
             kind: ItemKind::Const(..) | ItemKind::Static(..),
             span,
@@ -603,7 +603,7 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {
     for (_, node) in map.parent_iter(body.hir_id) {
         match node {
             Node::Expr(e) => span = e.span,
-            Node::Block(_) | Node::Arm(_) | Node::Stmt(_) | Node::Local(_) => (),
+            Node::Block(_) | Node::Arm(_) | Node::Stmt(_) | Node::LetStmt(_) => (),
             Node::Item(hir::Item {
                 kind: ItemKind::Const(..) | ItemKind::Static(..),
                 ..
diff --git a/clippy_lints/src/uninhabited_references.rs b/clippy_lints/src/uninhabited_references.rs
index 6732a43a19e..88039372ebd 100644
--- a/clippy_lints/src/uninhabited_references.rs
+++ b/clippy_lints/src/uninhabited_references.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, Expr, ExprKind, FnDecl, FnRetTy, TyKind, UnOp};
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::declare_lint_pass;
@@ -71,7 +71,7 @@ impl LateLintPass<'_> for UninhabitedReferences {
         }
         if let FnRetTy::Return(hir_ty) = fndecl.output
             && let TyKind::Ref(_, mut_ty) = hir_ty.kind
-            && hir_ty_to_ty(cx.tcx, mut_ty.ty).is_privately_uninhabited(cx.tcx, cx.param_env)
+            && lower_ty(cx.tcx, mut_ty.ty).is_privately_uninhabited(cx.tcx, cx.param_env)
         {
             span_lint(
                 cx,
diff --git a/clippy_lints/src/unit_types/let_unit_value.rs b/clippy_lints/src/unit_types/let_unit_value.rs
index d7ab40c4b66..80b661a757c 100644
--- a/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/clippy_lints/src/unit_types/let_unit_value.rs
@@ -5,14 +5,14 @@ use core::ops::ControlFlow;
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{walk_body, Visitor};
-use rustc_hir::{Expr, ExprKind, HirId, HirIdSet, Local, MatchSource, Node, PatKind, QPath, TyKind};
+use rustc_hir::{Expr, ExprKind, HirId, HirIdSet, LetStmt, MatchSource, Node, PatKind, QPath, TyKind};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::{in_external_macro, is_from_async_await};
 use rustc_middle::ty;
 
 use super::LET_UNIT_VALUE;
 
-pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) {
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) {
     // skip `let () = { ... }`
     if let PatKind::Tuple(fields, ..) = local.pat.kind
         && fields.is_empty()
@@ -144,7 +144,7 @@ fn expr_needs_inferred_result<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -
         return false;
     }
     while let Some(id) = locals_to_check.pop() {
-        if let Node::Local(l) = cx.tcx.parent_hir_node(id) {
+        if let Node::LetStmt(l) = cx.tcx.parent_hir_node(id) {
             if !l.ty.map_or(true, |ty| matches!(ty.kind, TyKind::Infer)) {
                 return false;
             }
diff --git a/clippy_lints/src/unit_types/mod.rs b/clippy_lints/src/unit_types/mod.rs
index 0abd48e6423..e016bd3434b 100644
--- a/clippy_lints/src/unit_types/mod.rs
+++ b/clippy_lints/src/unit_types/mod.rs
@@ -3,7 +3,7 @@ mod unit_arg;
 mod unit_cmp;
 mod utils;
 
-use rustc_hir::{Expr, Local};
+use rustc_hir::{Expr, LetStmt};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 
@@ -99,7 +99,7 @@ declare_clippy_lint! {
 declare_lint_pass!(UnitTypes => [LET_UNIT_VALUE, UNIT_CMP, UNIT_ARG]);
 
 impl<'tcx> LateLintPass<'tcx> for UnitTypes {
-    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) {
+    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
         let_unit_value::check(cx, local);
     }
 
diff --git a/clippy_lints/src/unnested_or_patterns.rs b/clippy_lints/src/unnested_or_patterns.rs
index 8094fee8477..0049de931f4 100644
--- a/clippy_lints/src/unnested_or_patterns.rs
+++ b/clippy_lints/src/unnested_or_patterns.rs
@@ -232,7 +232,7 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: us
         // In the case of only two patterns, replacement adds net characters.
         | Ref(_, Mutability::Not)
         // Dealt with elsewhere.
-        | Or(_) | Paren(_) => false,
+        | Or(_) | Paren(_) | Deref(_) => false,
         // Transform `box x | ... | box y` into `box (x | y)`.
         //
         // The cases below until `Slice(...)` deal with *singleton* products.
diff --git a/clippy_lints/src/unused_io_amount.rs b/clippy_lints/src/unused_io_amount.rs
index 9d735b19c64..448946bd66d 100644
--- a/clippy_lints/src/unused_io_amount.rs
+++ b/clippy_lints/src/unused_io_amount.rs
@@ -131,7 +131,7 @@ fn non_consuming_ok_arm<'a>(cx: &LateContext<'a>, arm: &hir::Arm<'a>) -> bool {
 fn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) {
     match expr.kind {
         ExprKind::If(cond, _, _)
-            if let ExprKind::Let(hir::Let { pat, init, .. }) = cond.kind
+            if let ExprKind::Let(hir::LetExpr { pat, init, .. }) = cond.kind
                 && is_ok_wild_or_dotdot_pattern(cx, pat)
                 && let Some(op) = should_lint(cx, init) =>
         {
diff --git a/clippy_lints/src/unused_peekable.rs b/clippy_lints/src/unused_peekable.rs
index 3f4ab3e31cf..e6f799335d7 100644
--- a/clippy_lints/src/unused_peekable.rs
+++ b/clippy_lints/src/unused_peekable.rs
@@ -3,7 +3,7 @@ use clippy_utils::ty::{is_type_diagnostic_item, peel_mid_ty_refs_is_mutable};
 use clippy_utils::{fn_def_id, is_trait_method, path_to_local_id, peel_ref_operators};
 use rustc_ast::Mutability;
 use rustc_hir::intravisit::{walk_expr, Visitor};
-use rustc_hir::{Block, Expr, ExprKind, HirId, Local, Node, PatKind, PathSegment, StmtKind};
+use rustc_hir::{Block, Expr, ExprKind, HirId, LetStmt, Node, PatKind, PathSegment, StmtKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter::OnlyBodies;
 use rustc_session::declare_lint_pass;
@@ -190,7 +190,7 @@ impl<'tcx> Visitor<'tcx> for PeekableVisitor<'_, 'tcx> {
                             },
                         }
                     },
-                    Node::Local(Local { init: Some(init), .. }) => {
+                    Node::LetStmt(LetStmt { init: Some(init), .. }) => {
                         if arg_is_mut_peekable(self.cx, init) {
                             self.found_peek_call = true;
                         }
diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs
index 10a69364dae..0bab917607d 100644
--- a/clippy_lints/src/use_self.rs
+++ b/clippy_lints/src/use_self.rs
@@ -11,7 +11,7 @@ use rustc_hir::{
     self as hir, Expr, ExprKind, FnRetTy, FnSig, GenericArgsParentheses, GenericParam, GenericParamKind, HirId, Impl,
     ImplItemKind, Item, ItemKind, Pat, PatKind, Path, QPath, Ty, TyKind,
 };
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::Ty as MiddleTy;
 use rustc_session::impl_lint_pass;
@@ -193,7 +193,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
     }
 
     fn check_body(&mut self, _: &LateContext<'_>, _: &hir::Body<'_>) {
-        // `hir_ty_to_ty` cannot be called in `Body`s or it will panic (sometimes). But in bodies
+        // `lower_ty` cannot be called in `Body`s or it will panic (sometimes). But in bodies
         // we can use `cx.typeck_results.node_type(..)` to get the `ty::Ty` from a `hir::Ty`.
         // However the `node_type()` method can *only* be called in bodies.
         if let Some(&mut StackItem::Check { ref mut in_body, .. }) = self.stack.last_mut() {
@@ -224,7 +224,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
             && let ty = if in_body > 0 {
                 cx.typeck_results().node_type(hir_ty.hir_id)
             } else {
-                hir_ty_to_ty(cx.tcx, hir_ty)
+                lower_ty(cx.tcx, hir_ty)
             }
             && let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity()
             && same_type_and_consts(ty, impl_ty)
diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs
index 538a748089e..7b43abeef67 100644
--- a/clippy_lints/src/utils/author.rs
+++ b/clippy_lints/src/utils/author.rs
@@ -649,6 +649,8 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                     BindingAnnotation::REF => "REF",
                     BindingAnnotation::MUT => "MUT",
                     BindingAnnotation::REF_MUT => "REF_MUT",
+                    BindingAnnotation::MUT_REF => "MUT_REF",
+                    BindingAnnotation::MUT_REF_MUT => "MUT_REF_MUT",
                 };
                 kind!("Binding(BindingAnnotation::{ann}, _, {name}, {sub})");
                 self.ident(name);
@@ -689,6 +691,11 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                 kind!("Box({pat})");
                 self.pat(pat);
             },
+            PatKind::Deref(pat) => {
+                bind!(self, pat);
+                kind!("Deref({pat})");
+                self.pat(pat);
+            },
             PatKind::Ref(pat, muta) => {
                 bind!(self, pat);
                 kind!("Ref({pat}, Mutability::{muta:?})");
diff --git a/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/clippy_lints/src/utils/internal_lints/metadata_collector.rs
index 5fb80059e03..5c1ebb922f1 100644
--- a/clippy_lints/src/utils/internal_lints/metadata_collector.rs
+++ b/clippy_lints/src/utils/internal_lints/metadata_collector.rs
@@ -994,7 +994,7 @@ impl<'a, 'hir> Visitor<'hir> for ApplicabilityResolver<'a, 'hir> {
 }
 
 /// This returns the parent local node if the expression is a reference one
-fn get_parent_local<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'hir>) -> Option<&'hir hir::Local<'hir>> {
+fn get_parent_local<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'hir>) -> Option<&'hir hir::LetStmt<'hir>> {
     if let ExprKind::Path(QPath::Resolved(_, path)) = expr.kind {
         if let hir::def::Res::Local(local_hir) = path.res {
             return get_parent_local_hir_id(cx, local_hir);
@@ -1004,9 +1004,9 @@ fn get_parent_local<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'hir>) -
     None
 }
 
-fn get_parent_local_hir_id<'hir>(cx: &LateContext<'hir>, hir_id: hir::HirId) -> Option<&'hir hir::Local<'hir>> {
+fn get_parent_local_hir_id<'hir>(cx: &LateContext<'hir>, hir_id: hir::HirId) -> Option<&'hir hir::LetStmt<'hir>> {
     match cx.tcx.parent_hir_node(hir_id) {
-        hir::Node::Local(local) => Some(local),
+        hir::Node::LetStmt(local) => Some(local),
         hir::Node::Pat(pattern) => get_parent_local_hir_id(cx, pattern.hir_id),
         _ => None,
     }
diff --git a/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs b/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
index 777fe544b24..63fcbd61528 100644
--- a/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
+++ b/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
@@ -42,7 +42,7 @@ impl LateLintPass<'_> for MsrvAttrImpl {
                     .filter(|t| matches!(t.unpack(), GenericArgKind::Type(_)))
                     .any(|t| match_type(cx, t.expect_ty(), &paths::MSRV))
             })
-            && !items.iter().any(|item| item.ident.name == sym!(enter_lint_attrs))
+            && !items.iter().any(|item| item.ident.name == sym!(check_attributes))
         {
             let context = if is_late_pass { "LateContext" } else { "EarlyContext" };
             let lint_pass = if is_late_pass { "LateLintPass" } else { "EarlyLintPass" };
diff --git a/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
index 2fa55c5ff52..8cf42832761 100644
--- a/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
+++ b/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
@@ -6,7 +6,7 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
-use rustc_hir::{Expr, ExprKind, Local, Mutability, Node};
+use rustc_hir::{Expr, ExprKind, LetStmt, Mutability, Node};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir::interpret::{Allocation, GlobalAlloc};
 use rustc_middle::mir::ConstValue;
@@ -216,7 +216,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Vec<Str
     match peel_hir_expr_refs(expr).0.kind {
         ExprKind::Path(ref qpath) => match cx.qpath_res(qpath, expr.hir_id) {
             Res::Local(hir_id) => {
-                if let Node::Local(Local { init: Some(init), .. }) = cx.tcx.parent_hir_node(hir_id) {
+                if let Node::LetStmt(LetStmt { init: Some(init), .. }) = cx.tcx.parent_hir_node(hir_id) {
                     path_to_matched_type(cx, init)
                 } else {
                     None
diff --git a/clippy_lints/src/vec.rs b/clippy_lints/src/vec.rs
index 7cfcf3fe946..27ead55bf39 100644
--- a/clippy_lints/src/vec.rs
+++ b/clippy_lints/src/vec.rs
@@ -9,7 +9,7 @@ use clippy_utils::ty::is_copy;
 use clippy_utils::visitors::for_each_local_use_after_expr;
 use clippy_utils::{get_parent_expr, higher, is_trait_method};
 use rustc_errors::Applicability;
-use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, Local, Mutability, Node, Pat, PatKind};
+use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, LetStmt, Mutability, Node, Pat, PatKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_middle::ty::layout::LayoutOf;
@@ -63,7 +63,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
         match cx.tcx.parent_hir_node(expr.hir_id) {
             // search for `let foo = vec![_]` expressions where all uses of `foo`
             // adjust to slices or call a method that exist on slices (e.g. len)
-            Node::Local(Local {
+            Node::LetStmt(LetStmt {
                 ty: None,
                 pat:
                     Pat {
@@ -93,7 +93,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
                 }
             },
             // if the local pattern has a specified type, do not lint.
-            Node::Local(Local { ty: Some(_), .. }) if higher::VecArgs::hir(cx, expr).is_some() => {
+            Node::LetStmt(LetStmt { ty: Some(_), .. }) if higher::VecArgs::hir(cx, expr).is_some() => {
                 self.span_to_lint_map.insert(callsite, None);
             },
             // search for `for _ in vec![...]`
diff --git a/clippy_lints/src/vec_init_then_push.rs b/clippy_lints/src/vec_init_then_push.rs
index ac3b2bdaf65..b58a4fb8474 100644
--- a/clippy_lints/src/vec_init_then_push.rs
+++ b/clippy_lints/src/vec_init_then_push.rs
@@ -7,7 +7,7 @@ use core::ops::ControlFlow;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{
-    BindingAnnotation, Block, Expr, ExprKind, HirId, Local, Mutability, PatKind, QPath, Stmt, StmtKind, UnOp,
+    BindingAnnotation, Block, Expr, ExprKind, HirId, LetStmt, Mutability, PatKind, QPath, Stmt, StmtKind, UnOp,
 };
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
@@ -157,7 +157,7 @@ impl<'tcx> LateLintPass<'tcx> for VecInitThenPush {
         self.searcher = None;
     }
 
-    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) {
+    fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx LetStmt<'tcx>) {
         if let Some(init_expr) = local.init
             && let PatKind::Binding(BindingAnnotation::MUT, id, name, None) = local.pat.kind
             && !in_external_macro(cx.sess(), local.span)
diff --git a/clippy_lints/src/zero_repeat_side_effects.rs b/clippy_lints/src/zero_repeat_side_effects.rs
index 852d04cd21b..143fecdd237 100644
--- a/clippy_lints/src/zero_repeat_side_effects.rs
+++ b/clippy_lints/src/zero_repeat_side_effects.rs
@@ -78,7 +78,7 @@ fn inner_check(cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>, inner_expr:
         let parent_hir_node = cx.tcx.parent_hir_node(expr.hir_id);
         let return_type = cx.typeck_results().expr_ty(expr);
 
-        if let Node::Local(l) = parent_hir_node {
+        if let Node::LetStmt(l) = parent_hir_node {
             array_span_lint(
                 cx,
                 l.span,
diff --git a/clippy_lints/src/zero_sized_map_values.rs b/clippy_lints/src/zero_sized_map_values.rs
index 4aaf3b0a0b6..d1f7c6417c7 100644
--- a/clippy_lints/src/zero_sized_map_values.rs
+++ b/clippy_lints/src/zero_sized_map_values.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_help;
 use clippy_utils::ty::{is_normalizable, is_type_diagnostic_item};
 use rustc_hir::{self as hir, HirId, ItemKind, Node};
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir_analysis::lower_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_middle::ty::{Adt, Ty, TypeVisitableExt};
@@ -91,5 +91,5 @@ fn ty_from_hir_ty<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'t
                 None
             }
         })
-        .unwrap_or_else(|| hir_ty_to_ty(cx.tcx, hir_ty))
+        .unwrap_or_else(|| lower_ty(cx.tcx, hir_ty))
 }
diff --git a/clippy_utils/src/ast_utils.rs b/clippy_utils/src/ast_utils.rs
index 93b0913a6b7..f594a40ff59 100644
--- a/clippy_utils/src/ast_utils.rs
+++ b/clippy_utils/src/ast_utils.rs
@@ -198,7 +198,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
         },
         (AssignOp(lo, lp, lv), AssignOp(ro, rp, rv)) => lo.node == ro.node && eq_expr(lp, rp) && eq_expr(lv, rv),
         (Field(lp, lf), Field(rp, rf)) => eq_id(*lf, *rf) && eq_expr(lp, rp),
-        (Match(ls, la), Match(rs, ra)) => eq_expr(ls, rs) && over(la, ra, eq_arm),
+        (Match(ls, la, lkind), Match(rs, ra, rkind)) => (lkind == rkind) && eq_expr(ls, rs) && over(la, ra, eq_arm),
         (
             Closure(box ast::Closure {
                 binder: lb,
diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs
index cd22174f5c2..253ae3aca68 100644
--- a/clippy_utils/src/consts.rs
+++ b/clippy_utils/src/consts.rs
@@ -17,7 +17,7 @@ use rustc_span::def_id::DefId;
 use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::SyntaxContext;
 use rustc_target::abi::Size;
-use std::cmp::Ordering::{self, Equal};
+use std::cmp::Ordering;
 use std::hash::{Hash, Hasher};
 use std::iter;
 
@@ -207,7 +207,7 @@ impl<'tcx> Constant<'tcx> {
                     .zip(r)
                     .zip(tys)
                     .map(|((li, ri), cmp_type)| Self::partial_cmp(tcx, cmp_type, li, ri))
-                    .find(|r| r.map_or(true, |o| o != Equal))
+                    .find(|r| r.map_or(true, |o| o != Ordering::Equal))
                     .unwrap_or_else(|| Some(l.len().cmp(&r.len()))),
                 _ => None,
             },
@@ -217,7 +217,7 @@ impl<'tcx> Constant<'tcx> {
                 };
                 iter::zip(l, r)
                     .map(|(li, ri)| Self::partial_cmp(tcx, cmp_type, li, ri))
-                    .find(|r| r.map_or(true, |o| o != Equal))
+                    .find(|r| r.map_or(true, |o| o != Ordering::Equal))
                     .unwrap_or_else(|| Some(l.len().cmp(&r.len())))
             },
             (Self::Repeat(lv, ls), Self::Repeat(rv, rs)) => {
@@ -230,7 +230,7 @@ impl<'tcx> Constant<'tcx> {
                     lv,
                     rv,
                 ) {
-                    Some(Equal) => Some(ls.cmp(rs)),
+                    Some(Ordering::Equal) => Some(ls.cmp(rs)),
                     x => x,
                 }
             },
@@ -361,7 +361,7 @@ pub enum FullInt {
 impl PartialEq for FullInt {
     #[must_use]
     fn eq(&self, other: &Self) -> bool {
-        self.cmp(other) == Equal
+        self.cmp(other) == Ordering::Equal
     }
 }
 
@@ -819,7 +819,7 @@ pub fn mir_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) ->
             ty::Float(FloatTy::F64) => Some(Constant::F64(f64::from_bits(
                 int.try_into().expect("invalid f64 bit representation"),
             ))),
-            ty::RawPtr(_) => Some(Constant::RawPtr(int.assert_bits(int.size()))),
+            ty::RawPtr(_, _) => Some(Constant::RawPtr(int.assert_bits(int.size()))),
             _ => None,
         },
         (_, ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Str) => {
diff --git a/clippy_utils/src/higher.rs b/clippy_utils/src/higher.rs
index 9f69941cfc7..801a9852159 100644
--- a/clippy_utils/src/higher.rs
+++ b/clippy_utils/src/higher.rs
@@ -102,7 +102,7 @@ impl<'hir> IfLet<'hir> {
         if let ExprKind::If(
             Expr {
                 kind:
-                    ExprKind::Let(&hir::Let {
+                    ExprKind::Let(&hir::LetExpr {
                         pat: let_pat,
                         init: let_expr,
                         span: let_span,
@@ -379,7 +379,7 @@ impl<'hir> WhileLet<'hir> {
                             ExprKind::If(
                                 Expr {
                                     kind:
-                                        ExprKind::Let(&hir::Let {
+                                        ExprKind::Let(&hir::LetExpr {
                                             pat: let_pat,
                                             init: let_expr,
                                             span: let_span,
diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs
index 106d1d0d77f..f8bbe997774 100644
--- a/clippy_utils/src/hir_utils.rs
+++ b/clippy_utils/src/hir_utils.rs
@@ -8,7 +8,7 @@ use rustc_hir::def::Res;
 use rustc_hir::MatchSource::TryDesugar;
 use rustc_hir::{
     ArrayLen, BinOpKind, BindingAnnotation, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg,
-    GenericArgs, HirId, HirIdMap, InlineAsmOperand, Let, Lifetime, LifetimeName, Pat, PatField, PatKind, Path,
+    GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName, Pat, PatField, PatKind, Path,
     PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding,
 };
 use rustc_lexer::{tokenize, TokenKind};
@@ -837,7 +837,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                     }
                 }
             },
-            ExprKind::Let(Let { pat, init, ty, .. }) => {
+            ExprKind::Let(LetExpr { pat, init, ty, .. }) => {
                 self.hash_expr(init);
                 if let Some(ty) = ty {
                     self.hash_ty(ty);
@@ -954,7 +954,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                     self.hash_pat(pat);
                 }
             },
-            PatKind::Box(pat) => self.hash_pat(pat),
+            PatKind::Box(pat) | PatKind::Deref(pat) => self.hash_pat(pat),
             PatKind::Lit(expr) => self.hash_expr(expr),
             PatKind::Or(pats) => {
                 for pat in pats {
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 5e356f554ef..37c12dd850c 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -99,22 +99,21 @@ use rustc_hir::hir_id::{HirIdMap, HirIdSet};
 use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
 use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
 use rustc_hir::{
-    self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Destination, Expr,
+    self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, ByRef, Closure, Destination, Expr,
     ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, Item,
-    ItemKind, LangItem, Local, MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path, PathSegment, PrimTy,
-    QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp,
+    ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path, PathSegment,
+    PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp,
 };
 use rustc_lexer::{tokenize, TokenKind};
 use rustc_lint::{LateContext, Level, Lint, LintContext};
 use rustc_middle::hir::place::PlaceBase;
 use rustc_middle::mir::Const;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
-use rustc_middle::ty::binding::BindingMode;
 use rustc_middle::ty::fast_reject::SimplifiedType;
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::{
     self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, FloatTy, GenericArgsRef, IntTy, ParamEnv,
-    ParamEnvAnd, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, UintTy, UpvarCapture,
+    ParamEnvAnd, Ty, TyCtxt, TypeVisitableExt, UintTy, UpvarCapture,
 };
 use rustc_span::hygiene::{ExpnKind, MacroKind};
 use rustc_span::source_map::SourceMap;
@@ -133,14 +132,14 @@ use rustc_middle::hir::nested_filter;
 #[macro_export]
 macro_rules! extract_msrv_attr {
     ($context:ident) => {
-        fn enter_lint_attrs(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) {
+        fn check_attributes(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) {
             let sess = rustc_lint::LintContext::sess(cx);
-            self.msrv.enter_lint_attrs(sess, attrs);
+            self.msrv.check_attributes(sess, attrs);
         }
 
-        fn exit_lint_attrs(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) {
+        fn check_attributes_post(&mut self, cx: &rustc_lint::$context<'_>, attrs: &[rustc_ast::ast::Attribute]) {
             let sess = rustc_lint::LintContext::sess(cx);
-            self.msrv.exit_lint_attrs(sess, attrs);
+            self.msrv.check_attributes_post(sess, attrs);
         }
     };
 }
@@ -186,7 +185,7 @@ pub fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr
 pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> {
     if let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
         && matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..))
-        && let Node::Local(local) = cx.tcx.parent_hir_node(hir_id)
+        && let Node::LetStmt(local) = cx.tcx.parent_hir_node(hir_id)
     {
         return local.init;
     }
@@ -1009,11 +1008,12 @@ pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind {
             .typeck_results()
             .extract_binding_mode(cx.sess(), id, span)
             .unwrap()
+            .0
         {
-            BindingMode::BindByValue(_) if !is_copy(cx, cx.typeck_results().node_type(id)) => {
+            ByRef::No if !is_copy(cx, cx.typeck_results().node_type(id)) => {
                 capture = CaptureKind::Value;
             },
-            BindingMode::BindByReference(Mutability::Mut) if capture != CaptureKind::Value => {
+            ByRef::Yes(Mutability::Mut) if capture != CaptureKind::Value => {
                 capture = CaptureKind::Ref(Mutability::Mut);
             },
             _ => (),
@@ -1043,7 +1043,7 @@ pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind {
             .get(child_id)
             .map_or(&[][..], |x| &**x)
         {
-            if let rustc_ty::RawPtr(TypeAndMut { mutbl: mutability, .. }) | rustc_ty::Ref(_, _, mutability) =
+            if let rustc_ty::RawPtr(_, mutability) | rustc_ty::Ref(_, _, mutability) =
                 *adjust.last().map_or(target, |a| a.target).kind()
             {
                 return CaptureKind::Ref(mutability);
@@ -1082,7 +1082,7 @@ pub fn capture_local_usage(cx: &LateContext<'_>, e: &Expr<'_>) -> CaptureKind {
                 },
                 _ => break,
             },
-            Node::Local(l) => match pat_capture_kind(cx, l.pat) {
+            Node::LetStmt(l) => match pat_capture_kind(cx, l.pat) {
                 CaptureKind::Value => break,
                 capture @ CaptureKind::Ref(_) => return capture,
             },
@@ -1360,7 +1360,7 @@ pub fn get_enclosing_loop_or_multi_call_closure<'tcx>(
                 ExprKind::Closure { .. } | ExprKind::Loop(..) => return Some(e),
                 _ => (),
             },
-            Node::Stmt(_) | Node::Block(_) | Node::Local(_) | Node::Arm(_) => (),
+            Node::Stmt(_) | Node::Block(_) | Node::LetStmt(_) | Node::Arm(_) => (),
             _ => break,
         }
     }
@@ -1465,7 +1465,7 @@ pub fn is_else_clause(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
 pub fn is_inside_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
     let mut child_id = expr.hir_id;
     for (parent_id, node) in tcx.hir().parent_iter(child_id) {
-        if let Node::Local(Local {
+        if let Node::LetStmt(LetStmt {
             init: Some(init),
             els: Some(els),
             ..
@@ -1485,7 +1485,7 @@ pub fn is_inside_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
 pub fn is_else_clause_in_let_else(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
     let mut child_id = expr.hir_id;
     for (parent_id, node) in tcx.hir().parent_iter(child_id) {
-        if let Node::Local(Local { els: Some(els), .. }) = node
+        if let Node::LetStmt(LetStmt { els: Some(els), .. }) = node
             && els.hir_id == child_id
         {
             return true;
@@ -1681,7 +1681,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
     match pat.kind {
         PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable.
         PatKind::Binding(_, _, _, pat) => pat.map_or(false, |pat| is_refutable(cx, pat)),
-        PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat),
+        PatKind::Box(pat) | PatKind::Deref(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat),
         PatKind::Path(ref qpath) => is_enum_variant(cx, qpath, pat.hir_id),
         PatKind::Or(pats) => {
             // TODO: should be the honest check, that pats is exhaustive set
@@ -2038,7 +2038,7 @@ fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
             .typeck_results()
             .pat_binding_modes()
             .get(pat.hir_id)
-            .is_some_and(|mode| matches!(mode, BindingMode::BindByReference(_)))
+            .is_some_and(|mode| matches!(mode.0, ByRef::Yes(_)))
         {
             // If a tuple `(x, y)` is of type `&(i32, i32)`, then due to match ergonomics,
             // the inner patterns become references. Don't consider this the identity function
@@ -2161,7 +2161,7 @@ pub fn is_expr_used_or_unified(tcx: TyCtxt<'_>, expr: &Expr<'_>) -> bool {
             Node::Stmt(Stmt {
                 kind: StmtKind::Expr(_)
                     | StmtKind::Semi(_)
-                    | StmtKind::Let(Local {
+                    | StmtKind::Let(LetStmt {
                         pat: Pat {
                             kind: PatKind::Wild,
                             ..
@@ -2642,7 +2642,7 @@ pub struct ExprUseCtxt<'tcx> {
 /// The node which consumes a value.
 pub enum ExprUseNode<'tcx> {
     /// Assignment to, or initializer for, a local
-    Local(&'tcx Local<'tcx>),
+    LetStmt(&'tcx LetStmt<'tcx>),
     /// Initializer for a const or static item.
     ConstStatic(OwnerId),
     /// Implicit or explicit return from a function.
@@ -2674,7 +2674,7 @@ impl<'tcx> ExprUseNode<'tcx> {
     /// Gets the needed type as it's defined without any type inference.
     pub fn defined_ty(&self, cx: &LateContext<'tcx>) -> Option<DefinedTy<'tcx>> {
         match *self {
-            Self::Local(Local { ty: Some(ty), .. }) => Some(DefinedTy::Hir(ty)),
+            Self::LetStmt(LetStmt { ty: Some(ty), .. }) => Some(DefinedTy::Hir(ty)),
             Self::ConstStatic(id) => Some(DefinedTy::Mir(
                 cx.param_env
                     .and(Binder::dummy(cx.tcx.type_of(id).instantiate_identity())),
@@ -2734,7 +2734,7 @@ impl<'tcx> ExprUseNode<'tcx> {
                 let sig = cx.tcx.fn_sig(id).skip_binder();
                 Some(DefinedTy::Mir(cx.tcx.param_env(id).and(sig.input(i))))
             },
-            Self::Local(_) | Self::FieldAccess(..) | Self::Callee | Self::Expr | Self::Other => None,
+            Self::LetStmt(_) | Self::FieldAccess(..) | Self::Callee | Self::Expr | Self::Other => None,
         }
     }
 }
@@ -2773,7 +2773,7 @@ pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> Optio
     .continue_value()
     .map(|(use_node, child_id)| {
         let node = match use_node {
-            Node::Local(l) => ExprUseNode::Local(l),
+            Node::LetStmt(l) => ExprUseNode::LetStmt(l),
             Node::ExprField(field) => ExprUseNode::Field(field),
 
             Node::Item(&Item {
@@ -3161,7 +3161,7 @@ pub fn is_never_expr<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option<
             }
         }
 
-        fn visit_local(&mut self, l: &'tcx Local<'_>) {
+        fn visit_local(&mut self, l: &'tcx LetStmt<'_>) {
             if let Some(e) = l.init {
                 self.visit_expr(e);
             }
@@ -3238,7 +3238,7 @@ fn get_path_to_ty<'tcx>(tcx: TyCtxt<'tcx>, from: LocalDefId, ty: Ty<'tcx>, args:
         rustc_ty::Array(..)
         | rustc_ty::Dynamic(..)
         | rustc_ty::Never
-        | rustc_ty::RawPtr(_)
+        | rustc_ty::RawPtr(_, _)
         | rustc_ty::Ref(..)
         | rustc_ty::Slice(_)
         | rustc_ty::Tuple(_) => format!("<{}>", EarlyBinder::bind(ty).instantiate(tcx, args)),
diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs
index dadb0d662ce..325c9bee057 100644
--- a/clippy_utils/src/qualify_min_const_fn.rs
+++ b/clippy_utils/src/qualify_min_const_fn.rs
@@ -112,7 +112,7 @@ fn check_rvalue<'tcx>(
         Rvalue::Repeat(operand, _)
         | Rvalue::Use(operand)
         | Rvalue::Cast(
-            CastKind::PointerFromExposedAddress
+            CastKind::PointerWithExposedProvenance
             | CastKind::IntToInt
             | CastKind::FloatToInt
             | CastKind::IntToFloat
@@ -149,7 +149,7 @@ fn check_rvalue<'tcx>(
                 Err((span, "unsizing casts are not allowed in const fn".into()))
             }
         },
-        Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => {
+        Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {
             Err((span, "casting pointers to ints is unstable in const fn".into()))
         },
         Rvalue::Cast(CastKind::DynStar, _, _) => {
@@ -174,7 +174,7 @@ fn check_rvalue<'tcx>(
                 ))
             }
         },
-        Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::UbCheck(_), _)
+        Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::UbChecks, _)
         | Rvalue::ShallowInitBox(_, _) => Ok(()),
         Rvalue::UnaryOp(_, operand) => {
             let ty = operand.ty(body, tcx);
diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs
index 3924eb5a81c..ab1be66dc78 100644
--- a/clippy_utils/src/ty.rs
+++ b/clippy_utils/src/ty.rs
@@ -96,7 +96,11 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'
                         return false;
                     }
 
-                    for (predicate, _span) in cx.tcx.explicit_item_bounds(def_id).instantiate_identity_iter_copied() {
+                    for (predicate, _span) in cx
+                        .tcx
+                        .explicit_item_super_predicates(def_id)
+                        .instantiate_identity_iter_copied()
+                    {
                         match predicate.kind().skip_binder() {
                             // For `impl Trait<U>`, it will register a predicate of `T: Trait<U>`, so we go through
                             // and check substitutions to find `U`.
@@ -331,14 +335,14 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
     match ty.kind() {
         ty::Adt(adt, _) => cx.tcx.has_attr(adt.did(), sym::must_use),
         ty::Foreign(did) => cx.tcx.has_attr(*did, sym::must_use),
-        ty::Slice(ty) | ty::Array(ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) | ty::Ref(_, ty, _) => {
+        ty::Slice(ty) | ty::Array(ty, _) | ty::RawPtr(ty, _) | ty::Ref(_, ty, _) => {
             // for the Array case we don't need to care for the len == 0 case
             // because we don't want to lint functions returning empty arrays
             is_must_use_ty(cx, *ty)
         },
         ty::Tuple(args) => args.iter().any(|ty| is_must_use_ty(cx, ty)),
         ty::Alias(ty::Opaque, AliasTy { def_id, .. }) => {
-            for (predicate, _) in cx.tcx.explicit_item_bounds(def_id).skip_binder() {
+            for (predicate, _) in cx.tcx.explicit_item_super_predicates(def_id).skip_binder() {
                 if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() {
                     if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) {
                         return true;
@@ -739,7 +743,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
         ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) => sig_from_bounds(
             cx,
             ty,
-            cx.tcx.item_bounds(def_id).iter_instantiated(cx.tcx, args),
+            cx.tcx.item_super_predicates(def_id).iter_instantiated(cx.tcx, args),
             cx.tcx.opt_parent(def_id),
         ),
         ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)),
diff --git a/clippy_utils/src/ty/type_certainty/mod.rs b/clippy_utils/src/ty/type_certainty/mod.rs
index 7913926928f..762830ffd78 100644
--- a/clippy_utils/src/ty/type_certainty/mod.rs
+++ b/clippy_utils/src/ty/type_certainty/mod.rs
@@ -242,7 +242,7 @@ fn path_segment_certainty(
             Node::Param(..) => Certainty::Certain(None),
             // A local's type is certain if its type annotation is certain or it has an initializer whose
             // type is certain.
-            Node::Local(local) => {
+            Node::LetStmt(local) => {
                 let lhs = local.ty.map_or(Certainty::Uncertain, |ty| type_certainty(cx, ty));
                 let rhs = local
                     .init
diff --git a/clippy_utils/src/visitors.rs b/clippy_utils/src/visitors.rs
index a4c06c0e637..a3f3b32ed37 100644
--- a/clippy_utils/src/visitors.rs
+++ b/clippy_utils/src/visitors.rs
@@ -5,7 +5,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::intravisit::{self, walk_block, walk_expr, Visitor};
 use rustc_hir::{
-    AnonConst, Arm, Block, BlockCheckMode, Body, BodyId, Expr, ExprKind, HirId, ItemId, ItemKind, Let, Pat, QPath,
+    AnonConst, Arm, Block, BlockCheckMode, Body, BodyId, Expr, ExprKind, HirId, ItemId, ItemKind, LetExpr, Pat, QPath,
     Stmt, UnOp, UnsafeSource, Unsafety,
 };
 use rustc_lint::LateContext;
@@ -624,7 +624,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
             | ExprKind::Field(e, _)
             | ExprKind::Unary(UnOp::Deref, e)
             | ExprKind::Match(e, ..)
-            | ExprKind::Let(&Let { init: e, .. }) => {
+            | ExprKind::Let(&LetExpr { init: e, .. }) => {
                 helper(typeck, false, e, f)?;
             },
             ExprKind::Block(&Block { expr: Some(e), .. }, _) | ExprKind::Cast(e, _) | ExprKind::Unary(_, e) => {
diff --git a/rust-toolchain b/rust-toolchain
index a63e66f3214..b2fe5c8bee7 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2024-03-21"
+channel = "nightly-2024-04-04"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/tests/ui-toml/needless_raw_string_hashes_one_allowed/clippy.toml b/tests/ui-toml/needless_raw_string_hashes_one_allowed/clippy.toml
new file mode 100644
index 00000000000..2f3d60be3a7
--- /dev/null
+++ b/tests/ui-toml/needless_raw_string_hashes_one_allowed/clippy.toml
@@ -0,0 +1 @@
+allow-one-hash-in-raw-strings = true
diff --git a/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.fixed b/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.fixed
new file mode 100644
index 00000000000..fd20bdff6e2
--- /dev/null
+++ b/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.fixed
@@ -0,0 +1,9 @@
+#![allow(clippy::no_effect, unused)]
+#![warn(clippy::needless_raw_string_hashes)]
+
+fn main() {
+    r#"\aaa"#;
+    r#"\aaa"#;
+    r#"Hello "world"!"#;
+    r####" "### "## "# "####;
+}
diff --git a/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs b/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs
new file mode 100644
index 00000000000..3c6c2463700
--- /dev/null
+++ b/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs
@@ -0,0 +1,9 @@
+#![allow(clippy::no_effect, unused)]
+#![warn(clippy::needless_raw_string_hashes)]
+
+fn main() {
+    r#"\aaa"#;
+    r##"\aaa"##;
+    r##"Hello "world"!"##;
+    r######" "### "## "# "######;
+}
diff --git a/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.stderr b/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.stderr
new file mode 100644
index 00000000000..421ad66e4c9
--- /dev/null
+++ b/tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.stderr
@@ -0,0 +1,40 @@
+error: unnecessary hashes around raw string literal
+  --> tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs:6:5
+   |
+LL |     r##"\aaa"##;
+   |     ^^^^^^^^^^^
+   |
+   = note: `-D clippy::needless-raw-string-hashes` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::needless_raw_string_hashes)]`
+help: remove one hash from both sides of the string literal
+   |
+LL -     r##"\aaa"##;
+LL +     r#"\aaa"#;
+   |
+
+error: unnecessary hashes around raw string literal
+  --> tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs:7:5
+   |
+LL |     r##"Hello "world"!"##;
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove one hash from both sides of the string literal
+   |
+LL -     r##"Hello "world"!"##;
+LL +     r#"Hello "world"!"#;
+   |
+
+error: unnecessary hashes around raw string literal
+  --> tests/ui-toml/needless_raw_string_hashes_one_allowed/needless_raw_string_hashes.rs:8:5
+   |
+LL |     r######" "### "## "# "######;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove 2 hashes from both sides of the string literal
+   |
+LL -     r######" "### "## "# "######;
+LL +     r####" "### "## "# "####;
+   |
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/builtin_type_shadow.stderr b/tests/ui/builtin_type_shadow.stderr
index 1e15cdee772..033204af925 100644
--- a/tests/ui/builtin_type_shadow.stderr
+++ b/tests/ui/builtin_type_shadow.stderr
@@ -19,6 +19,7 @@ LL |     42
    |
    = note: expected type parameter `u32`
                         found type `{integer}`
+   = note: the caller chooses a type for `u32` which can be different from `i32`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/crashes/ice-6179.rs b/tests/ui/crashes/ice-6179.rs
index fffc0f7d0d4..91160eef03d 100644
--- a/tests/ui/crashes/ice-6179.rs
+++ b/tests/ui/crashes/ice-6179.rs
@@ -1,5 +1,5 @@
 //! This is a minimal reproducer for the ICE in https://github.com/rust-lang/rust-clippy/pull/6179.
-//! The ICE is mainly caused by using `hir_ty_to_ty`. See the discussion in the PR for details.
+//! The ICE is mainly caused by using `lower_ty`. See the discussion in the PR for details.
 
 #![warn(clippy::use_self)]
 #![allow(dead_code, clippy::let_with_type_underscore)]
diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed
index 37e9e627c4c..ffc5b74d7bd 100644
--- a/tests/ui/use_self.fixed
+++ b/tests/ui/use_self.fixed
@@ -8,7 +8,6 @@
     clippy::from_over_into,
     clippy::self_named_constructors,
     clippy::needless_lifetimes,
-    clippy::missing_transmute_annotations,
     clippy::missing_transmute_annotations
 )]
 
diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs
index 06792034b74..eb9d96168bc 100644
--- a/tests/ui/use_self.rs
+++ b/tests/ui/use_self.rs
@@ -8,7 +8,6 @@
     clippy::from_over_into,
     clippy::self_named_constructors,
     clippy::needless_lifetimes,
-    clippy::missing_transmute_annotations,
     clippy::missing_transmute_annotations
 )]
 
diff --git a/tests/ui/use_self.stderr b/tests/ui/use_self.stderr
index 65b8ac482ab..bd5b685b45d 100644
--- a/tests/ui/use_self.stderr
+++ b/tests/ui/use_self.stderr
@@ -1,5 +1,5 @@
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:24:21
+  --> tests/ui/use_self.rs:23:21
    |
 LL |         fn new() -> Foo {
    |                     ^^^ help: use the applicable keyword: `Self`
@@ -8,253 +8,253 @@ LL |         fn new() -> Foo {
    = help: to override `-D warnings` add `#[allow(clippy::use_self)]`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:25:13
+  --> tests/ui/use_self.rs:24:13
    |
 LL |             Foo {}
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:27:22
+  --> tests/ui/use_self.rs:26:22
    |
 LL |         fn test() -> Foo {
    |                      ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:28:13
+  --> tests/ui/use_self.rs:27:13
    |
 LL |             Foo::new()
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:33:25
+  --> tests/ui/use_self.rs:32:25
    |
 LL |         fn default() -> Foo {
    |                         ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:34:13
+  --> tests/ui/use_self.rs:33:13
    |
 LL |             Foo::new()
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:75:28
+  --> tests/ui/use_self.rs:74:28
    |
 LL |         fn clone(&self) -> Foo<'a> {
    |                            ^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:108:24
+  --> tests/ui/use_self.rs:107:24
    |
 LL |         fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {
    |                        ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:108:55
+  --> tests/ui/use_self.rs:107:55
    |
 LL |         fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {
    |                                                       ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:123:13
+  --> tests/ui/use_self.rs:122:13
    |
 LL |             TS(0)
    |             ^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:158:29
+  --> tests/ui/use_self.rs:157:29
    |
 LL |                 fn bar() -> Bar {
    |                             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:159:21
+  --> tests/ui/use_self.rs:158:21
    |
 LL |                     Bar { foo: Foo {} }
    |                     ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:170:21
+  --> tests/ui/use_self.rs:169:21
    |
 LL |         fn baz() -> Foo {
    |                     ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:171:13
+  --> tests/ui/use_self.rs:170:13
    |
 LL |             Foo {}
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:188:21
+  --> tests/ui/use_self.rs:187:21
    |
 LL |             let _ = Enum::B(42);
    |                     ^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:189:21
+  --> tests/ui/use_self.rs:188:21
    |
 LL |             let _ = Enum::C { field: true };
    |                     ^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:190:21
+  --> tests/ui/use_self.rs:189:21
    |
 LL |             let _ = Enum::A;
    |                     ^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:232:13
+  --> tests/ui/use_self.rs:231:13
    |
 LL |             nested::A::fun_1();
    |             ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:233:13
+  --> tests/ui/use_self.rs:232:13
    |
 LL |             nested::A::A;
    |             ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:235:13
+  --> tests/ui/use_self.rs:234:13
    |
 LL |             nested::A {};
    |             ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:254:13
+  --> tests/ui/use_self.rs:253:13
    |
 LL |             TestStruct::from_something()
    |             ^^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:268:25
+  --> tests/ui/use_self.rs:267:25
    |
 LL |         async fn g() -> S {
    |                         ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:269:13
+  --> tests/ui/use_self.rs:268:13
    |
 LL |             S {}
    |             ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:273:16
+  --> tests/ui/use_self.rs:272:16
    |
 LL |             &p[S::A..S::B]
    |                ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:273:22
+  --> tests/ui/use_self.rs:272:22
    |
 LL |             &p[S::A..S::B]
    |                      ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:296:29
+  --> tests/ui/use_self.rs:295:29
    |
 LL |         fn foo(value: T) -> Foo<T> {
    |                             ^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:297:13
+  --> tests/ui/use_self.rs:296:13
    |
 LL |             Foo::<T> { value }
    |             ^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:469:13
+  --> tests/ui/use_self.rs:468:13
    |
 LL |             A::new::<submod::B>(submod::B {})
    |             ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:506:13
+  --> tests/ui/use_self.rs:505:13
    |
 LL |             S2::new()
    |             ^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:543:17
+  --> tests/ui/use_self.rs:542:17
    |
 LL |                 Foo::Bar => unimplemented!(),
    |                 ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:544:17
+  --> tests/ui/use_self.rs:543:17
    |
 LL |                 Foo::Baz => unimplemented!(),
    |                 ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:550:20
+  --> tests/ui/use_self.rs:549:20
    |
 LL |             if let Foo::Bar = self {
    |                    ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:574:17
+  --> tests/ui/use_self.rs:573:17
    |
 LL |                 Something::Num(n) => *n,
    |                 ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:575:17
+  --> tests/ui/use_self.rs:574:17
    |
 LL |                 Something::TupleNums(n, _m) => *n,
    |                 ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:576:17
+  --> tests/ui/use_self.rs:575:17
    |
 LL |                 Something::StructNums { one, two: _ } => *one,
    |                 ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:582:17
+  --> tests/ui/use_self.rs:581:17
    |
 LL |                 crate::issue8845::Something::Num(n) => *n,
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:583:17
+  --> tests/ui/use_self.rs:582:17
    |
 LL |                 crate::issue8845::Something::TupleNums(n, _m) => *n,
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:584:17
+  --> tests/ui/use_self.rs:583:17
    |
 LL |                 crate::issue8845::Something::StructNums { one, two: _ } => *one,
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:600:17
+  --> tests/ui/use_self.rs:599:17
    |
 LL |             let Foo(x) = self;
    |                 ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:605:17
+  --> tests/ui/use_self.rs:604:17
    |
 LL |             let crate::issue8845::Foo(x) = self;
    |                 ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:612:17
+  --> tests/ui/use_self.rs:611:17
    |
 LL |             let Bar { x, .. } = self;
    |                 ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:617:17
+  --> tests/ui/use_self.rs:616:17
    |
 LL |             let crate::issue8845::Bar { x, .. } = self;
    |                 ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:656:17
+  --> tests/ui/use_self.rs:655:17
    |
 LL |                 E::A => {},
    |                 ^ help: use the applicable keyword: `Self`