diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index f87269960bc..44e4dea3481 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -403,8 +403,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     }
                 }
                 let typeck = self.infcx.tcx.typeck(self.mir_def_id());
-                let hir_id = hir.parent_id(expr.hir_id);
-                let parent = self.infcx.tcx.hir_node(hir_id);
+                let parent = self.infcx.tcx.parent_hir_node(expr.hir_id);
                 let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
                     && let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind
                     && let Some(def_id) = typeck.type_dependent_def_id(parent_expr.hir_id)
@@ -1660,8 +1659,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
 
         // Check that the parent of the closure is a method call,
         // with receiver matching with local's type (modulo refs)
-        let parent = hir.parent_id(closure_expr.hir_id);
-        if let hir::Node::Expr(parent) = tcx.hir_node(parent) {
+        if let hir::Node::Expr(parent) = tcx.parent_hir_node(closure_expr.hir_id) {
             if let hir::ExprKind::MethodCall(_, recv, ..) = parent.kind {
                 let recv_ty = typeck_results.expr_ty(recv);
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 9e7fd45ec19..5aed18ca456 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -944,7 +944,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         let hir = self.infcx.tcx.hir();
         let closure_id = self.mir_hir_id();
         let closure_span = self.infcx.tcx.def_span(self.mir_def_id());
-        let fn_call_id = hir.parent_id(closure_id);
+        let fn_call_id = self.infcx.tcx.parent_hir_id(closure_id);
         let node = self.infcx.tcx.hir_node(fn_call_id);
         let def_id = hir.enclosing_body_owner(fn_call_id);
         let mut look_at_return = true;
@@ -1034,7 +1034,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         if let InstanceDef::Item(def_id) = source.instance
             && let Some(Node::Expr(hir::Expr { hir_id, kind, .. })) = hir.get_if_local(def_id)
             && let ExprKind::Closure(hir::Closure { kind: hir::ClosureKind::Closure, .. }) = kind
-            && let Some(Node::Expr(expr)) = hir.find_parent(*hir_id)
+            && let Node::Expr(expr) = self.infcx.tcx.parent_hir_node(*hir_id)
         {
             let mut cur_expr = expr;
             while let ExprKind::MethodCall(path_segment, recv, _, _) = cur_expr.kind {
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index e69d2ca966b..7529ec53a98 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -214,8 +214,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 if let Some(id) = placeholder.bound.kind.get_id()
                     && let Some(placeholder_id) = id.as_local()
                     && let gat_hir_id = self.infcx.tcx.local_def_id_to_hir_id(placeholder_id)
-                    && let Some(generics_impl) =
-                        hir.get_parent(hir.parent_id(gat_hir_id)).generics()
+                    && let Some(generics_impl) = self
+                        .infcx
+                        .tcx
+                        .parent_hir_node(self.infcx.tcx.parent_hir_id(gat_hir_id))
+                        .generics()
                 {
                     Some((gat_hir_id, generics_impl))
                 } else {
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
index 98276ff2e68..1be2a2bc1f3 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
@@ -131,11 +131,10 @@ fn is_parent_const_stable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     let local_def_id = def_id.expect_local();
     let hir_id = tcx.local_def_id_to_hir_id(local_def_id);
 
-    let Some(parent) = tcx.hir().opt_parent_id(hir_id) else { return false };
-
-    if !tcx.is_const_trait_impl_raw(parent.owner.def_id.to_def_id()) {
+    let parent_owner_id = tcx.parent_hir_id(hir_id).owner;
+    if !tcx.is_const_trait_impl_raw(parent_owner_id.to_def_id()) {
         return false;
     }
 
-    tcx.lookup_const_stability(parent.owner).is_some_and(|stab| stab.is_const_stable())
+    tcx.lookup_const_stability(parent_owner_id).is_some_and(|stab| stab.is_const_stable())
 }
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index abf7a695fd2..a7a1c69b9be 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3508,7 +3508,7 @@ impl<'hir> Node<'hir> {
     /// ```ignore (illustrative)
     /// ctor
     ///     .ctor_hir_id()
-    ///     .and_then(|ctor_id| tcx.hir().find_parent(ctor_id))
+    ///     .map(|ctor_id| tcx.parent_hir_node(ctor_id))
     ///     .and_then(|parent| parent.ident())
     /// ```
     pub fn ident(&self) -> Option<Ident> {
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index d438d3e7c60..1ae3ebaebbb 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -2749,14 +2749,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         arg_idx: Option<usize>,
     ) -> Option<Ty<'tcx>> {
         let tcx = self.tcx();
-        let hir = tcx.hir();
-
         let hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn(..), ident, .. }) =
             tcx.hir_node(fn_hir_id)
         else {
             return None;
         };
-        let i = hir.get_parent(fn_hir_id).expect_item().expect_impl();
+        let i = tcx.parent_hir_node(fn_hir_id).expect_item().expect_impl();
 
         let trait_ref =
             self.instantiate_mono_trait_ref(i.of_trait.as_ref()?, self.ast_ty_to_ty(i.self_ty));
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index fbcebb7c87c..f458ff01c10 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -224,11 +224,8 @@ pub(crate) fn placeholder_type_error_diag<'tcx>(
             is_fn = true;
 
             // Check if parent is const or static
-            let parent_id = tcx.hir().parent_id(hir_ty.hir_id);
-            let parent_node = tcx.hir_node(parent_id);
-
             is_const_or_static = matches!(
-                parent_node,
+                tcx.parent_hir_node(hir_ty.hir_id),
                 Node::Item(&hir::Item {
                     kind: hir::ItemKind::Const(..) | hir::ItemKind::Static(..),
                     ..
@@ -1085,7 +1082,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<ty::PolyFnSig<
 
         ImplItem(hir::ImplItem { kind: ImplItemKind::Fn(sig, _), generics, .. }) => {
             // Do not try to infer the return type for a impl method coming from a trait
-            if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = tcx.hir().get_parent(hir_id)
+            if let Item(hir::Item { kind: ItemKind::Impl(i), .. }) = tcx.parent_hir_node(hir_id)
                 && i.of_trait.is_some()
             {
                 icx.astconv().ty_of_fn(
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 4860555de20..e5e731bbe8c 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -51,7 +51,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                 // of a const parameter type, e.g. `struct Foo<const N: usize, const M: [u8; N]>` is not allowed.
                 None
             } else if tcx.features().generic_const_exprs {
-                let parent_node = tcx.hir().get_parent(hir_id);
+                let parent_node = tcx.parent_hir_node(hir_id);
                 if let Node::Variant(Variant { disr_expr: Some(constant), .. }) = parent_node
                     && constant.hir_id == hir_id
                 {
@@ -113,7 +113,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                     Some(parent_def_id.to_def_id())
                 }
             } else {
-                let parent_node = tcx.hir().get_parent(hir_id);
+                let parent_node = tcx.parent_hir_node(hir_id);
                 match parent_node {
                     // HACK(eddyb) this provides the correct generics for repeat
                     // expressions' count (i.e. `N` in `[x; N]`), and explicit
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index ab9ed6ef98d..05755f98f20 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -315,8 +315,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
     // We create bi-directional Outlives predicates between the original
     // and the duplicated parameter, to ensure that they do not get out of sync.
     if let Node::Item(&Item { kind: ItemKind::OpaqueTy(..), .. }) = node {
-        let opaque_ty_id = tcx.hir().parent_id(hir_id);
-        let opaque_ty_node = tcx.hir_node(opaque_ty_id);
+        let opaque_ty_node = tcx.parent_hir_node(hir_id);
         let Node::Ty(&Ty { kind: TyKind::OpaqueDef(_, lifetimes, _), .. }) = opaque_ty_node else {
             bug!("unexpected {opaque_ty_node:?}")
         };
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 3849c0893f4..1aa9c6929f8 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -732,7 +732,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                     let Some(def_id) = def_id.as_local() else { continue };
                     let hir_id = self.tcx.local_def_id_to_hir_id(def_id);
                     // Ensure that the parent of the def is an item, not HRTB
-                    let parent_id = self.tcx.hir().parent_id(hir_id);
+                    let parent_id = self.tcx.parent_hir_id(hir_id);
                     if !parent_id.is_owner() {
                         struct_span_code_err!(
                             self.tcx.dcx(),
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 20a7663f864..c0128afe2bf 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -30,7 +30,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
         );
     };
 
-    let parent_node_id = tcx.hir().parent_id(hir_id);
+    let parent_node_id = tcx.parent_hir_id(hir_id);
     let parent_node = tcx.hir_node(parent_node_id);
 
     let (generics, arg_idx) = match parent_node {
@@ -79,7 +79,7 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
         }
 
         Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, .. })
-            if let Node::TraitRef(trait_ref) = tcx.hir_node(tcx.hir().parent_id(binding_id)) =>
+            if let Node::TraitRef(trait_ref) = tcx.parent_hir_node(binding_id) =>
         {
             let Some(trait_def_id) = trait_ref.trait_def_id() else {
                 return Ty::new_error_with_message(
diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
index 3b1ee2975fd..52ff8b2e45d 100644
--- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs
@@ -135,7 +135,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
             // Here we check if the reference to the generic type
             // is from the 'of_trait' field of the enclosing impl
 
-            let parent = self.tcx.hir().get_parent(self.path_segment.hir_id);
+            let parent = self.tcx.parent_hir_node(self.path_segment.hir_id);
             let parent_item = self.tcx.hir_node_by_def_id(
                 self.tcx.hir().get_parent_item(self.path_segment.hir_id).def_id,
             );
@@ -770,9 +770,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
             num = num_trait_generics_except_self,
         );
 
-        if let Some(parent_node) = self.tcx.hir().opt_parent_id(self.path_segment.hir_id)
-            && let hir::Node::Expr(expr) = self.tcx.hir_node(parent_node)
-        {
+        if let hir::Node::Expr(expr) = self.tcx.parent_hir_node(self.path_segment.hir_id) {
             match &expr.kind {
                 hir::ExprKind::Path(qpath) => self
                     .suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index 7ea0469dedd..0311aa94cd4 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -287,7 +287,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     {
         // If this `if` expr is the parent's function return expr,
         // the cause of the type coercion is the return type, point at it. (#25228)
-        let hir_id = self.tcx.hir().parent_id(self.tcx.hir().parent_id(then_expr.hir_id));
+        let hir_id = self.tcx.parent_hir_id(self.tcx.parent_hir_id(then_expr.hir_id));
         let ret_reason = self.maybe_get_coercion_reason(hir_id, if_span);
         let cause = self.cause(if_span, ObligationCauseCode::IfExpressionWithNoElse);
         let mut error = false;
@@ -396,7 +396,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let node = self.tcx.hir_node(hir_id);
         if let hir::Node::Block(block) = node {
             // check that the body's parent is an fn
-            let parent = self.tcx.hir().get_parent(self.tcx.hir().parent_id(block.hir_id));
+            let parent = self.tcx.parent_hir_node(self.tcx.parent_hir_id(block.hir_id));
             if let (Some(expr), hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(..), .. })) =
                 (&block.expr, parent)
             {
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 299ee092a80..c4271c66e1c 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -361,7 +361,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let fn_decl_span = if let hir::Node::Expr(hir::Expr {
             kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }),
             ..
-        }) = hir.get_parent(hir_id)
+        }) = self.tcx.parent_hir_node(hir_id)
         {
             fn_decl_span
         } else if let Some((
@@ -383,11 +383,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         {
             // Actually need to unwrap one more layer of HIR to get to
             // the _real_ closure...
-            let async_closure = hir.parent_id(parent_hir_id);
             if let hir::Node::Expr(hir::Expr {
                 kind: hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }),
                 ..
-            }) = self.tcx.hir_node(async_closure)
+            }) = self.tcx.parent_hir_node(parent_hir_id)
             {
                 fn_decl_span
             } else {
@@ -415,8 +414,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         call_expr: &'tcx hir::Expr<'tcx>,
         callee_expr: &'tcx hir::Expr<'tcx>,
     ) -> bool {
-        let hir_id = self.tcx.hir().parent_id(call_expr.hir_id);
-        let parent_node = self.tcx.hir_node(hir_id);
+        let parent_node = self.tcx.parent_hir_node(call_expr.hir_id);
         if let (
             hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Array(_), .. }),
             hir::ExprKind::Tup(exp),
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 28f850a50a0..549ad44d7e3 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -1594,7 +1594,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                         err.span_label(cause.span, "return type is not `()`");
                     }
                     ObligationCauseCode::BlockTailExpression(blk_id, ..) => {
-                        let parent_id = fcx.tcx.hir().parent_id(blk_id);
+                        let parent_id = fcx.tcx.parent_hir_id(blk_id);
                         err = self.report_return_mismatched_types(
                             cause,
                             expected,
@@ -1785,7 +1785,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
     ) -> DiagnosticBuilder<'a> {
         let mut err = fcx.err_ctxt().report_mismatched_types(cause, expected, found, ty_err);
 
-        let parent_id = fcx.tcx.hir().parent_id(id);
+        let parent_id = fcx.tcx.parent_hir_id(id);
         let parent = fcx.tcx.hir_node(parent_id);
         if let Some(expr) = expression
             && let hir::Node::Expr(hir::Expr {
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index d8974251de0..fdb2cb69ee7 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -298,7 +298,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let hir::Node::Pat(pat) = self.tcx.hir_node(local_hir_id) else {
             return false;
         };
-        let (init_ty_hir_id, init) = match hir.get_parent(pat.hir_id) {
+        let (init_ty_hir_id, init) = match self.tcx.parent_hir_node(pat.hir_id) {
             hir::Node::Local(hir::Local { ty: Some(ty), init, .. }) => (ty.hir_id, *init),
             hir::Node::Local(hir::Local { init: Some(init), .. }) => (init.hir_id, Some(*init)),
             _ => return false,
@@ -445,7 +445,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 continue;
             }
 
-            if let hir::Node::Expr(parent_expr) = hir.get_parent(binding.hir_id)
+            if let hir::Node::Expr(parent_expr) = self.tcx.parent_hir_node(binding.hir_id)
                 && let hir::ExprKind::MethodCall(segment, rcvr, args, _) = parent_expr.kind
                 && rcvr.hir_id == binding.hir_id
             {
@@ -557,7 +557,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let Some(TypeError::Sorts(ExpectedFound { expected, .. })) = error else {
             return;
         };
-        let mut parent_id = self.tcx.hir().parent_id(expr.hir_id);
+        let mut parent_id = self.tcx.parent_hir_id(expr.hir_id);
         let mut parent;
         'outer: loop {
             // Climb the HIR tree to see if the current `Expr` is part of a `break;` statement.
@@ -568,7 +568,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 break;
             };
             parent = p;
-            parent_id = self.tcx.hir().parent_id(parent_id);
+            parent_id = self.tcx.parent_hir_id(parent_id);
             let hir::ExprKind::Break(destination, _) = parent.kind else {
                 continue;
             };
@@ -578,7 +578,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // Climb the HIR tree to find the (desugared) `loop` this `break` corresponds to.
                 let parent = match self.tcx.hir_node(parent_id) {
                     hir::Node::Expr(&ref parent) => {
-                        parent_id = self.tcx.hir().parent_id(parent.hir_id);
+                        parent_id = self.tcx.parent_hir_id(parent.hir_id);
                         parent
                     }
                     hir::Node::Stmt(hir::Stmt {
@@ -586,11 +586,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         kind: hir::StmtKind::Semi(&ref parent) | hir::StmtKind::Expr(&ref parent),
                         ..
                     }) => {
-                        parent_id = self.tcx.hir().parent_id(*hir_id);
+                        parent_id = self.tcx.parent_hir_id(*hir_id);
                         parent
                     }
                     hir::Node::Block(_) => {
-                        parent_id = self.tcx.hir().parent_id(parent_id);
+                        parent_id = self.tcx.parent_hir_id(parent_id);
                         parent
                     }
                     _ => break,
@@ -677,8 +677,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &hir::Expr<'_>,
         error: Option<TypeError<'tcx>>,
     ) {
-        let parent = self.tcx.hir().parent_id(expr.hir_id);
-        match (self.tcx.hir_node(parent), error) {
+        match (self.tcx.parent_hir_node(expr.hir_id), error) {
             (hir::Node::Local(hir::Local { ty: Some(ty), init: Some(init), .. }), _)
                 if init.hir_id == expr.hir_id =>
             {
@@ -724,16 +723,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         if let hir::Node::Pat(pat) = self.tcx.hir_node(*hir_id) {
                             primary_span = pat.span;
                             secondary_span = pat.span;
-                            match self.tcx.hir().find_parent(pat.hir_id) {
-                                Some(hir::Node::Local(hir::Local { ty: Some(ty), .. })) => {
+                            match self.tcx.parent_hir_node(pat.hir_id) {
+                                hir::Node::Local(hir::Local { ty: Some(ty), .. }) => {
                                     primary_span = ty.span;
                                     post_message = " type";
                                 }
-                                Some(hir::Node::Local(hir::Local { init: Some(init), .. })) => {
+                                hir::Node::Local(hir::Local { init: Some(init), .. }) => {
                                     primary_span = init.span;
                                     post_message = " value";
                                 }
-                                Some(hir::Node::Param(hir::Param { ty_span, .. })) => {
+                                hir::Node::Param(hir::Param { ty_span, .. }) => {
                                     primary_span = *ty_span;
                                     post_message = " parameter type";
                                 }
@@ -787,12 +786,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &hir::Expr<'_>,
         error: Option<TypeError<'tcx>>,
     ) {
-        let parent = self.tcx.hir().parent_id(expr.hir_id);
         let Some(TypeError::Sorts(ExpectedFound { expected, .. })) = error else {
             return;
         };
         let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. }) =
-            self.tcx.hir_node(parent)
+            self.tcx.parent_hir_node(expr.hir_id)
         else {
             return;
         };
@@ -1017,7 +1015,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         )) = expr.kind
         {
             let bind = self.tcx.hir_node(*bind_hir_id);
-            let parent = self.tcx.hir_node(self.tcx.hir().parent_id(*bind_hir_id));
+            let parent = self.tcx.parent_hir_node(*bind_hir_id);
             if let hir::Node::Pat(hir::Pat {
                 kind: hir::PatKind::Binding(_, _hir_id, _, _), ..
             }) = bind
@@ -1088,7 +1086,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expr: &hir::Expr<'_>,
         checked_ty: Ty<'tcx>,
     ) {
-        let Some(hir::Node::Expr(parent_expr)) = self.tcx.hir().find_parent(expr.hir_id) else {
+        let hir::Node::Expr(parent_expr) = self.tcx.parent_hir_node(expr.hir_id) else {
             return;
         };
         enum CallableKind {
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 292b85eb97f..31c97aab7fb 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1016,7 +1016,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         original_expr_id: HirId,
         then: impl FnOnce(&hir::Expr<'_>),
     ) {
-        let mut parent = self.tcx.hir().parent_id(original_expr_id);
+        let mut parent = self.tcx.parent_hir_id(original_expr_id);
         loop {
             let node = self.tcx.hir_node(parent);
             match node {
@@ -1038,15 +1038,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ),
                     ..
                 }) => {
-                    // Check if our original expression is a child of the condition of a while loop
-                    let expr_is_ancestor = std::iter::successors(Some(original_expr_id), |id| {
-                        self.tcx.hir().opt_parent_id(*id)
-                    })
-                    .take_while(|id| *id != parent)
-                    .any(|id| id == expr.hir_id);
-                    // if it is, then we have a situation like `while Some(0) = value.get(0) {`,
+                    // Check if our original expression is a child of the condition of a while loop.
+                    // If it is, then we have a situation like `while Some(0) = value.get(0) {`,
                     // where `while let` was more likely intended.
-                    if expr_is_ancestor {
+                    if self.tcx.hir().parent_id_iter(original_expr_id).any(|id| id == expr.hir_id) {
                         then(expr);
                     }
                     break;
@@ -1056,7 +1051,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 | hir::Node::TraitItem(_)
                 | hir::Node::Crate(_) => break,
                 _ => {
-                    parent = self.tcx.hir().parent_id(parent);
+                    parent = self.tcx.parent_hir_id(parent);
                 }
             }
         }
@@ -1199,9 +1194,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 && !matches!(lhs.kind, hir::ExprKind::Lit(_))
             {
                 // Do not suggest `if let x = y` as `==` is way more likely to be the intention.
-                let hir = self.tcx.hir();
                 if let hir::Node::Expr(hir::Expr { kind: ExprKind::If { .. }, .. }) =
-                    hir.get_parent(hir.parent_id(expr.hir_id))
+                    self.tcx.parent_hir_node(expr.hir_id)
                 {
                     err.span_suggestion_verbose(
                         expr.span.shrink_to_lo(),
@@ -2645,7 +2639,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         err.span_label(field.span, "method, not a field");
         let expr_is_call =
             if let hir::Node::Expr(hir::Expr { kind: ExprKind::Call(callee, _args), .. }) =
-                self.tcx.hir().get_parent(expr.hir_id)
+                self.tcx.parent_hir_node(expr.hir_id)
             {
                 expr.hir_id == callee.hir_id
             } else {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 36c3eef82fc..7eb421ca8f5 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -764,7 +764,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let code = match lang_item {
             hir::LangItem::IntoFutureIntoFuture => {
-                if let hir::Node::Expr(into_future_call) = self.tcx.hir().get_parent(hir_id)
+                if let hir::Node::Expr(into_future_call) = self.tcx.parent_hir_node(hir_id)
                     && let hir::ExprKind::Call(_, [arg0]) = &into_future_call.kind
                 {
                     Some(ObligationCauseCode::AwaitableExpr(arg0.hir_id))
@@ -956,12 +956,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 ..
             }) => Some((hir::HirId::make_owner(owner_id.def_id), &sig.decl, ident, false)),
             Node::Expr(&hir::Expr { hir_id, kind: hir::ExprKind::Closure(..), .. })
-                if let Some(Node::Item(&hir::Item {
+                if let Node::Item(&hir::Item {
                     ident,
                     kind: hir::ItemKind::Fn(ref sig, ..),
                     owner_id,
                     ..
-                })) = self.tcx.hir().find_parent(hir_id) =>
+                }) = self.tcx.parent_hir_node(hir_id) =>
             {
                 Some((
                     hir::HirId::make_owner(owner_id.def_id),
@@ -1574,7 +1574,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub(in super::super) fn expr_in_place(&self, mut expr_id: hir::HirId) -> bool {
         let mut contained_in_place = false;
 
-        while let hir::Node::Expr(parent_expr) = self.tcx.hir().get_parent(expr_id) {
+        while let hir::Node::Expr(parent_expr) = self.tcx.parent_hir_node(expr_id) {
             match &parent_expr.kind {
                 hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
                     if lhs.hir_id == expr_id {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
index 1ad79cb78c4..6aa986b0df4 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
@@ -93,7 +93,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.find_ambiguous_parameter_in(def_id, error.root_obligation.predicate);
         }
 
-        let hir = self.tcx.hir();
         let (expr, qpath) = match self.tcx.hir_node(hir_id) {
             hir::Node::Expr(expr) => {
                 if self.closure_span_overlaps_error(error, expr.span) {
@@ -122,7 +121,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 hir_id: call_hir_id,
                 span: call_span,
                 ..
-            }) = hir.get_parent(hir_id)
+            }) = self.tcx.parent_hir_node(hir_id)
                 && callee.hir_id == hir_id
             {
                 if self.closure_span_overlaps_error(error, *call_span) {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index ed0bdb9bdaa..193c9a4b908 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -681,9 +681,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // Check if the parent expression is a call to Pin::new. If it
                 // is and we were expecting a Box, ergo Pin<Box<expected>>, we
                 // can suggest Box::pin.
-                let parent = self.tcx.hir().parent_id(expr.hir_id);
                 let Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. }) =
-                    self.tcx.hir_node(parent)
+                    self.tcx.parent_hir_node(expr.hir_id)
                 else {
                     return false;
                 };
@@ -1687,7 +1686,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     return expr;
                 };
 
-                match self.tcx.hir_node(self.tcx.hir().parent_id(*hir_id)) {
+                match self.tcx.parent_hir_node(*hir_id) {
                     // foo.clone()
                     hir::Node::Local(hir::Local { init: Some(init), .. }) => {
                         self.note_type_is_not_clone_inner_expr(init)
@@ -1699,7 +1698,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ..
                     }) => {
                         let hir::Node::Local(hir::Local { init: Some(init), .. }) =
-                            self.tcx.hir_node(self.tcx.hir().parent_id(*pat_hir_id))
+                            self.tcx.parent_hir_node(*pat_hir_id)
                         else {
                             return expr;
                         };
@@ -1733,7 +1732,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         call_expr_path
                     && let hir::Node::Pat(hir::Pat { hir_id, .. }) = self.tcx.hir_node(*binding)
                     && let hir::Node::Local(hir::Local { init: Some(init), .. }) =
-                        self.tcx.hir_node(self.tcx.hir().parent_id(*hir_id))
+                        self.tcx.parent_hir_node(*hir_id)
                     && let Expr {
                         kind: hir::ExprKind::Closure(hir::Closure { body: body_id, .. }),
                         ..
@@ -1899,8 +1898,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) -> bool {
         let map = self.tcx.hir();
         let returned = matches!(
-            map.find_parent(expr.hir_id),
-            Some(hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Ret(_), .. }))
+            self.tcx.parent_hir_node(expr.hir_id),
+            hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Ret(_), .. })
         ) || map.get_return_block(expr.hir_id).is_some();
         if returned
             && let ty::Adt(e, args_e) = expected.kind()
@@ -1972,7 +1971,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 // Unroll desugaring, to make sure this works for `for` loops etc.
                 loop {
-                    parent = self.tcx.hir().parent_id(id);
+                    parent = self.tcx.parent_hir_id(id);
                     let parent_span = self.tcx.hir().span(parent);
                     if parent_span.find_ancestor_inside(expr.span).is_some() {
                         // The parent node is part of the same span, so is the result of the
@@ -2211,24 +2210,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return None;
         };
 
-        let local_parent = self.tcx.hir().parent_id(local_id);
-        let Node::Param(hir::Param { hir_id: param_hir_id, .. }) = self.tcx.hir_node(local_parent)
+        let Node::Param(hir::Param { hir_id: param_hir_id, .. }) =
+            self.tcx.parent_hir_node(local_id)
         else {
             return None;
         };
 
-        let param_parent = self.tcx.hir().parent_id(*param_hir_id);
         let Node::Expr(hir::Expr {
             hir_id: expr_hir_id,
             kind: hir::ExprKind::Closure(hir::Closure { fn_decl: closure_fn_decl, .. }),
             ..
-        }) = self.tcx.hir_node(param_parent)
+        }) = self.tcx.parent_hir_node(*param_hir_id)
         else {
             return None;
         };
 
-        let expr_parent = self.tcx.hir().parent_id(*expr_hir_id);
-        let hir = self.tcx.hir_node(expr_parent);
+        let hir = self.tcx.parent_hir_node(*expr_hir_id);
         let closure_params_len = closure_fn_decl.inputs.len();
         let (
             Node::Expr(hir::Expr {
@@ -2409,10 +2406,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         None => String::new(),
                     };
 
-                    if let Some(hir::Node::Expr(hir::Expr {
-                        kind: hir::ExprKind::Assign(..),
-                        ..
-                    })) = self.tcx.hir().find_parent(expr.hir_id)
+                    if let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(..), .. }) =
+                        self.tcx.parent_hir_node(expr.hir_id)
                     {
                         if mutability.is_mut() {
                             // Suppressing this diagnostic, we'll properly print it in `check_expr_assign`
@@ -2443,10 +2438,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     };
 
                     // Suggest dereferencing the lhs for expressions such as `&T <= T`
-                    if let Some(hir::Node::Expr(hir::Expr {
+                    if let hir::Node::Expr(hir::Expr {
                         kind: hir::ExprKind::Binary(_, lhs, ..),
                         ..
-                    })) = self.tcx.hir().find_parent(expr.hir_id)
+                    }) = self.tcx.parent_hir_node(expr.hir_id)
                         && let &ty::Ref(..) = self.check_expr(lhs).kind()
                     {
                         let (sugg, verbose) = make_sugg(lhs, lhs.span, "*");
@@ -2602,7 +2597,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         || (checked_ty.is_box() && steps == 1)
                         // We can always deref a binop that takes its arguments by ref.
                         || matches!(
-                            self.tcx.hir().get_parent(expr.hir_id),
+                            self.tcx.parent_hir_node(expr.hir_id),
                             hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Binary(op, ..), .. })
                                 if !op.node.is_by_value()
                         )
@@ -2664,10 +2659,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Returns whether the given expression is an `else if`.
     fn is_else_if_block(&self, expr: &hir::Expr<'_>) -> bool {
         if let hir::ExprKind::If(..) = expr.kind {
-            let parent_id = self.tcx.hir().parent_id(expr.hir_id);
             if let Node::Expr(hir::Expr {
                 kind: hir::ExprKind::If(_, _, Some(else_expr)), ..
-            }) = self.tcx.hir_node(parent_id)
+            }) = self.tcx.parent_hir_node(expr.hir_id)
             {
                 return else_expr.hir_id == expr.hir_id;
             }
@@ -2704,7 +2698,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let mut sugg = vec![];
 
-        if let Some(hir::Node::ExprField(field)) = self.tcx.hir().find_parent(expr.hir_id) {
+        if let hir::Node::ExprField(field) = self.tcx.parent_hir_node(expr.hir_id) {
             // `expr` is a literal field for a struct, only suggest if appropriate
             if field.is_shorthand {
                 // This is a field literal
@@ -3056,8 +3050,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         else {
             return;
         };
-        let parent = self.tcx.hir().parent_id(expr.hir_id);
-        if let hir::Node::ExprField(_) = self.tcx.hir_node(parent) {
+        if let hir::Node::ExprField(_) = self.tcx.parent_hir_node(expr.hir_id) {
             // Ignore `Foo { field: a..Default::default() }`
             return;
         }
@@ -3139,8 +3132,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let hir::Node::Pat(pat) = self.tcx.hir_node(hir_id) else {
             return;
         };
-        let Some(hir::Node::Local(hir::Local { ty: None, init: Some(init), .. })) =
-            self.tcx.hir().find_parent(pat.hir_id)
+        let hir::Node::Local(hir::Local { ty: None, init: Some(init), .. }) =
+            self.tcx.parent_hir_node(pat.hir_id)
         else {
             return;
         };
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index 06a14613567..c1af4b5983e 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -220,7 +220,7 @@ fn typeck_with_fallback<'tcx>(
                 span,
             }))
         } else if let Node::AnonConst(_) = node {
-            match tcx.hir_node(tcx.hir().parent_id(id)) {
+            match tcx.parent_hir_node(id) {
                 Node::Ty(&hir::Ty { kind: hir::TyKind::Typeof(ref anon_const), .. })
                     if anon_const.hir_id == id =>
                 {
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 81b82393515..7fc51e36a2b 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -128,7 +128,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let sugg_span = if let SelfSource::MethodCall(expr) = source {
             // Given `foo.bar(baz)`, `expr` is `bar`, but we want to point to the whole thing.
-            self.tcx.hir().expect_expr(self.tcx.hir().parent_id(expr.hir_id)).span
+            self.tcx.hir().expect_expr(self.tcx.parent_hir_id(expr.hir_id)).span
         } else {
             span
         };
@@ -231,9 +231,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = kind
                             && let hir::def::Res::Local(hir_id) = path.res
                             && let hir::Node::Pat(b) = self.tcx.hir_node(hir_id)
-                            && let Some(hir::Node::Param(p)) = self.tcx.hir().find_parent(b.hir_id)
-                            && let Some(node) = self.tcx.hir().find_parent(p.hir_id)
-                            && let Some(decl) = node.fn_decl()
+                            && let hir::Node::Param(p) = self.tcx.parent_hir_node(b.hir_id)
+                            && let Some(decl) = self.tcx.parent_hir_node(p.hir_id).fn_decl()
                             && let Some(ty) = decl.inputs.iter().find(|ty| ty.span == p.ty_span)
                             && let hir::TyKind::Ref(_, mut_ty) = &ty.kind
                             && let hir::Mutability::Not = mut_ty.mutbl
@@ -471,7 +470,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if let SelfSource::MethodCall(rcvr_expr) = source {
             self.suggest_fn_call(&mut err, rcvr_expr, rcvr_ty, |output_ty| {
                 let call_expr =
-                    self.tcx.hir().expect_expr(self.tcx.hir().parent_id(rcvr_expr.hir_id));
+                    self.tcx.hir().expect_expr(self.tcx.parent_hir_id(rcvr_expr.hir_id));
                 let probe = self.lookup_probe_for_diagnostic(
                     item_name,
                     output_ty,
@@ -1020,7 +1019,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         rcvr_ty,
                         &item_segment,
                         span,
-                        tcx.hir().get_parent(rcvr_expr.hir_id).expect_expr(),
+                        tcx.parent_hir_node(rcvr_expr.hir_id).expect_expr(),
                         rcvr_expr,
                     ) {
                         err.span_note(
@@ -1254,7 +1253,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let msg = "remove this method call";
             let mut fallback_span = true;
             if let SelfSource::MethodCall(expr) = source {
-                let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().parent_id(expr.hir_id));
+                let call_expr = self.tcx.hir().expect_expr(self.tcx.parent_hir_id(expr.hir_id));
                 if let Some(span) = call_expr.span.trim_start(expr.span) {
                     err.span_suggestion(span, msg, "", Applicability::MachineApplicable);
                     fallback_span = false;
@@ -1753,7 +1752,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         Applicability::MachineApplicable,
                     );
                 } else {
-                    let call_expr = tcx.hir().expect_expr(tcx.hir().parent_id(expr.hir_id));
+                    let call_expr = tcx.hir().expect_expr(tcx.parent_hir_id(expr.hir_id));
 
                     if let Some(span) = call_expr.span.trim_start(item_name.span) {
                         err.span_suggestion(
@@ -1937,7 +1936,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         let span = tcx.hir().span(hir_id);
                         let filename = tcx.sess.source_map().span_to_filename(span);
 
-                        let parent_node = self.tcx.hir().get_parent(hir_id);
+                        let parent_node = self.tcx.parent_hir_node(hir_id);
                         let msg = format!(
                             "you must specify a type for this binding, like `{concrete_type}`",
                         );
@@ -2016,8 +2015,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut visitor = LetVisitor { result: None, ident_name: seg1.ident.name };
         visitor.visit_body(body);
 
-        let parent = self.tcx.hir().parent_id(seg1.hir_id);
-        if let Node::Expr(call_expr) = self.tcx.hir_node(parent)
+        if let Node::Expr(call_expr) = self.tcx.parent_hir_node(seg1.hir_id)
             && let Some(expr) = visitor.result
             && let Some(self_ty) = self.node_ty_opt(expr.hir_id)
         {
@@ -2056,7 +2054,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             for (fields, args) in
                 self.get_field_candidates_considering_privacy(span, actual, mod_id, expr.hir_id)
             {
-                let call_expr = self.tcx.hir().expect_expr(self.tcx.hir().parent_id(expr.hir_id));
+                let call_expr = self.tcx.hir().expect_expr(self.tcx.parent_hir_id(expr.hir_id));
 
                 let lang_items = self.tcx.lang_items();
                 let never_mention_traits = [
@@ -2133,7 +2131,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let SelfSource::MethodCall(expr) = source else {
             return;
         };
-        let call_expr = tcx.hir().expect_expr(tcx.hir().parent_id(expr.hir_id));
+        let call_expr = tcx.hir().expect_expr(tcx.parent_hir_id(expr.hir_id));
 
         let ty::Adt(kind, args) = actual.kind() else {
             return;
@@ -3250,8 +3248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return false;
         }
 
-        let parent = self.tcx.hir().parent_id(expr.hir_id);
-        if let Node::Expr(call_expr) = self.tcx.hir_node(parent)
+        if let Node::Expr(call_expr) = self.tcx.parent_hir_node(expr.hir_id)
             && let hir::ExprKind::MethodCall(
                 hir::PathSegment { ident: method_name, .. },
                 self_expr,
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index 9ce61898561..9a8444e6a2b 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -383,7 +383,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     }
                 };
                 if self.check_for_missing_semi(expr, &mut err)
-                    && let hir::Node::Expr(expr) = self.tcx.hir().get_parent(expr.hir_id)
+                    && let hir::Node::Expr(expr) = self.tcx.parent_hir_node(expr.hir_id)
                     && let hir::ExprKind::Assign(..) = expr.kind
                 {
                     // We defer to the later error produced by `check_lhs_assignable`.
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index fcf4b59e93f..67aa9218585 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -720,8 +720,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if let PatKind::Ref(inner, mutbl) = pat.kind
             && let PatKind::Binding(_, _, binding, ..) = inner.kind
         {
-            let binding_parent_id = tcx.hir().parent_id(pat.hir_id);
-            let binding_parent = tcx.hir_node(binding_parent_id);
+            let binding_parent = tcx.parent_hir_node(pat.hir_id);
             debug!(?inner, ?pat, ?binding_parent);
 
             let mutability = match mutbl {
@@ -989,7 +988,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         res.descr(),
                     ),
                 );
-                match self.tcx.hir().get_parent(pat.hir_id) {
+                match self.tcx.parent_hir_node(pat.hir_id) {
                     hir::Node::PatField(..) => {
                         e.span_suggestion_verbose(
                             ident.span.shrink_to_hi(),
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index dd9ed80ca72..4d2d19b51e2 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -862,8 +862,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     ) {
                         err.subdiagnostic(subdiag);
                     }
-                    if let Some(hir::Node::Expr(m)) = self.tcx.hir().find_parent(scrut_hir_id)
-                        && let Some(hir::Node::Stmt(stmt)) = self.tcx.hir().find_parent(m.hir_id)
+                    if let hir::Node::Expr(m) = self.tcx.parent_hir_node(scrut_hir_id)
+                        && let hir::Node::Stmt(stmt) = self.tcx.parent_hir_node(m.hir_id)
                         && let hir::StmtKind::Expr(_) = stmt.kind
                     {
                         err.span_suggestion_verbose(
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index f884ca83073..3c42f13141d 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -106,7 +106,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                                 }
                                 p_def_id.as_local().and_then(|id| {
                                     let local_id = tcx.local_def_id_to_hir_id(id);
-                                    let generics = tcx.hir().find_parent(local_id)?.generics()?;
+                                    let generics = tcx.parent_hir_node(local_id).generics()?;
                                     Some((id, generics))
                                 })
                             });
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
index bbe07b8ed72..248e1c0fcc8 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
@@ -735,30 +735,29 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
             };
             local.pat.walk(&mut find_compatible_candidates);
         }
-        match hir.find_parent(blk.hir_id) {
-            Some(hir::Node::Expr(hir::Expr { hir_id, .. })) => match hir.find_parent(*hir_id) {
-                Some(hir::Node::Arm(hir::Arm { pat, .. })) => {
+        match self.tcx.parent_hir_node(blk.hir_id) {
+            hir::Node::Expr(hir::Expr { hir_id, .. }) => match self.tcx.parent_hir_node(*hir_id) {
+                hir::Node::Arm(hir::Arm { pat, .. }) => {
                     pat.walk(&mut find_compatible_candidates);
                 }
-                Some(
-                    hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body), .. })
-                    | hir::Node::ImplItem(hir::ImplItem {
-                        kind: hir::ImplItemKind::Fn(_, body), ..
-                    })
-                    | hir::Node::TraitItem(hir::TraitItem {
-                        kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body)),
-                        ..
-                    })
-                    | hir::Node::Expr(hir::Expr {
-                        kind: hir::ExprKind::Closure(hir::Closure { body, .. }),
-                        ..
-                    }),
-                ) => {
+
+                hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body), .. })
+                | hir::Node::ImplItem(hir::ImplItem {
+                    kind: hir::ImplItemKind::Fn(_, body), ..
+                })
+                | hir::Node::TraitItem(hir::TraitItem {
+                    kind: hir::TraitItemKind::Fn(_, hir::TraitFn::Provided(body)),
+                    ..
+                })
+                | hir::Node::Expr(hir::Expr {
+                    kind: hir::ExprKind::Closure(hir::Closure { body, .. }),
+                    ..
+                }) => {
                     for param in hir.body(*body).params {
                         param.pat.walk(&mut find_compatible_candidates);
                     }
                 }
-                Some(hir::Node::Expr(hir::Expr {
+                hir::Node::Expr(hir::Expr {
                     kind:
                         hir::ExprKind::If(
                             hir::Expr { kind: hir::ExprKind::Let(let_), .. },
@@ -766,7 +765,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                             _,
                         ),
                     ..
-                })) if then_block.hir_id == *hir_id => {
+                }) if then_block.hir_id == *hir_id => {
                     let_.pat.walk(&mut find_compatible_candidates);
                 }
                 _ => {}
diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
index 7401654aea8..0253f5a2df2 100644
--- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
@@ -65,10 +65,10 @@ pub fn report_object_safety_error<'tcx>(
         && let hir::TyKind::TraitObject([trait_ref, ..], ..) = ty.kind
     {
         let mut hir_id = hir_id;
-        while let hir::Node::Ty(ty) = tcx.hir().get_parent(hir_id) {
+        while let hir::Node::Ty(ty) = tcx.parent_hir_node(hir_id) {
             hir_id = ty.hir_id;
         }
-        if tcx.hir().get_parent(hir_id).fn_sig().is_some() {
+        if tcx.parent_hir_node(hir_id).fn_sig().is_some() {
             // Do not suggest `impl Trait` when dealing with things like super-traits.
             err.span_suggestion_verbose(
                 ty.span.until(trait_ref.span),
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index f10d3d4a68a..6ee1d1ca924 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1416,8 +1416,7 @@ impl<'tcx> LateLintPass<'tcx> for UnreachablePub {
     }
 
     fn check_field_def(&mut self, cx: &LateContext<'_>, field: &hir::FieldDef<'_>) {
-        let map = cx.tcx.hir();
-        if matches!(map.get_parent(field.hir_id), Node::Variant(_)) {
+        if matches!(cx.tcx.parent_hir_node(field.hir_id), Node::Variant(_)) {
             return;
         }
         self.perform_lint(cx, "field", field.def_id, field.vis_span, false);
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 1c480ec8f53..30f05444d21 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -933,7 +933,7 @@ impl<'tcx> LateContext<'tcx> {
 
         while let hir::ExprKind::Path(ref qpath) = expr.kind
             && let Some(parent_node) = match self.qpath_res(qpath, expr.hir_id) {
-                Res::Local(hir_id) => self.tcx.hir().find_parent(hir_id),
+                Res::Local(hir_id) => Some(self.tcx.parent_hir_node(hir_id)),
                 _ => None,
             }
             && let Some(init) = match parent_node {
@@ -977,7 +977,7 @@ impl<'tcx> LateContext<'tcx> {
 
         while let hir::ExprKind::Path(ref qpath) = expr.kind
             && let Some(parent_node) = match self.qpath_res(qpath, expr.hir_id) {
-                Res::Local(hir_id) => self.tcx.hir().find_parent(hir_id),
+                Res::Local(hir_id) => Some(self.tcx.parent_hir_node(hir_id)),
                 Res::Def(_, def_id) => self.tcx.hir().get_if_local(def_id),
                 _ => None,
             }
diff --git a/compiler/rustc_lint/src/drop_forget_useless.rs b/compiler/rustc_lint/src/drop_forget_useless.rs
index 9a31aa062f0..78ac7f9b235 100644
--- a/compiler/rustc_lint/src/drop_forget_useless.rs
+++ b/compiler/rustc_lint/src/drop_forget_useless.rs
@@ -214,8 +214,7 @@ fn is_single_call_in_arm<'tcx>(
     drop_expr: &'tcx Expr<'_>,
 ) -> bool {
     if arg.can_have_side_effects() {
-        let parent_node = cx.tcx.hir().find_parent(drop_expr.hir_id);
-        if let Some(Node::Arm(Arm { body, .. })) = &parent_node {
+        if let Node::Arm(Arm { body, .. }) = cx.tcx.parent_hir_node(drop_expr.hir_id) {
             return body.hir_id == drop_expr.hir_id;
         }
     }
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 516df14c894..596221a8455 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -144,15 +144,14 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
         match &ty.kind {
             TyKind::Path(QPath::Resolved(_, path)) => {
                 if lint_ty_kind_usage(cx, &path.res) {
-                    let hir = cx.tcx.hir();
-                    let span = match hir.find_parent(ty.hir_id) {
-                        Some(Node::Pat(Pat {
+                    let span = match cx.tcx.parent_hir_node(ty.hir_id) {
+                        Node::Pat(Pat {
                             kind:
                                 PatKind::Path(qpath)
                                 | PatKind::TupleStruct(qpath, ..)
                                 | PatKind::Struct(qpath, ..),
                             ..
-                        })) => {
+                        }) => {
                             if let QPath::TypeRelative(qpath_ty, ..) = qpath
                                 && qpath_ty.hir_id == ty.hir_id
                             {
@@ -161,7 +160,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
                                 None
                             }
                         }
-                        Some(Node::Expr(Expr { kind: ExprKind::Path(qpath), .. })) => {
+                        Node::Expr(Expr { kind: ExprKind::Path(qpath), .. }) => {
                             if let QPath::TypeRelative(qpath_ty, ..) = qpath
                                 && qpath_ty.hir_id == ty.hir_id
                             {
@@ -172,7 +171,7 @@ impl<'tcx> LateLintPass<'tcx> for TyTyKind {
                         }
                         // Can't unify these two branches because qpath below is `&&` and above is `&`
                         // and `A | B` paths don't play well together with adjustments, apparently.
-                        Some(Node::Expr(Expr { kind: ExprKind::Struct(qpath, ..), .. })) => {
+                        Node::Expr(Expr { kind: ExprKind::Struct(qpath, ..), .. }) => {
                             if let QPath::TypeRelative(qpath_ty, ..) = qpath
                                 && qpath_ty.hir_id == ty.hir_id
                             {
diff --git a/compiler/rustc_lint/src/nonstandard_style.rs b/compiler/rustc_lint/src/nonstandard_style.rs
index 05b39829a12..4ecd87e37d3 100644
--- a/compiler/rustc_lint/src/nonstandard_style.rs
+++ b/compiler/rustc_lint/src/nonstandard_style.rs
@@ -427,7 +427,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
 
     fn check_pat(&mut self, cx: &LateContext<'_>, p: &hir::Pat<'_>) {
         if let PatKind::Binding(_, hid, ident, _) = p.kind {
-            if let hir::Node::PatField(field) = cx.tcx.hir().get_parent(hid) {
+            if let hir::Node::PatField(field) = cx.tcx.parent_hir_node(hid) {
                 if !field.is_shorthand {
                     // Only check if a new name has been introduced, to avoid warning
                     // on both the struct definition and this pattern.
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 1205395b890..e4ebae2a973 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -200,8 +200,7 @@ fn lint_overflowing_range_endpoint<'tcx>(
     ty: &str,
 ) -> bool {
     // Look past casts to support cases like `0..256 as u8`
-    let (expr, lit_span) = if let Node::Expr(par_expr) =
-        cx.tcx.hir_node(cx.tcx.hir().parent_id(expr.hir_id))
+    let (expr, lit_span) = if let Node::Expr(par_expr) = cx.tcx.parent_hir_node(expr.hir_id)
         && let ExprKind::Cast(_, _) = par_expr.kind
     {
         (par_expr, expr.span)
@@ -211,9 +210,8 @@ fn lint_overflowing_range_endpoint<'tcx>(
 
     // We only want to handle exclusive (`..`) ranges,
     // which are represented as `ExprKind::Struct`.
-    let par_id = cx.tcx.hir().parent_id(expr.hir_id);
-    let Node::ExprField(field) = cx.tcx.hir_node(par_id) else { return false };
-    let Node::Expr(struct_expr) = cx.tcx.hir().get_parent(field.hir_id) else { return false };
+    let Node::ExprField(field) = cx.tcx.parent_hir_node(expr.hir_id) else { return false };
+    let Node::Expr(struct_expr) = cx.tcx.parent_hir_node(field.hir_id) else { return false };
     if !is_range_literal(struct_expr) {
         return false;
     };
@@ -496,8 +494,7 @@ fn lint_uint_literal<'tcx>(
         _ => bug!(),
     };
     if lit_val < min || lit_val > max {
-        let parent_id = cx.tcx.hir().parent_id(e.hir_id);
-        if let Node::Expr(par_e) = cx.tcx.hir_node(parent_id) {
+        if let Node::Expr(par_e) = cx.tcx.parent_hir_node(e.hir_id) {
             match par_e.kind {
                 hir::ExprKind::Cast(..) => {
                     if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() {
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index bf72aac1033..50817dd0a80 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -82,7 +82,7 @@ impl<'hir> Iterator for ParentHirIterator<'hir> {
         }
 
         // There are nodes that do not have entries, so we need to skip them.
-        let parent_id = self.map.parent_id(self.current_id);
+        let parent_id = self.map.tcx.parent_hir_id(self.current_id);
 
         if parent_id == self.current_id {
             self.current_id = CRATE_HIR_ID;
@@ -175,6 +175,28 @@ impl<'tcx> TyCtxt<'tcx> {
         self.opt_hir_node_by_def_id(id)
             .unwrap_or_else(|| bug!("couldn't find HIR node for def id {id:?}"))
     }
+
+    /// Returns `HirId` of the parent HIR node of node with this `hir_id`.
+    /// Returns the same `hir_id` if and only if `hir_id == CRATE_HIR_ID`.
+    ///
+    /// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`].
+    pub fn parent_hir_id(self, hir_id: HirId) -> HirId {
+        let HirId { owner, local_id } = hir_id;
+        if local_id == ItemLocalId::from_u32(0) {
+            self.hir_owner_parent(owner)
+        } else {
+            let parent_local_id = self.hir_owner_nodes(owner).nodes[local_id].parent;
+            // HIR indexing should have checked that.
+            debug_assert_ne!(parent_local_id, local_id);
+            HirId { owner, local_id: parent_local_id }
+        }
+    }
+
+    /// Returns parent HIR node of node with this `hir_id`.
+    /// Returns HIR node of the same `hir_id` if and only if `hir_id == CRATE_HIR_ID`.
+    pub fn parent_hir_node(self, hir_id: HirId) -> Node<'tcx> {
+        self.hir_node(self.parent_hir_id(hir_id))
+    }
 }
 
 impl<'hir> Map<'hir> {
@@ -217,39 +239,6 @@ impl<'hir> Map<'hir> {
         self.tcx.definitions_untracked().def_path_hash(def_id)
     }
 
-    /// Finds the id of the parent node to this one.
-    ///
-    /// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`].
-    pub fn opt_parent_id(self, id: HirId) -> Option<HirId> {
-        if id.local_id == ItemLocalId::from_u32(0) {
-            // FIXME: This function never returns `None` right now, and the parent chain end is
-            // determined by checking for `parent(id) == id`. This function should return `None`
-            // for the crate root instead.
-            Some(self.tcx.hir_owner_parent(id.owner))
-        } else {
-            let owner = self.tcx.hir_owner_nodes(id.owner);
-            let node = &owner.nodes[id.local_id];
-            let hir_id = HirId { owner: id.owner, local_id: node.parent };
-            // HIR indexing should have checked that.
-            debug_assert_ne!(id.local_id, node.parent);
-            Some(hir_id)
-        }
-    }
-
-    #[track_caller]
-    pub fn parent_id(self, hir_id: HirId) -> HirId {
-        self.opt_parent_id(hir_id)
-            .unwrap_or_else(|| bug!("No parent for node {}", self.node_to_string(hir_id)))
-    }
-
-    pub fn get_parent(self, hir_id: HirId) -> Node<'hir> {
-        self.tcx.hir_node(self.parent_id(hir_id))
-    }
-
-    pub fn find_parent(self, hir_id: HirId) -> Option<Node<'hir>> {
-        Some(self.tcx.hir_node(self.opt_parent_id(hir_id)?))
-    }
-
     pub fn get_if_local(self, id: DefId) -> Option<Node<'hir>> {
         id.as_local()
             .and_then(|id| Some(self.tcx.hir_node(self.tcx.opt_local_def_id_to_hir_id(id)?)))
@@ -304,14 +293,13 @@ impl<'hir> Map<'hir> {
     /// which this is the body of, i.e., a `fn`, `const` or `static`
     /// item (possibly associated), a closure, or a `hir::AnonConst`.
     pub fn body_owner(self, BodyId { hir_id }: BodyId) -> HirId {
-        let parent = self.parent_id(hir_id);
+        let parent = self.tcx.parent_hir_id(hir_id);
         assert!(is_body_owner(self.tcx.hir_node(parent), hir_id), "{hir_id:?}");
         parent
     }
 
     pub fn body_owner_def_id(self, BodyId { hir_id }: BodyId) -> LocalDefId {
-        let parent = self.parent_id(hir_id);
-        associated_body(self.tcx.hir_node(parent)).unwrap().0
+        associated_body(self.tcx.parent_hir_node(hir_id)).unwrap().0
     }
 
     /// Given a `LocalDefId`, returns the `BodyId` associated with it,
@@ -569,8 +557,8 @@ impl<'hir> Map<'hir> {
 
     /// Checks if the node is left-hand side of an assignment.
     pub fn is_lhs(self, id: HirId) -> bool {
-        match self.find_parent(id) {
-            Some(Node::Expr(expr)) => match expr.kind {
+        match self.tcx.parent_hir_node(id) {
+            Node::Expr(expr) => match expr.kind {
                 ExprKind::Assign(lhs, _rhs, _span) => lhs.hir_id == id,
                 _ => false,
             },
@@ -793,7 +781,7 @@ impl<'hir> Map<'hir> {
             Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident),
             // A `Ctor` doesn't have an identifier itself, but its parent
             // struct/variant does. Compare with `hir::Map::span`.
-            Node::Ctor(..) => match self.find_parent(id)? {
+            Node::Ctor(..) => match self.tcx.parent_hir_node(id) {
                 Node::Item(item) => Some(item.ident),
                 Node::Variant(variant) => Some(variant.ident),
                 _ => unreachable!(),
@@ -925,7 +913,7 @@ impl<'hir> Map<'hir> {
                 ForeignItemKind::Fn(decl, _, _) => until_within(item.span, decl.output.span()),
                 _ => named_span(item.span, item.ident, None),
             },
-            Node::Ctor(_) => return self.span(self.parent_id(hir_id)),
+            Node::Ctor(_) => return self.span(self.tcx.parent_hir_id(hir_id)),
             Node::Expr(Expr {
                 kind: ExprKind::Closure(Closure { fn_decl_span, .. }),
                 span,
@@ -968,7 +956,7 @@ impl<'hir> Map<'hir> {
             Node::PatField(field) => field.span,
             Node::Arm(arm) => arm.span,
             Node::Block(block) => block.span,
-            Node::Ctor(..) => self.span_with_body(self.parent_id(hir_id)),
+            Node::Ctor(..) => self.span_with_body(self.tcx.parent_hir_id(hir_id)),
             Node::Lifetime(lifetime) => lifetime.ident.span,
             Node::GenericParam(param) => param.span,
             Node::Infer(i) => i.span,
@@ -1001,7 +989,7 @@ impl<'hir> Map<'hir> {
     /// Returns the HirId of `N` in `struct Foo<const N: usize = { ... }>` when
     /// called with the HirId for the `{ ... }` anon const
     pub fn opt_const_param_default_param_def_id(self, anon_const: HirId) -> Option<LocalDefId> {
-        match self.get_parent(anon_const) {
+        match self.tcx.parent_hir_node(anon_const) {
             Node::GenericParam(GenericParam {
                 def_id: param_id,
                 kind: GenericParamKind::Const { .. },
@@ -1026,7 +1014,7 @@ impl<'hir> Map<'hir> {
             _ => None,
         }?;
 
-        match self.find_parent(expr.hir_id)? {
+        match self.tcx.parent_hir_node(expr.hir_id) {
             Node::ExprField(field) => {
                 if field.ident.name == local.name && field.is_shorthand {
                     return Some(local.name);
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index f66cd2370e3..4ef9bc16221 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -136,13 +136,14 @@ pub fn provide(providers: &mut Providers) {
     };
     providers.opt_hir_owner_nodes =
         |tcx, id| tcx.hir_crate(()).owners.get(id)?.as_owner().map(|i| &i.nodes);
-    providers.hir_owner_parent = |tcx, id| {
-        // Accessing the local_parent is ok since its value is hashed as part of `id`'s DefPathHash.
-        tcx.opt_local_parent(id.def_id).map_or(CRATE_HIR_ID, |parent| {
-            let mut parent_hir_id = tcx.local_def_id_to_hir_id(parent);
-            parent_hir_id.local_id =
-                tcx.hir_crate(()).owners[parent_hir_id.owner.def_id].unwrap().parenting[&id.def_id];
-            parent_hir_id
+    providers.hir_owner_parent = |tcx, owner_id| {
+        tcx.opt_local_parent(owner_id.def_id).map_or(CRATE_HIR_ID, |parent_def_id| {
+            let parent_owner_id = tcx.local_def_id_to_hir_id(parent_def_id).owner;
+            HirId {
+                owner: parent_owner_id,
+                local_id: tcx.hir_crate(()).owners[parent_owner_id.def_id].unwrap().parenting
+                    [&owner_id.def_id],
+            }
         })
     };
     providers.hir_attrs = |tcx, id| {
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index 2d366948771..04740a96291 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -792,7 +792,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 return id;
             }
 
-            let next = hir.parent_id(id);
+            let next = self.tcx.parent_hir_id(id);
             if next == id {
                 bug!("lint traversal reached the root of the crate");
             }
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index ec704dec352..c24827ea902 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -2069,14 +2069,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         span: Span,
         target: Target,
     ) -> bool {
-        let hir = self.tcx.hir();
-
         if let Target::ForeignFn = target
-            && let Some(parent) = hir.opt_parent_id(hir_id)
             && let hir::Node::Item(Item {
                 kind: ItemKind::ForeignMod { abi: Abi::RustIntrinsic | Abi::PlatformIntrinsic, .. },
                 ..
-            }) = self.tcx.hir_node(parent)
+            }) = self.tcx.parent_hir_node(hir_id)
         {
             return true;
         }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index f68200b6f4d..eb75b04ed1c 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1032,15 +1032,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
         };
 
-        let hir = self.tcx.hir();
         let hir_id = self.tcx.local_def_id_to_hir_id(def_id.as_local()?);
-        match hir.find_parent(hir_id) {
-            Some(hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(local), .. })) => {
+        match self.tcx.parent_hir_node(hir_id) {
+            hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(local), .. }) => {
                 get_name(err, &local.pat.kind)
             }
             // Different to previous arm because one is `&hir::Local` and the other
             // is `P<hir::Local>`.
-            Some(hir::Node::Local(local)) => get_name(err, &local.pat.kind),
+            hir::Node::Local(local) => get_name(err, &local.pat.kind),
             _ => None,
         }
     }
@@ -1202,8 +1201,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let hir::Node::Pat(pat) = self.tcx.hir_node(hir_id) else {
             return;
         };
-        let Some(hir::Node::Local(hir::Local { ty: None, init: Some(init), .. })) =
-            self.tcx.hir().find_parent(pat.hir_id)
+        let hir::Node::Local(hir::Local { ty: None, init: Some(init), .. }) =
+            self.tcx.parent_hir_node(pat.hir_id)
         else {
             return;
         };
@@ -1790,7 +1789,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
                 && let Res::Local(hir_id) = path.res
                 && let hir::Node::Pat(binding) = self.tcx.hir_node(hir_id)
-                && let Some(hir::Node::Local(local)) = self.tcx.hir().find_parent(binding.hir_id)
+                && let hir::Node::Local(local) = self.tcx.parent_hir_node(binding.hir_id)
                 && let None = local.ty
                 && let Some(binding_expr) = local.init
             {
@@ -3188,8 +3187,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 }
             }
             ObligationCauseCode::VariableType(hir_id) => {
-                let parent_node = tcx.hir().parent_id(hir_id);
-                match tcx.hir_node(parent_node) {
+                match tcx.parent_hir_node(hir_id) {
                     Node::Local(hir::Local { ty: Some(ty), .. }) => {
                         err.span_suggestion_verbose(
                             ty.span.shrink_to_lo(),
@@ -3237,8 +3235,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                     types always have a known size";
                 if let Some(hir_id) = hir_id
                     && let hir::Node::Param(param) = self.tcx.hir_node(hir_id)
-                    && let Some(item) = self.tcx.hir().find_parent(hir_id)
-                    && let Some(decl) = item.fn_decl()
+                    && let Some(decl) = self.tcx.parent_hir_node(hir_id).fn_decl()
                     && let Some(t) = decl.inputs.iter().find(|t| param.ty_span.contains(t.span))
                 {
                     // We use `contains` because the type might be surrounded by parentheses,
@@ -4079,8 +4076,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
                 && let hir::Path { res: Res::Local(hir_id), .. } = path
                 && let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id)
-                && let parent_hir_id = self.tcx.hir().parent_id(binding.hir_id)
-                && let hir::Node::Local(local) = self.tcx.hir_node(parent_hir_id)
+                && let hir::Node::Local(local) = self.tcx.parent_hir_node(binding.hir_id)
                 && let Some(binding_expr) = local.init
             {
                 // If the expression we're calling on is a binding, we want to point at the
@@ -4338,8 +4334,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
                 && let hir::Path { res: Res::Local(hir_id), .. } = path
                 && let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id)
-                && let Some(parent) = self.tcx.hir().find_parent(binding.hir_id)
             {
+                let parent = self.tcx.parent_hir_node(binding.hir_id);
                 // We've reached the root of the method call chain...
                 if let hir::Node::Local(local) = parent
                     && let Some(binding_expr) = local.init
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 07e4fef9dd4..7d14395850b 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -1162,8 +1162,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
                 && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path
                 && let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id)
-                && let Some(parent) = self.tcx.hir().find_parent(binding.hir_id)
             {
+                let parent = self.tcx.parent_hir_node(binding.hir_id);
                 // We've reached the root of the method call chain...
                 if let hir::Node::Local(local) = parent
                     && let Some(binding_expr) = local.init
diff --git a/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs b/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs
index 1e327f7a6df..9365fbfaed0 100644
--- a/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs
+++ b/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs
@@ -46,11 +46,10 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnConstants {
             return;
         };
         if let ConstantSource::Constant = source
-            && let Some(node) = cx.tcx.hir().find_parent(e.hir_id)
             && let Node::Item(Item {
                 kind: ItemKind::Const(..),
                 ..
-            }) = node
+            }) = cx.tcx.parent_hir_node(e.hir_id)
         {
             return;
         }
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
index 0f29743856a..a31943f0021 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
@@ -67,25 +67,20 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: &Msrv
 }
 
 fn is_child_of_cast(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
-    let map = cx.tcx.hir();
-    if let Some(parent_id) = map.opt_parent_id(expr.hir_id) {
-        let parent = cx.tcx.hir_node(parent_id);
-        let expr = match parent {
-            Node::Block(block) => {
-                if let Some(parent_expr) = block.expr {
-                    parent_expr
-                } else {
-                    return false;
-                }
-            },
-            Node::Expr(expr) => expr,
-            _ => return false,
-        };
+    let parent = cx.tcx.parent_hir_node(expr.hir_id);
+    let expr = match parent {
+        Node::Block(block) => {
+            if let Some(parent_expr) = block.expr {
+                parent_expr
+            } else {
+                return false;
+            }
+        },
+        Node::Expr(expr) => expr,
+        _ => return false,
+    };
 
-        matches!(expr.kind, ExprKind::Cast(..))
-    } else {
-        false
-    }
+    matches!(expr.kind, ExprKind::Cast(..))
 }
 
 /// Returns the type T of the pointed to *const [T] or *mut [T] and the mutability of the slice if
diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
index 81d0def4322..b4a23d0d4db 100644
--- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
@@ -65,7 +65,7 @@ pub(super) fn check<'tcx>(
         && let ExprKind::Path(qpath) = inner.kind
         && let QPath::Resolved(None, Path { res, .. }) = qpath
         && let Res::Local(hir_id) = res
-        && let parent = cx.tcx.hir().get_parent(*hir_id)
+        && let parent = cx.tcx.parent_hir_node(*hir_id)
         && let Node::Local(local) = parent
     {
         if let Some(ty) = local.ty
diff --git a/src/tools/clippy/clippy_lints/src/dbg_macro.rs b/src/tools/clippy/clippy_lints/src/dbg_macro.rs
index 9424a9103db..ec66556cebf 100644
--- a/src/tools/clippy/clippy_lints/src/dbg_macro.rs
+++ b/src/tools/clippy/clippy_lints/src/dbg_macro.rs
@@ -63,7 +63,7 @@ impl LateLintPass<'_> for DbgMacro {
                 ExprKind::Block(..) => {
                     // If the `dbg!` macro is a "free" statement and not contained within other expressions,
                     // remove the whole statement.
-                    if let Some(Node::Stmt(_)) = cx.tcx.hir().find_parent(expr.hir_id)
+                    if let Node::Stmt(_) = cx.tcx.parent_hir_node(expr.hir_id)
                         && let Some(semi_span) = cx.sess().source_map().mac_call_stmt_semi_span(macro_call.span)
                     {
                         (macro_call.span.to(semi_span), String::new())
diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
index c4437a3c4b3..59d2df0295f 100644
--- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
+++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs
@@ -128,8 +128,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> {
                 },
                 _,
             ) => {
-                if let Some(parent) = self.cx.tcx.hir().find_parent(expr.hir_id)
-                    && let Some(fn_sig) = parent.fn_sig()
+                if let Some(fn_sig) = self.cx.tcx.parent_hir_node(expr.hir_id).fn_sig()
                     && let FnRetTy::Return(_ty) = fn_sig.decl.output
                 {
                     // We cannot check the exact type since it's a `hir::Ty`` which does not implement `is_numeric`
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index 194cf69ea7e..cdbb52f497b 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -1088,7 +1088,7 @@ fn report<'tcx>(
                 //
                 // e.g. `&mut x.y.z` where `x` is a union, and accessing `z` requires a
                 // deref through `ManuallyDrop<_>` will not compile.
-                let parent_id = cx.tcx.hir().parent_id(expr.hir_id);
+                let parent_id = cx.tcx.parent_hir_id(expr.hir_id);
                 if parent_id == data.first_expr.hir_id {
                     return;
                 }
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index 218d7c6c01a..064bac2e7dc 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -131,7 +131,7 @@ fn is_argument(tcx: TyCtxt<'_>, id: HirId) -> bool {
         _ => return false,
     }
 
-    matches!(tcx.hir().find_parent(id), Some(Node::Param(_)))
+    matches!(tcx.parent_hir_node(id), Node::Param(_))
 }
 
 impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
@@ -156,8 +156,8 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
             let map = &self.cx.tcx.hir();
             if is_argument(self.cx.tcx, cmt.hir_id) {
                 // Skip closure arguments
-                let parent_id = map.parent_id(cmt.hir_id);
-                if let Some(Node::Expr(..)) = map.find_parent(parent_id) {
+                let parent_id = self.cx.tcx.parent_hir_id(cmt.hir_id);
+                if let Node::Expr(..) = self.cx.tcx.parent_hir_node(parent_id) {
                     return;
                 }
 
diff --git a/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs b/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs
index 8fba41c0e24..6fb38a0d6dd 100644
--- a/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/impl_trait_in_params.rs
@@ -53,7 +53,7 @@ pub(super) fn check_fn<'tcx>(cx: &LateContext<'_>, kind: &'tcx FnKind<'_>, body:
 
 pub(super) fn check_impl_item(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {
     if let ImplItemKind::Fn(_, body_id) = impl_item.kind
-        && let hir::Node::Item(item) = cx.tcx.hir().get_parent(impl_item.hir_id())
+        && let hir::Node::Item(item) = cx.tcx.parent_hir_node(impl_item.hir_id())
         && let hir::ItemKind::Impl(impl_) = item.kind
         && let hir::Impl { of_trait, .. } = *impl_
         && of_trait.is_none()
@@ -72,7 +72,7 @@ pub(super) fn check_impl_item(cx: &LateContext<'_>, impl_item: &ImplItem<'_>) {
 pub(super) fn check_trait_item(cx: &LateContext<'_>, trait_item: &TraitItem<'_>, avoid_breaking_exported_api: bool) {
     if !avoid_breaking_exported_api
         && let TraitItemKind::Fn(_, _) = trait_item.kind
-        && let hir::Node::Item(item) = cx.tcx.hir().get_parent(trait_item.hir_id())
+        && let hir::Node::Item(item) = cx.tcx.parent_hir_node(trait_item.hir_id())
         // ^^ (Will always be a trait)
         && !item.vis_span.is_empty() // Is public
         && !is_in_test_function(cx.tcx, trait_item.hir_id())
diff --git a/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs b/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs
index 0a2fd0c663e..80a537b9f94 100644
--- a/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs
@@ -41,8 +41,8 @@ impl<'tcx> LateLintPass<'tcx> for IgnoredUnitPatterns {
             return;
         }
 
-        match cx.tcx.hir().get_parent(pat.hir_id) {
-            Node::Param(param) if matches!(cx.tcx.hir().get_parent(param.hir_id), Node::Item(_)) => {
+        match cx.tcx.parent_hir_node(pat.hir_id) {
+            Node::Param(param) if matches!(cx.tcx.parent_hir_node(param.hir_id), Node::Item(_)) => {
                 // Ignore function parameters
                 return;
             },
diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
index 252be30c4e2..51b4f26b6d1 100644
--- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
+++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
@@ -242,12 +242,8 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
             } = *self;
 
             if let Some(use_info) = slice_lint_info.get_mut(&local_id)
-                // Check if this is even a local we're interested in
-
-                && let map = cx.tcx.hir()
-
                 // Checking for slice indexing
-                && let parent_id = map.parent_id(expr.hir_id)
+                && let parent_id = cx.tcx.parent_hir_id(expr.hir_id)
                 && let hir::Node::Expr(parent_expr) = cx.tcx.hir_node(parent_id)
                 && let hir::ExprKind::Index(_, index_expr, _) = parent_expr.kind
                 && let Some(Constant::Int(index_value)) = constant(cx, cx.typeck_results(), index_expr)
@@ -255,11 +251,10 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
                 && index_value < max_suggested_slice
 
                 // Make sure that this slice index is read only
-                && let maybe_addrof_id = map.parent_id(parent_id)
-                && let hir::Node::Expr(maybe_addrof_expr) = cx.tcx.hir_node(maybe_addrof_id)
+                && let hir::Node::Expr(maybe_addrof_expr) = cx.tcx.parent_hir_node(parent_id)
                 && let hir::ExprKind::AddrOf(_kind, hir::Mutability::Not, _inner_expr) = maybe_addrof_expr.kind
             {
-                use_info.index_use.push((index_value, map.span(parent_expr.hir_id)));
+                use_info.index_use.push((index_value, cx.tcx.hir().span(parent_expr.hir_id)));
                 return;
             }
 
diff --git a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
index 82a37bb4f27..b5821d909f8 100644
--- a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
+++ b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
@@ -269,7 +269,7 @@ impl {self_ty_without_ref} {{
                     // }
                     let span_behind_impl = cx
                         .tcx
-                        .def_span(cx.tcx.hir().parent_id(item.hir_id()).owner.def_id)
+                        .def_span(cx.tcx.parent_hir_id(item.hir_id()).owner.def_id)
                         .shrink_to_lo();
 
                     let sugg = format!(
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index f5636945f20..2b73663d229 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -285,7 +285,7 @@ fn elision_suggestions(
             .iter()
             .filter(|usage| named_lifetime(usage).map_or(false, |id| elidable_lts.contains(&id)))
             .map(|usage| {
-                match cx.tcx.hir().get_parent(usage.hir_id) {
+                match cx.tcx.parent_hir_node(usage.hir_id) {
                     Node::Ty(Ty {
                         kind: TyKind::Ref(..), ..
                     }) => {
diff --git a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
index 5f015db2b33..0f35514b8ad 100644
--- a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
@@ -62,8 +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 parent_node = cx.tcx.hir().parent_id(hir_id)
-                            && let Node::Local(parent_let_expr) = cx.tcx.hir_node(parent_node)
+                            && let Node::Local(parent_let_expr) = cx.tcx.parent_hir_node(hir_id)
                             && let Some(init) = parent_let_expr.init
                         {
                             match init.kind {
diff --git a/src/tools/clippy/clippy_lints/src/manual_hash_one.rs b/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
index 73687fbbe54..5cbab0ec977 100644
--- a/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
@@ -68,8 +68,8 @@ impl LateLintPass<'_> for ManualHashOne {
             && let ExprKind::MethodCall(seg, build_hasher, [], _) = init.kind
             && seg.ident.name == sym!(build_hasher)
 
-            && let Node::Stmt(local_stmt) = cx.tcx.hir().get_parent(local.hir_id)
-            && let Node::Block(block) = cx.tcx.hir().get_parent(local_stmt.hir_id)
+            && let Node::Stmt(local_stmt) = cx.tcx.parent_hir_node(local.hir_id)
+            && let Node::Block(block) = cx.tcx.parent_hir_node(local_stmt.hir_id)
 
             && let mut stmts = block.stmts.iter()
                 .skip_while(|stmt| stmt.hir_id != local_stmt.hir_id)
@@ -91,7 +91,7 @@ impl LateLintPass<'_> for ManualHashOne {
 
             // `hasher.finish()`, may be anywhere in a statement or the trailing expr of the block
             && let Some(path_expr) = local_used_once(cx, (maybe_finish_stmt, block.expr), hasher)
-            && let Node::Expr(finish_expr) = cx.tcx.hir().get_parent(path_expr.hir_id)
+            && let Node::Expr(finish_expr) = cx.tcx.parent_hir_node(path_expr.hir_id)
             && !finish_expr.span.from_expansion()
             && let ExprKind::MethodCall(seg, _, [], _) = finish_expr.kind
             && seg.ident.name == sym!(finish)
diff --git a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
index e1768c6d976..0bde62bd554 100644
--- a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
@@ -79,9 +79,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
             && let Node::Pat(_) = cx.tcx.hir_node(hir_id)
         {
             // Apply only to params or locals with annotated types
-            match cx.tcx.hir().find_parent(hir_id) {
-                Some(Node::Param(..)) => (),
-                Some(Node::Local(local)) => {
+            match cx.tcx.parent_hir_node(hir_id) {
+                Node::Param(..) => (),
+                Node::Local(local) => {
                     let Some(ty) = local.ty else { return };
                     if matches!(ty.kind, TyKind::Infer) {
                         return;
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs b/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs
index 89da7a55cbd..61977045fd4 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_single_binding.rs
@@ -36,7 +36,7 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e
     .to_string();
 
     // Do we need to add ';' to suggestion ?
-    if let Node::Stmt(stmt) = cx.tcx.hir().get_parent(expr.hir_id)
+    if let Node::Stmt(stmt) = cx.tcx.parent_hir_node(expr.hir_id)
         && let StmtKind::Expr(_) = stmt.kind
         && match match_body.kind {
             // We don't need to add a ; to blocks, unless that block is from a macro expansion
@@ -146,18 +146,16 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e
 
 /// Returns true if the `ex` match expression is in a local (`let`) or assign expression
 fn opt_parent_assign_span<'a>(cx: &LateContext<'a>, ex: &Expr<'a>) -> Option<AssignmentExpr> {
-    let map = &cx.tcx.hir();
-
-    if let Some(Node::Expr(parent_arm_expr)) = map.find_parent(ex.hir_id) {
-        return match map.find_parent(parent_arm_expr.hir_id) {
-            Some(Node::Local(parent_let_expr)) => Some(AssignmentExpr::Local {
+    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 {
                 span: parent_let_expr.span,
                 pat_span: parent_let_expr.pat.span(),
             }),
-            Some(Node::Expr(Expr {
+            Node::Expr(Expr {
                 kind: ExprKind::Assign(parent_assign_expr, match_expr, _),
                 ..
-            })) => Some(AssignmentExpr::Assign {
+            }) => Some(AssignmentExpr::Assign {
                 span: parent_assign_expr.span,
                 match_span: match_expr.span,
             }),
@@ -191,7 +189,7 @@ fn sugg_with_curlies<'a>(
 
     // If the parent is already an arm, and the body is another match statement,
     // we need curly braces around suggestion
-    if let Node::Arm(arm) = &cx.tcx.hir().get_parent(match_expr.hir_id) {
+    if let Node::Arm(arm) = &cx.tcx.parent_hir_node(match_expr.hir_id) {
         if let ExprKind::Match(..) = arm.body.kind {
             cbrace_end = format!("\n{indent}}}");
             // Fix body indent due to the match
diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
index dfaaeb14ca3..a1b82679f2e 100644
--- a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
@@ -199,7 +199,7 @@ fn get_pat_binding<'tcx>(
             return span.map(|span| PatBindingInfo {
                 span,
                 byref_ident,
-                is_field: matches!(cx.tcx.hir().get_parent(local), Node::PatField(_)),
+                is_field: matches!(cx.tcx.parent_hir_node(local), Node::PatField(_)),
             });
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index e8a7a321bf4..1452547807b 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -4458,7 +4458,7 @@ impl Methods {
                     _ => {},
                 },
                 ("drain", ..) => {
-                    if let Node::Stmt(Stmt { hir_id: _, kind, .. }) = cx.tcx.hir().get_parent(expr.hir_id)
+                    if let Node::Stmt(Stmt { hir_id: _, kind, .. }) = cx.tcx.parent_hir_node(expr.hir_id)
                         && matches!(kind, StmtKind::Semi(_))
                         && args.len() <= 1
                     {
diff --git a/src/tools/clippy/clippy_lints/src/methods/readonly_write_lock.rs b/src/tools/clippy/clippy_lints/src/methods/readonly_write_lock.rs
index 1184dd4525a..6c6846c4b47 100644
--- a/src/tools/clippy/clippy_lints/src/methods/readonly_write_lock.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/readonly_write_lock.rs
@@ -21,9 +21,9 @@ fn is_unwrap_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, receiver: &Expr<'_>) {
     if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(receiver).peel_refs(), sym::RwLock)
-        && let Node::Expr(unwrap_call_expr) = cx.tcx.hir().get_parent(expr.hir_id)
+        && 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.hir().get_parent(unwrap_call_expr.hir_id)
+        && let parent = cx.tcx.parent_hir_node(unwrap_call_expr.hir_id)
         && let Node::Local(local) = parent
         && let Some(mir) = enclosing_mir(cx.tcx, expr.hir_id)
         && let Some((local, _)) = mir
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs
index 2046692bbd0..988f3e86fcf 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs
@@ -16,7 +16,7 @@ use super::UNNECESSARY_FOLD;
 /// Changing `fold` to `sum` needs it sometimes when the return type can't be
 /// inferred. This checks for some common cases where it can be safely omitted
 fn needs_turbofish(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
-    let parent = cx.tcx.hir().get_parent(expr.hir_id);
+    let parent = cx.tcx.parent_hir_node(expr.hir_id);
 
     // some common cases where turbofish isn't needed:
     // - assigned to a local variable with a type annotation
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs
index a1125d70db3..1b2bfbf4090 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs
@@ -76,7 +76,7 @@ pub(super) fn check(
                     (expr.span.with_lo(call_args[0].span.hi()), String::new()),
                 ];
                 // try to also remove the unsafe block if present
-                if let hir::Node::Block(block) = cx.tcx.hir().get_parent(expr.hir_id)
+                if let hir::Node::Block(block) = cx.tcx.parent_hir_node(expr.hir_id)
                     && let hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) = block.rules
                 {
                     suggs.extend([
diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
index b593e48ae2e..a1f7dc7b38c 100644
--- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
+++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -206,10 +206,9 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
 ///
 /// When such a read is found, the lint is triggered.
 fn check_for_unsequenced_reads(vis: &mut ReadVisitor<'_, '_>) {
-    let map = &vis.cx.tcx.hir();
     let mut cur_id = vis.write_expr.hir_id;
     loop {
-        let parent_id = map.parent_id(cur_id);
+        let parent_id = vis.cx.tcx.parent_hir_id(cur_id);
         if parent_id == cur_id {
             break;
         }
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
index d2eef6ae433..149d440ecac 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
@@ -161,7 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
         };
 
         // Exclude non-inherent impls
-        if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) {
+        if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id) {
             if matches!(
                 item.kind,
                 ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..)
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
index 2c5c3dcaa75..384a402ce5b 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs
@@ -100,7 +100,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
         }
 
         // Exclude non-inherent impls
-        if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) {
+        if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id) {
             if matches!(
                 item.kind,
                 ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..)
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index 10ab380ba1b..ea73d9afa2e 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -449,7 +449,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
             let mut dereferenced_expr = expr;
             let mut needs_check_adjustment = true;
             loop {
-                let parent_id = cx.tcx.hir().parent_id(cur_expr.hir_id);
+                let parent_id = cx.tcx.parent_hir_id(cur_expr.hir_id);
                 if parent_id == cur_expr.hir_id {
                     break;
                 }
diff --git a/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs b/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs
index 40d4a842bef..2a933a11e12 100644
--- a/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs
@@ -34,7 +34,7 @@ pub(super) fn check<'tcx>(
 }
 
 fn used_in_comparison_with_zero(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
-    let Some(Node::Expr(parent_expr)) = cx.tcx.hir().find_parent(expr.hir_id) else {
+    let Node::Expr(parent_expr) = cx.tcx.parent_hir_node(expr.hir_id) else {
         return false;
     };
     let ExprKind::Binary(op, lhs, rhs) = parent_expr.kind else {
diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
index 57d37067e8f..ec03ab0e41a 100644
--- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
+++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
@@ -301,7 +301,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue {
         }
 
         // Exclude non-inherent impls
-        if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) {
+        if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id) {
             if matches!(
                 item.kind,
                 ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..)
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
index 513a913f56a..bbecc39a813 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
@@ -41,7 +41,7 @@ pub(super) fn check<'tcx>(
         _ => return false,
     };
 
-    if let Node::Expr(parent) = cx.tcx.hir().get_parent(e.hir_id)
+    if let Node::Expr(parent) = cx.tcx.parent_hir_node(e.hir_id)
         && parent.precedence().order() > ExprPrecedence::Cast.order()
     {
         sugg = format!("({sugg})");
diff --git a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
index e1cd82e18d5..c11504cd2d4 100644
--- a/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/tuple_array_conversions.rs
@@ -153,13 +153,10 @@ fn all_bindings_are_for_conv<'tcx>(
     let Some(locals) = locals.iter().map(|e| path_to_local(e)).collect::<Option<Vec<_>>>() else {
         return false;
     };
-    let Some(local_parents) = locals
+    let local_parents = locals
         .iter()
-        .map(|&l| cx.tcx.hir().find_parent(l))
-        .collect::<Option<Vec<_>>>()
-    else {
-        return false;
-    };
+        .map(|l| cx.tcx.parent_hir_node(*l))
+        .collect::<Vec<_>>();
 
     local_parents
         .iter()
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
index 44cff78a793..eba7fa7b993 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
@@ -19,9 +19,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
     if is_questionmark_desugar_marked_call(expr) {
         return;
     }
-    let map = &cx.tcx.hir();
-    let opt_parent_node = map.find_parent(expr.hir_id);
-    if let Some(hir::Node::Expr(parent_expr)) = opt_parent_node
+    if let hir::Node::Expr(parent_expr) = cx.tcx.parent_hir_node(expr.hir_id)
         && is_questionmark_desugar_marked_call(parent_expr)
     {
         return;
@@ -183,8 +181,8 @@ fn fmt_stmts_and_call(
 
     let mut stmts_and_call_snippet = stmts_and_call.join(&format!("{}{}", ";\n", " ".repeat(call_expr_indent)));
     // expr is not in a block statement or result expression position, wrap in a block
-    let parent_node = cx.tcx.hir().find_parent(call_expr.hir_id);
-    if !matches!(parent_node, Some(Node::Block(_))) && !matches!(parent_node, Some(Node::Stmt(_))) {
+    let parent_node = cx.tcx.parent_hir_node(call_expr.hir_id);
+    if !matches!(parent_node, Node::Block(_)) && !matches!(parent_node, Node::Stmt(_)) {
         let block_indent = call_expr_indent + 4;
         stmts_and_call_snippet =
             reindent_multiline(stmts_and_call_snippet.into(), true, Some(block_indent)).into_owned();
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs b/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs
index f5af540fa14..c332cf076ae 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs
@@ -116,7 +116,7 @@ impl LateLintPass<'_> for UnnecessaryBoxReturns {
     fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'_>) {
         // Ignore implementations of traits, because the lint should be on the
         // trait, not on the implementation of it.
-        let Node::Item(parent) = cx.tcx.hir().get_parent(item.hir_id()) else {
+        let Node::Item(parent) = cx.tcx.parent_hir_node(item.hir_id()) else {
             return;
         };
         let ItemKind::Impl(parent) = parent.kind else { return };
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
index 446160f8e0f..9c8b0ae1727 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
@@ -92,7 +92,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
 
         // Abort if the method is implementing a trait or of it a trait method.
         let hir_id = cx.tcx.local_def_id_to_hir_id(def_id);
-        if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) {
+        if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id) {
             if matches!(
                 item.kind,
                 ItemKind::Impl(Impl { of_trait: Some(_), .. }) | ItemKind::Trait(..)
diff --git a/src/tools/clippy/clippy_lints/src/unused_async.rs b/src/tools/clippy/clippy_lints/src/unused_async.rs
index 1d42375ba8e..738fba54fa8 100644
--- a/src/tools/clippy/clippy_lints/src/unused_async.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_async.rs
@@ -156,7 +156,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync {
             && let Some(local_def_id) = def_id.as_local()
             && cx.tcx.def_kind(def_id) == DefKind::Fn
             && cx.tcx.asyncness(def_id).is_async()
-            && !is_node_func_call(cx.tcx.hir().get_parent(hir_id), path.span)
+            && !is_node_func_call(cx.tcx.parent_hir_node(hir_id), path.span)
         {
             self.async_fns_as_value.insert(local_def_id);
         }
diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs
index ae2ac38cffe..f2eb774b5cb 100644
--- a/src/tools/clippy/clippy_lints/src/unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/unwrap.rs
@@ -208,7 +208,7 @@ struct MutationVisitor<'tcx> {
 /// (i.e. the `x` in `x.as_mut()`), and that is the reason for why we care about its parent
 /// expression: that will be where the actual method call is.
 fn is_option_as_mut_use(tcx: TyCtxt<'_>, expr_id: HirId) -> bool {
-    if let Node::Expr(mutating_expr) = tcx.hir().get_parent(expr_id)
+    if let Node::Expr(mutating_expr) = tcx.parent_hir_node(expr_id)
         && let ExprKind::MethodCall(path, ..) = mutating_expr.kind
     {
         path.ident.name.as_str() == "as_mut"
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
index fae1b90ace2..349e0e3e077 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
@@ -1007,9 +1007,9 @@ fn get_parent_local<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'hir>) -
 fn get_parent_local_hir_id<'hir>(cx: &LateContext<'hir>, hir_id: hir::HirId) -> Option<&'hir hir::Local<'hir>> {
     let map = cx.tcx.hir();
 
-    match map.find_parent(hir_id) {
-        Some(hir::Node::Local(local)) => Some(local),
-        Some(hir::Node::Pat(pattern)) => get_parent_local_hir_id(cx, pattern.hir_id),
+    match cx.tcx.parent_hir_node(hir_id) {
+        hir::Node::Local(local) => Some(local),
+        hir::Node::Pat(pattern) => get_parent_local_hir_id(cx, pattern.hir_id),
         _ => None,
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
index 6e449dc9806..38c832931fc 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
@@ -217,8 +217,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
     match peel_hir_expr_refs(expr).0.kind {
         ExprKind::Path(ref qpath) => match cx.qpath_res(qpath, expr.hir_id) {
             Res::Local(hir_id) => {
-                let parent_id = cx.tcx.hir().parent_id(hir_id);
-                if let Node::Local(Local { init: Some(init), .. }) = cx.tcx.hir_node(parent_id) {
+                if let Node::Local(Local { init: Some(init), .. }) = cx.tcx.parent_hir_node(hir_id) {
                     path_to_matched_type(cx, init)
                 } else {
                     None
diff --git a/src/tools/clippy/clippy_lints/src/vec.rs b/src/tools/clippy/clippy_lints/src/vec.rs
index 2c33c93412a..b3489142558 100644
--- a/src/tools/clippy/clippy_lints/src/vec.rs
+++ b/src/tools/clippy/clippy_lints/src/vec.rs
@@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
         if let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows()) {
             // 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)
-            if let Node::Local(local) = cx.tcx.hir().get_parent(expr.hir_id)
+            if let Node::Local(local) = cx.tcx.parent_hir_node(expr.hir_id)
                 // for now ignore locals with type annotations.
                 // this is to avoid compile errors when doing the suggestion here: let _: Vec<_> = vec![..];
                 && local.ty.is_none()
@@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
             }
             // if the local pattern has a specified type, do not lint.
             else if let Some(_) = higher::VecArgs::hir(cx, expr)
-                && let Node::Local(local) = cx.tcx.hir().get_parent(expr.hir_id)
+                && let Node::Local(local) = cx.tcx.parent_hir_node(expr.hir_id)
                 && local.ty.is_some()
             {
                 let span = expr.span.ctxt().outer_expn_data().call_site;
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 6a33e11be46..67a18caca0e 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -182,11 +182,9 @@ pub fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr
 /// Note: If you have an expression that references a binding `x`, use `path_to_local` to get the
 /// canonical binding `HirId`.
 pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> {
-    let hir = cx.tcx.hir();
     if let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
         && matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..))
-        && let parent = hir.parent_id(hir_id)
-        && let Node::Local(local) = cx.tcx.hir_node(parent)
+        && let Node::Local(local) = cx.tcx.parent_hir_node(hir_id)
     {
         return local.init;
     }
@@ -333,7 +331,7 @@ pub fn is_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, diag_item: Symbol)
 /// Checks if the `def_id` belongs to a function that is part of a trait impl.
 pub fn is_def_id_trait_method(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {
     if let Some(hir_id) = cx.tcx.opt_local_def_id_to_hir_id(def_id)
-        && let Node::Item(item) = cx.tcx.hir().get_parent(hir_id)
+        && let Node::Item(item) = cx.tcx.parent_hir_node(hir_id)
         && let ItemKind::Impl(imp) = item.kind
     {
         imp.of_trait.is_some()
@@ -1311,7 +1309,7 @@ pub fn contains_return<'tcx>(expr: impl Visitable<'tcx>) -> bool {
 
 /// Gets the parent node, if any.
 pub fn get_parent_node(tcx: TyCtxt<'_>, id: HirId) -> Option<Node<'_>> {
-    tcx.hir().find_parent(id)
+    Some(tcx.parent_hir_node(id))
 }
 
 /// Gets the parent expression, if any –- this is useful to constrain a lint.
@@ -2227,7 +2225,7 @@ pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool {
 /// }
 /// ```
 pub fn is_trait_impl_item(cx: &LateContext<'_>, hir_id: HirId) -> bool {
-    if let Some(Node::Item(item)) = cx.tcx.hir().find_parent(hir_id) {
+    if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id) {
         matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }))
     } else {
         false
diff --git a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
index adca2ca1c3e..7913926928f 100644
--- a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
@@ -237,7 +237,7 @@ fn path_segment_certainty(
         },
 
         // `get_parent` because `hir_id` refers to a `Pat`, and we're interested in the node containing the `Pat`.
-        Res::Local(hir_id) => match cx.tcx.hir().get_parent(hir_id) {
+        Res::Local(hir_id) => match cx.tcx.parent_hir_node(hir_id) {
             // An argument's type is always certain.
             Node::Param(..) => Certainty::Certain(None),
             // A local's type is certain if its type annotation is certain or it has an initializer whose