Stop using HirId for fn-like parents

(cherry picked from commit 68d7c837fc377ac4145d931171fa2b1d1bd1670f)
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 792359c..7f73515 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -1859,16 +1859,17 @@
             }
         }
 
-        let parent_id = fcx.tcx.hir().get_parent_item(id);
-        let mut parent_item = fcx.tcx.hir_node_by_def_id(parent_id.def_id);
+        let mut parent_id = fcx.tcx.hir().get_parent_item(id).def_id;
+        let mut parent_item = fcx.tcx.hir_node_by_def_id(parent_id);
         // When suggesting return, we need to account for closures and async blocks, not just items.
         for (_, node) in fcx.tcx.hir().parent_iter(id) {
             match node {
                 hir::Node::Expr(&hir::Expr {
-                    kind: hir::ExprKind::Closure(hir::Closure { .. }),
+                    kind: hir::ExprKind::Closure(hir::Closure { def_id, .. }),
                     ..
                 }) => {
                     parent_item = node;
+                    parent_id = *def_id;
                     break;
                 }
                 hir::Node::Item(_) | hir::Node::TraitItem(_) | hir::Node::ImplItem(_) => break,
@@ -1878,13 +1879,7 @@
 
         if let (Some(expr), Some(_), Some(fn_decl)) = (expression, blk_id, parent_item.fn_decl()) {
             fcx.suggest_missing_break_or_return_expr(
-                &mut err,
-                expr,
-                fn_decl,
-                expected,
-                found,
-                id,
-                parent_id.into(),
+                &mut err, expr, fn_decl, expected, found, id, parent_id,
             );
         }
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index dd44fdd..0045d00 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -932,7 +932,7 @@
     pub(in super::super) fn get_node_fn_decl(
         &self,
         node: Node<'tcx>,
-    ) -> Option<(hir::HirId, &'tcx hir::FnDecl<'tcx>, Ident, bool)> {
+    ) -> Option<(LocalDefId, &'tcx hir::FnDecl<'tcx>, Ident, bool)> {
         match node {
             Node::Item(&hir::Item {
                 ident,
@@ -943,25 +943,20 @@
                 // This is less than ideal, it will not suggest a return type span on any
                 // method called `main`, regardless of whether it is actually the entry point,
                 // but it will still present it as the reason for the expected type.
-                Some((
-                    hir::HirId::make_owner(owner_id.def_id),
-                    &sig.decl,
-                    ident,
-                    ident.name != sym::main,
-                ))
+                Some((owner_id.def_id, &sig.decl, ident, ident.name != sym::main))
             }
             Node::TraitItem(&hir::TraitItem {
                 ident,
                 kind: hir::TraitItemKind::Fn(ref sig, ..),
                 owner_id,
                 ..
-            }) => Some((hir::HirId::make_owner(owner_id.def_id), &sig.decl, ident, true)),
+            }) => Some((owner_id.def_id, &sig.decl, ident, true)),
             Node::ImplItem(&hir::ImplItem {
                 ident,
                 kind: hir::ImplItemKind::Fn(ref sig, ..),
                 owner_id,
                 ..
-            }) => Some((hir::HirId::make_owner(owner_id.def_id), &sig.decl, ident, false)),
+            }) => Some((owner_id.def_id, &sig.decl, ident, false)),
             Node::Expr(&hir::Expr {
                 hir_id,
                 kind:
@@ -991,12 +986,7 @@
                     }) => (ident, sig, owner_id),
                     _ => return None,
                 };
-                Some((
-                    hir::HirId::make_owner(owner_id.def_id),
-                    &sig.decl,
-                    ident,
-                    ident.name != sym::main,
-                ))
+                Some((owner_id.def_id, &sig.decl, ident, ident.name != sym::main))
             }
             _ => None,
         }
@@ -1007,7 +997,7 @@
     pub fn get_fn_decl(
         &self,
         blk_id: hir::HirId,
-    ) -> Option<(hir::HirId, &'tcx hir::FnDecl<'tcx>, bool)> {
+    ) -> Option<(LocalDefId, &'tcx hir::FnDecl<'tcx>, bool)> {
         // Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
         // `while` before reaching it, as block tail returns are not available in them.
         self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 3f6f4cc..29f05ed 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -10,6 +10,7 @@
 use crate::ty::TypeAndMut;
 use core::cmp::min;
 use core::iter;
+use hir::def_id::LocalDefId;
 use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
 use rustc_data_structures::packed::Pu128;
 use rustc_errors::{Applicability, Diag, MultiSpan};
@@ -796,7 +797,7 @@
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
         can_suggest: bool,
-        fn_id: hir::HirId,
+        fn_id: LocalDefId,
     ) -> bool {
         let found =
             self.resolve_numeric_literals_with_default(self.resolve_vars_if_possible(found));
@@ -912,7 +913,7 @@
         err: &mut Diag<'_>,
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
-        fn_id: hir::HirId,
+        fn_id: LocalDefId,
     ) {
         // Only apply the suggestion if:
         //  - the return type is a generic parameter
@@ -926,7 +927,7 @@
 
         let ty::Param(expected_ty_as_param) = expected.kind() else { return };
 
-        let fn_node = self.tcx.hir_node(fn_id);
+        let fn_node = self.tcx.hir_node_by_def_id(fn_id);
 
         let hir::Node::Item(hir::Item {
             kind:
@@ -1020,7 +1021,7 @@
         expected: Ty<'tcx>,
         found: Ty<'tcx>,
         id: hir::HirId,
-        fn_id: hir::HirId,
+        fn_id: LocalDefId,
     ) {
         if !expected.is_unit() {
             return;
@@ -1072,11 +1073,11 @@
         let can_return = match fn_decl.output {
             hir::FnRetTy::Return(ty) => {
                 let ty = self.astconv().ast_ty_to_ty(ty);
-                let bound_vars = self.tcx.late_bound_vars(fn_id);
+                let bound_vars = self.tcx.late_bound_vars(self.tcx.local_def_id_to_hir_id(fn_id));
                 let ty = self
                     .tcx
                     .instantiate_bound_regions_with_erased(Binder::bind_with_vars(ty, bound_vars));
-                let ty = match self.tcx.asyncness(fn_id.owner) {
+                let ty = match self.tcx.asyncness(fn_id) {
                     ty::Asyncness::Yes => self.get_impl_future_output_ty(ty).unwrap_or_else(|| {
                         span_bug!(
                             fn_decl.output.span(),
@@ -1097,8 +1098,9 @@
             _ => false,
         };
         if can_return
-            && let Some(owner_node) = self.tcx.hir_node(fn_id).as_owner()
-            && let Some(span) = expr.span.find_ancestor_inside(*owner_node.span())
+            && let Some(span) = expr.span.find_ancestor_inside(
+                self.tcx.hir().span_with_body(self.tcx.local_def_id_to_hir_id(fn_id)),
+            )
         {
             err.multipart_suggestion(
                 "you might have meant to return this value",
diff --git a/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.rs b/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.rs
new file mode 100644
index 0000000..8ad99a4
--- /dev/null
+++ b/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.rs
@@ -0,0 +1,17 @@
+//@ edition: 2021
+
+fn call(_: impl Fn() -> bool) {}
+
+async fn test() {
+    call(|| -> Option<()> {
+        //~^ ERROR expected
+        if true {
+            false
+            //~^ ERROR mismatched types
+        }
+        true
+        //~^ ERROR mismatched types
+    })
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr b/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr
new file mode 100644
index 0000000..70cd9f9
--- /dev/null
+++ b/tests/ui/async-await/dont-ice-for-type-mismatch-in-closure-in-async.stderr
@@ -0,0 +1,46 @@
+error[E0308]: mismatched types
+  --> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:9:13
+   |
+LL | /         if true {
+LL | |             false
+   | |             ^^^^^ expected `()`, found `bool`
+LL | |
+LL | |         }
+   | |_________- expected this to be `()`
+
+error[E0308]: mismatched types
+  --> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:12:9
+   |
+LL |         true
+   |         ^^^^ expected `Option<()>`, found `bool`
+   |
+   = note: expected enum `Option<()>`
+              found type `bool`
+
+error[E0271]: expected `{closure@dont-ice-for-type-mismatch-in-closure-in-async.rs:6:10}` to be a closure that returns `bool`, but it returns `Option<()>`
+  --> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:6:10
+   |
+LL |       call(|| -> Option<()> {
+   |  _____----_^
+   | |     |
+   | |     required by a bound introduced by this call
+LL | |
+LL | |         if true {
+LL | |             false
+...  |
+LL | |
+LL | |     })
+   | |_____^ expected `bool`, found `Option<()>`
+   |
+   = note: expected type `bool`
+              found enum `Option<()>`
+note: required by a bound in `call`
+  --> $DIR/dont-ice-for-type-mismatch-in-closure-in-async.rs:3:25
+   |
+LL | fn call(_: impl Fn() -> bool) {}
+   |                         ^^^^ required by this bound in `call`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0271, E0308.
+For more information about an error, try `rustc --explain E0271`.