Introduce TypeInformationCtxt to abstract over LateCtxt/FnCtxt
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index b8fed4b..627c7b4 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -2,7 +2,8 @@
 //! normal visitor, which just walks the entire body in one shot, the
 //! `ExprUseVisitor` determines how expressions are being used.
 
-use std::cell::RefCell;
+use std::cell::{Ref, RefCell};
+use std::ops::Deref;
 use std::slice::from_ref;
 
 use hir::def::DefKind;
@@ -16,7 +17,6 @@
 use rustc_hir::def::{CtorOf, Res};
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::{HirId, PatKind};
-use rustc_infer::infer::InferCtxt;
 use rustc_middle::hir::place::ProjectionKind;
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::{
@@ -24,9 +24,11 @@
 };
 use rustc_span::{ErrorGuaranteed, Span};
 use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
-use rustc_trait_selection::infer::InferCtxtExt as _;
+use rustc_trait_selection::infer::InferCtxtExt;
 use ty::BorrowKind::ImmBorrow;
 
+use crate::fn_ctxt::FnCtxt;
+
 type McResult<T> = Result<T, ErrorGuaranteed>;
 
 /// This trait defines the callbacks you can expect to receive when
@@ -122,16 +124,61 @@
     }
 }
 
+pub trait TypeInformationCtxt<'tcx> {
+    type TypeckResults<'a>: Deref<Target = ty::TypeckResults<'tcx>>
+    where
+        Self: 'a;
+
+    fn typeck_results(&self) -> Self::TypeckResults<'_>;
+
+    fn resolve_vars_if_possible<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T;
+
+    fn tainted_by_errors(&self) -> Option<ErrorGuaranteed>;
+
+    fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool;
+
+    fn body_owner_def_id(&self) -> LocalDefId;
+
+    fn tcx(&self) -> TyCtxt<'tcx>;
+}
+
+impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> {
+    type TypeckResults<'a> = Ref<'a, ty::TypeckResults<'tcx>>
+    where
+        Self: 'a;
+
+    fn typeck_results(&self) -> Self::TypeckResults<'_> {
+        self.typeck_results.borrow()
+    }
+
+    fn resolve_vars_if_possible<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T {
+        self.infcx.resolve_vars_if_possible(t)
+    }
+
+    fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
+        if let Some(guar) = self.infcx.tainted_by_errors() { Err(guar) } else { Ok(()) }
+    }
+
+    fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
+        self.infcx.type_is_copy_modulo_regions(self.param_env, ty)
+    }
+
+    fn body_owner_def_id(&self) -> LocalDefId {
+        self.body_id
+    }
+
+    fn tcx(&self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+}
+
 /// The ExprUseVisitor type
 ///
 /// This is the code that actually walks the tree.
-pub struct ExprUseVisitor<'a, 'tcx, D: Delegate<'tcx>> {
-    typeck_results: &'a ty::TypeckResults<'tcx>,
-    infcx: &'a InferCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-    upvars: Option<&'tcx FxIndexMap<HirId, hir::Upvar>>,
-    body_owner: LocalDefId,
+pub struct ExprUseVisitor<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> {
+    cx: Cx,
     delegate: RefCell<D>,
+    upvars: Option<&'tcx FxIndexMap<HirId, hir::Upvar>>,
 }
 
 /// If the MC results in an error, it's because the type check
@@ -153,30 +200,20 @@
     };
 }
 
-impl<'a, 'tcx, D: Delegate<'tcx>> ExprUseVisitor<'a, 'tcx, D> {
+impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> {
     /// Creates the ExprUseVisitor, configuring it with the various options provided:
     ///
     /// - `delegate` -- who receives the callbacks
     /// - `param_env` --- parameter environment for trait lookups (esp. pertaining to `Copy`)
     /// - `typeck_results` --- typeck results for the code being analyzed
-    pub fn new(
-        delegate: D,
-        infcx: &'a InferCtxt<'tcx>,
-        body_owner: LocalDefId,
-        param_env: ty::ParamEnv<'tcx>,
-        typeck_results: &'a ty::TypeckResults<'tcx>,
-    ) -> Self {
+    pub fn new(cx: Cx, delegate: D) -> Self {
         ExprUseVisitor {
-            infcx,
-            param_env,
-            typeck_results,
-            body_owner,
             delegate: RefCell::new(delegate),
-            upvars: infcx.tcx.upvars_mentioned(body_owner),
+            upvars: cx.tcx().upvars_mentioned(cx.body_owner_def_id()),
+            cx,
         }
     }
 
-    #[instrument(skip(self), level = "debug")]
     pub fn consume_body(&self, body: &hir::Body<'_>) {
         for param in body.params {
             let param_ty = return_if_err!(self.pat_ty_adjusted(param.pat));
@@ -190,14 +227,10 @@
         self.consume_expr(body.value);
     }
 
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.infcx.tcx
-    }
-
     fn consume_or_copy(&self, place_with_id: &PlaceWithHirId<'tcx>, diag_expr_id: HirId) {
         debug!("delegate_consume(place_with_id={:?})", place_with_id);
 
-        if self.type_is_copy_modulo_regions(place_with_id.place.ty()) {
+        if self.cx.type_is_copy_modulo_regions(place_with_id.place.ty()) {
             self.delegate.borrow_mut().copy(place_with_id, diag_expr_id)
         } else {
             self.delegate.borrow_mut().consume(place_with_id, diag_expr_id)
@@ -390,7 +423,7 @@
             }
 
             hir::ExprKind::AssignOp(_, lhs, rhs) => {
-                if self.typeck_results.is_method_call(expr) {
+                if self.cx.typeck_results().is_method_call(expr) {
                     self.consume_expr(lhs);
                 } else {
                     self.mutate_expr(lhs);
@@ -461,7 +494,7 @@
                         // A `Path` pattern is just a name like `Foo`. This is either a
                         // named constant or else it refers to an ADT variant
 
-                        let res = self.typeck_results.qpath_res(qpath, pat.hir_id);
+                        let res = self.cx.typeck_results().qpath_res(qpath, pat.hir_id);
                         match res {
                             Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) => {
                                 // Named constants have to be equated with the value
@@ -587,8 +620,11 @@
             self.consume_expr(field.expr);
 
             // The struct path probably didn't resolve
-            if self.typeck_results.opt_field_index(field.hir_id).is_none() {
-                self.tcx().dcx().span_delayed_bug(field.span, "couldn't resolve index for field");
+            if self.cx.typeck_results().opt_field_index(field.hir_id).is_none() {
+                self.cx
+                    .tcx()
+                    .dcx()
+                    .span_delayed_bug(field.span, "couldn't resolve index for field");
             }
         }
 
@@ -607,14 +643,14 @@
             ty::Adt(adt, args) if adt.is_struct() => {
                 // Consume those fields of the with expression that are needed.
                 for (f_index, with_field) in adt.non_enum_variant().fields.iter_enumerated() {
-                    let is_mentioned = fields
-                        .iter()
-                        .any(|f| self.typeck_results.opt_field_index(f.hir_id) == Some(f_index));
+                    let is_mentioned = fields.iter().any(|f| {
+                        self.cx.typeck_results().opt_field_index(f.hir_id) == Some(f_index)
+                    });
                     if !is_mentioned {
                         let field_place = self.cat_projection(
                             with_expr.hir_id,
                             with_place.clone(),
-                            with_field.ty(self.tcx(), args),
+                            with_field.ty(self.cx.tcx(), args),
                             ProjectionKind::Field(f_index, FIRST_VARIANT),
                         );
                         self.consume_or_copy(&field_place, field_place.hir_id);
@@ -626,7 +662,7 @@
                 // struct; however, when EUV is run during typeck, it
                 // may not. This will generate an error earlier in typeck,
                 // so we can just ignore it.
-                if self.tcx().dcx().has_errors().is_none() {
+                if self.cx.tcx().dcx().has_errors().is_none() {
                     span_bug!(with_expr.span, "with expression doesn't evaluate to a struct");
                 }
             }
@@ -641,7 +677,8 @@
     /// consumed or borrowed as part of the automatic adjustment
     /// process.
     fn walk_adjustment(&self, expr: &hir::Expr<'_>) {
-        let adjustments = self.typeck_results.expr_adjustments(expr);
+        let typeck_results = self.cx.typeck_results();
+        let adjustments = typeck_results.expr_adjustments(expr);
         let mut place_with_id = return_if_err!(self.cat_expr_unadjusted(expr));
         for adjustment in adjustments {
             debug!("walk_adjustment expr={:?} adj={:?}", expr, adjustment);
@@ -749,12 +786,12 @@
     fn walk_pat(&self, discr_place: &PlaceWithHirId<'tcx>, pat: &hir::Pat<'_>, has_guard: bool) {
         debug!("walk_pat(discr_place={:?}, pat={:?}, has_guard={:?})", discr_place, pat, has_guard);
 
-        let tcx = self.tcx();
+        let tcx = self.cx.tcx();
         return_if_err!(self.cat_pattern(discr_place.clone(), pat, |place, pat| {
             if let PatKind::Binding(_, canonical_id, ..) = pat.kind {
                 debug!("walk_pat: binding place={:?} pat={:?}", place, pat);
                 if let Some(bm) =
-                    self.typeck_results.extract_binding_mode(tcx.sess, pat.hir_id, pat.span)
+                    self.cx.typeck_results().extract_binding_mode(tcx.sess, pat.hir_id, pat.span)
                 {
                     debug!("walk_pat: pat.hir_id={:?} bm={:?}", pat.hir_id, bm);
 
@@ -794,7 +831,7 @@
                 // determines whether to borrow *at the level of the deref pattern* rather than
                 // borrowing the bound place (since that inner place is inside the temporary that
                 // stores the result of calling `deref()`/`deref_mut()` so can't be captured).
-                let mutable = self.typeck_results.pat_has_ref_mut_binding(subpattern);
+                let mutable = self.cx.typeck_results().pat_has_ref_mut_binding(subpattern);
                 let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not };
                 let bk = ty::BorrowKind::from_mutbl(mutability);
                 self.delegate.borrow_mut().borrow(place, discr_place.hir_id, bk);
@@ -832,21 +869,21 @@
 
         debug!("walk_captures({:?})", closure_expr);
 
-        let tcx = self.tcx();
+        let tcx = self.cx.tcx();
         let closure_def_id = closure_expr.def_id;
-        let upvars = tcx.upvars_mentioned(self.body_owner);
-
         // For purposes of this function, coroutine and closures are equivalent.
-        let body_owner_is_closure =
-            matches!(tcx.hir().body_owner_kind(self.body_owner), hir::BodyOwnerKind::Closure,);
+        let body_owner_is_closure = matches!(
+            tcx.hir().body_owner_kind(self.cx.body_owner_def_id()),
+            hir::BodyOwnerKind::Closure
+        );
 
         // If we have a nested closure, we want to include the fake reads present in the nested closure.
-        if let Some(fake_reads) = self.typeck_results.closure_fake_reads.get(&closure_def_id) {
+        if let Some(fake_reads) = self.cx.typeck_results().closure_fake_reads.get(&closure_def_id) {
             for (fake_read, cause, hir_id) in fake_reads.iter() {
                 match fake_read.base {
                     PlaceBase::Upvar(upvar_id) => {
                         if upvar_is_local_variable(
-                            upvars,
+                            self.upvars,
                             upvar_id.var_path.hir_id,
                             body_owner_is_closure,
                         ) {
@@ -884,9 +921,14 @@
             }
         }
 
-        if let Some(min_captures) = self.typeck_results.closure_min_captures.get(&closure_def_id) {
+        if let Some(min_captures) =
+            self.cx.typeck_results().closure_min_captures.get(&closure_def_id)
+        {
             for (var_hir_id, min_list) in min_captures.iter() {
-                if upvars.map_or(body_owner_is_closure, |upvars| !upvars.contains_key(var_hir_id)) {
+                if self
+                    .upvars
+                    .map_or(body_owner_is_closure, |upvars| !upvars.contains_key(var_hir_id))
+                {
                     // The nested closure might be capturing the current (enclosing) closure's local variables.
                     // We check if the root variable is ever mentioned within the enclosing closure, if not
                     // then for the current body (if it's a closure) these aren't captures, we will ignore them.
@@ -898,7 +940,7 @@
 
                     let place_base = if body_owner_is_closure {
                         // Mark the place to be captured by the enclosing closure
-                        PlaceBase::Upvar(ty::UpvarId::new(*var_hir_id, self.body_owner))
+                        PlaceBase::Upvar(ty::UpvarId::new(*var_hir_id, self.cx.body_owner_def_id()))
                     } else {
                         // If the body owner isn't a closure then the variable must
                         // be a local variable
@@ -931,46 +973,29 @@
         }
     }
 
-    fn type_is_copy_modulo_regions(&self, ty: Ty<'tcx>) -> bool {
-        self.infcx.type_is_copy_modulo_regions(self.param_env, ty)
-    }
-
-    fn resolve_vars_if_possible<T>(&self, value: T) -> T
-    where
-        T: TypeFoldable<TyCtxt<'tcx>>,
-    {
-        self.infcx.resolve_vars_if_possible(value)
-    }
-
-    fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
-        self.infcx.tainted_by_errors()
-    }
-
     fn resolve_type_vars_or_error(&self, id: HirId, ty: Option<Ty<'tcx>>) -> McResult<Ty<'tcx>> {
         match ty {
             Some(ty) => {
-                let ty = self.resolve_vars_if_possible(ty);
-                if let Err(guar) = ty.error_reported() {
-                    debug!("resolve_type_vars_or_error: error from {:?}", ty);
-                    Err(guar)
-                } else if ty.is_ty_var() {
+                let ty = self.cx.resolve_vars_if_possible(ty);
+                self.cx.error_reported_in_ty(ty)?;
+                if ty.is_ty_var() {
                     debug!("resolve_type_vars_or_error: infer var from {:?}", ty);
-                    Err(self
-                        .tcx()
-                        .dcx()
-                        .span_delayed_bug(self.tcx().hir().span(id), "encountered type variable"))
+                    Err(self.cx.tcx().dcx().span_delayed_bug(
+                        self.cx.tcx().hir().span(id),
+                        "encountered type variable",
+                    ))
                 } else {
                     Ok(ty)
                 }
             }
             None => {
                 // FIXME
-                if let Some(guar) = self.tainted_by_errors() {
+                if let Some(guar) = self.cx.tainted_by_errors() {
                     Err(guar)
                 } else {
                     bug!(
                         "no type for node {} in mem_categorization",
-                        self.tcx().hir().node_to_string(id)
+                        self.cx.tcx().hir().node_to_string(id)
                     );
                 }
             }
@@ -978,15 +1003,18 @@
     }
 
     fn node_ty(&self, hir_id: HirId) -> McResult<Ty<'tcx>> {
-        self.resolve_type_vars_or_error(hir_id, self.typeck_results.node_type_opt(hir_id))
+        self.resolve_type_vars_or_error(hir_id, self.cx.typeck_results().node_type_opt(hir_id))
     }
 
     fn expr_ty(&self, expr: &hir::Expr<'_>) -> McResult<Ty<'tcx>> {
-        self.resolve_type_vars_or_error(expr.hir_id, self.typeck_results.expr_ty_opt(expr))
+        self.resolve_type_vars_or_error(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr))
     }
 
     fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> McResult<Ty<'tcx>> {
-        self.resolve_type_vars_or_error(expr.hir_id, self.typeck_results.expr_ty_adjusted_opt(expr))
+        self.resolve_type_vars_or_error(
+            expr.hir_id,
+            self.cx.typeck_results().expr_ty_adjusted_opt(expr),
+        )
     }
 
     /// Returns the type of value that this pattern matches against.
@@ -1004,7 +1032,7 @@
         // that these are never attached to binding patterns, so
         // actually this is somewhat "disjoint" from the code below
         // that aims to account for `ref x`.
-        if let Some(vec) = self.typeck_results.pat_adjustments().get(pat.hir_id) {
+        if let Some(vec) = self.cx.typeck_results().pat_adjustments().get(pat.hir_id) {
             if let Some(first_ty) = vec.first() {
                 debug!("pat_ty(pat={:?}) found adjusted ty `{:?}`", pat, first_ty);
                 return Ok(*first_ty);
@@ -1015,7 +1043,6 @@
     }
 
     /// Like `pat_ty`, but ignores implicit `&` patterns.
-    #[instrument(level = "debug", skip(self), ret)]
     fn pat_ty_unadjusted(&self, pat: &hir::Pat<'_>) -> McResult<Ty<'tcx>> {
         let base_ty = self.node_ty(pat.hir_id)?;
         trace!(?base_ty);
@@ -1025,7 +1052,8 @@
         match pat.kind {
             PatKind::Binding(..) => {
                 let bm = *self
-                    .typeck_results
+                    .cx
+                    .typeck_results()
                     .pat_binding_modes()
                     .get(pat.hir_id)
                     .expect("missing binding mode");
@@ -1039,6 +1067,7 @@
                         None => {
                             debug!("By-ref binding of non-derefable type");
                             Err(self
+                                .cx
                                 .tcx()
                                 .dcx()
                                 .span_delayed_bug(pat.span, "by-ref binding of non-derefable type"))
@@ -1053,22 +1082,22 @@
     }
 
     fn cat_expr(&self, expr: &hir::Expr<'_>) -> McResult<PlaceWithHirId<'tcx>> {
-        // This recursion helper avoids going through *too many*
-        // adjustments, since *only* non-overloaded deref recurses.
-        fn helper<'a, 'tcx, D: Delegate<'tcx>>(
-            this: &ExprUseVisitor<'a, 'tcx, D>,
-            expr: &hir::Expr<'_>,
-            adjustments: &[adjustment::Adjustment<'tcx>],
-        ) -> McResult<PlaceWithHirId<'tcx>> {
-            match adjustments.split_last() {
-                None => this.cat_expr_unadjusted(expr),
-                Some((adjustment, previous)) => {
-                    this.cat_expr_adjusted_with(expr, || helper(this, expr, previous), adjustment)
-                }
+        self.cat_expr_(expr, self.cx.typeck_results().expr_adjustments(expr))
+    }
+
+    /// This recursion helper avoids going through *too many*
+    /// adjustments, since *only* non-overloaded deref recurses.
+    fn cat_expr_(
+        &self,
+        expr: &hir::Expr<'_>,
+        adjustments: &[adjustment::Adjustment<'tcx>],
+    ) -> McResult<PlaceWithHirId<'tcx>> {
+        match adjustments.split_last() {
+            None => self.cat_expr_unadjusted(expr),
+            Some((adjustment, previous)) => {
+                self.cat_expr_adjusted_with(expr, || self.cat_expr_(expr, previous), adjustment)
             }
         }
-
-        helper(self, expr, self.typeck_results.expr_adjustments(expr))
     }
 
     fn cat_expr_adjusted(
@@ -1080,7 +1109,6 @@
         self.cat_expr_adjusted_with(expr, || Ok(previous), adjustment)
     }
 
-    #[instrument(level = "debug", skip(self, previous))]
     fn cat_expr_adjusted_with<F>(
         &self,
         expr: &hir::Expr<'_>,
@@ -1090,12 +1118,12 @@
     where
         F: FnOnce() -> McResult<PlaceWithHirId<'tcx>>,
     {
-        let target = self.resolve_vars_if_possible(adjustment.target);
+        let target = self.cx.resolve_vars_if_possible(adjustment.target);
         match adjustment.kind {
             adjustment::Adjust::Deref(overloaded) => {
                 // Equivalent to *expr or something similar.
                 let base = if let Some(deref) = overloaded {
-                    let ref_ty = Ty::new_ref(self.tcx(), deref.region, target, deref.mutbl);
+                    let ref_ty = Ty::new_ref(self.cx.tcx(), deref.region, target, deref.mutbl);
                     self.cat_rvalue(expr.hir_id, ref_ty)
                 } else {
                     previous()?
@@ -1113,12 +1141,11 @@
         }
     }
 
-    #[instrument(level = "debug", skip(self), ret)]
     fn cat_expr_unadjusted(&self, expr: &hir::Expr<'_>) -> McResult<PlaceWithHirId<'tcx>> {
         let expr_ty = self.expr_ty(expr)?;
         match expr.kind {
             hir::ExprKind::Unary(hir::UnOp::Deref, e_base) => {
-                if self.typeck_results.is_method_call(expr) {
+                if self.cx.typeck_results().is_method_call(expr) {
                     self.cat_overloaded_place(expr, e_base)
                 } else {
                     let base = self.cat_expr(e_base)?;
@@ -1131,7 +1158,8 @@
                 debug!(?base);
 
                 let field_idx = self
-                    .typeck_results
+                    .cx
+                    .typeck_results()
                     .field_indices()
                     .get(expr.hir_id)
                     .cloned()
@@ -1146,7 +1174,7 @@
             }
 
             hir::ExprKind::Index(base, _, _) => {
-                if self.typeck_results.is_method_call(expr) {
+                if self.cx.typeck_results().is_method_call(expr) {
                     // If this is an index implemented by a method call, then it
                     // will include an implicit deref of the result.
                     // The call to index() returns a `&T` value, which
@@ -1160,7 +1188,7 @@
             }
 
             hir::ExprKind::Path(ref qpath) => {
-                let res = self.typeck_results.qpath_res(qpath, expr.hir_id);
+                let res = self.cx.typeck_results().qpath_res(qpath, expr.hir_id);
                 self.cat_res(expr.hir_id, expr.span, expr_ty, res)
             }
 
@@ -1198,7 +1226,6 @@
         }
     }
 
-    #[instrument(level = "debug", skip(self, span), ret)]
     fn cat_res(
         &self,
         hir_id: HirId,
@@ -1239,9 +1266,8 @@
     /// Note: the actual upvar access contains invisible derefs of closure
     /// environment and upvar reference as appropriate. Only regionck cares
     /// about these dereferences, so we let it compute them as needed.
-    #[instrument(level = "debug", skip(self), ret)]
     fn cat_upvar(&self, hir_id: HirId, var_id: HirId) -> McResult<PlaceWithHirId<'tcx>> {
-        let closure_expr_def_id = self.body_owner;
+        let closure_expr_def_id = self.cx.body_owner_def_id();
 
         let upvar_id = ty::UpvarId {
             var_path: ty::UpvarPath { hir_id: var_id },
@@ -1252,12 +1278,10 @@
         Ok(PlaceWithHirId::new(hir_id, var_ty, PlaceBase::Upvar(upvar_id), Vec::new()))
     }
 
-    #[instrument(level = "debug", skip(self), ret)]
     fn cat_rvalue(&self, hir_id: HirId, expr_ty: Ty<'tcx>) -> PlaceWithHirId<'tcx> {
         PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Rvalue, Vec::new())
     }
 
-    #[instrument(level = "debug", skip(self, node), ret)]
     fn cat_projection(
         &self,
         node: HirId,
@@ -1268,7 +1292,7 @@
         let place_ty = base_place.place.ty();
         let mut projections = base_place.place.projections;
 
-        let node_ty = self.typeck_results.node_type(node);
+        let node_ty = self.cx.typeck_results().node_type(node);
         // Opaque types can't have field projections, but we can instead convert
         // the current place in-place (heh) to the hidden type, and then apply all
         // follow up projections on that.
@@ -1279,7 +1303,6 @@
         PlaceWithHirId::new(node, base_place.place.base_ty, base_place.place.base, projections)
     }
 
-    #[instrument(level = "debug", skip(self))]
     fn cat_overloaded_place(
         &self,
         expr: &hir::Expr<'_>,
@@ -1294,13 +1317,12 @@
         let ty::Ref(region, _, mutbl) = *base_ty.kind() else {
             span_bug!(expr.span, "cat_overloaded_place: base is not a reference");
         };
-        let ref_ty = Ty::new_ref(self.tcx(), region, place_ty, mutbl);
+        let ref_ty = Ty::new_ref(self.cx.tcx(), region, place_ty, mutbl);
 
         let base = self.cat_rvalue(expr.hir_id, ref_ty);
         self.cat_deref(expr.hir_id, base)
     }
 
-    #[instrument(level = "debug", skip(self, node), ret)]
     fn cat_deref(
         &self,
         node: HirId,
@@ -1311,8 +1333,8 @@
             Some(mt) => mt.ty,
             None => {
                 debug!("explicit deref of non-derefable type: {:?}", base_curr_ty);
-                return Err(self.tcx().dcx().span_delayed_bug(
-                    self.tcx().hir().span(node),
+                return Err(self.cx.tcx().dcx().span_delayed_bug(
+                    self.cx.tcx().hir().span(node),
                     "explicit deref of non-derefable type",
                 ));
             }
@@ -1343,10 +1365,11 @@
         pat_hir_id: HirId,
         span: Span,
     ) -> McResult<VariantIdx> {
-        let res = self.typeck_results.qpath_res(qpath, pat_hir_id);
-        let ty = self.typeck_results.node_type(pat_hir_id);
+        let res = self.cx.typeck_results().qpath_res(qpath, pat_hir_id);
+        let ty = self.cx.typeck_results().node_type(pat_hir_id);
         let ty::Adt(adt_def, _) = ty.kind() else {
             return Err(self
+                .cx
                 .tcx()
                 .dcx()
                 .span_delayed_bug(span, "struct or tuple struct pattern not applied to an ADT"));
@@ -1377,11 +1400,12 @@
         variant_index: VariantIdx,
         span: Span,
     ) -> McResult<usize> {
-        let ty = self.typeck_results.node_type(pat_hir_id);
+        let ty = self.cx.typeck_results().node_type(pat_hir_id);
         match ty.kind() {
             ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()),
             _ => {
-                self.tcx()
+                self.cx
+                    .tcx()
                     .dcx()
                     .span_bug(span, "struct or tuple struct pattern not applied to an ADT");
             }
@@ -1391,12 +1415,14 @@
     /// Returns the total number of fields in a tuple used within a Tuple pattern.
     /// Here `pat_hir_id` is the HirId of the pattern itself.
     fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> McResult<usize> {
-        let ty = self.typeck_results.node_type(pat_hir_id);
+        let ty = self.cx.typeck_results().node_type(pat_hir_id);
         match ty.kind() {
             ty::Tuple(args) => Ok(args.len()),
-            _ => {
-                Err(self.tcx().dcx().span_delayed_bug(span, "tuple pattern not applied to a tuple"))
-            }
+            _ => Err(self
+                .cx
+                .tcx()
+                .dcx()
+                .span_delayed_bug(span, "tuple pattern not applied to a tuple")),
         }
     }
 
@@ -1406,7 +1432,6 @@
     /// In general, the way that this works is that we walk down the pattern,
     /// constructing a `PlaceWithHirId` that represents the path that will be taken
     /// to reach the value being matched.
-    #[instrument(skip(self, op), ret, level = "debug")]
     fn cat_pattern_<F>(
         &self,
         mut place_with_id: PlaceWithHirId<'tcx>,
@@ -1448,7 +1473,9 @@
         // Then we see that to get the same result, we must start with
         // `deref { deref { place_foo }}` instead of `place_foo` since the pattern is now `Some(x,)`
         // and not `&&Some(x,)`, even though its assigned type is that of `&&Some(x,)`.
-        for _ in 0..self.typeck_results.pat_adjustments().get(pat.hir_id).map_or(0, |v| v.len()) {
+        for _ in
+            0..self.cx.typeck_results().pat_adjustments().get(pat.hir_id).map_or(0, |v| v.len())
+        {
             debug!("applying adjustment to place_with_id={:?}", place_with_id);
             place_with_id = self.cat_deref(pat.hir_id, place_with_id)?;
         }
@@ -1513,7 +1540,8 @@
                 for fp in field_pats {
                     let field_ty = self.pat_ty_adjusted(fp.pat)?;
                     let field_index = self
-                        .typeck_results
+                        .cx
+                        .typeck_results()
                         .field_indices()
                         .get(fp.hir_id)
                         .cloned()
@@ -1547,11 +1575,11 @@
                 self.cat_pattern_(subplace, subpat, op)?;
             }
             PatKind::Deref(subpat) => {
-                let mutable = self.typeck_results.pat_has_ref_mut_binding(subpat);
+                let mutable = self.cx.typeck_results().pat_has_ref_mut_binding(subpat);
                 let mutability = if mutable { hir::Mutability::Mut } else { hir::Mutability::Not };
-                let re_erased = self.tcx().lifetimes.re_erased;
+                let re_erased = self.cx.tcx().lifetimes.re_erased;
                 let ty = self.pat_ty_adjusted(subpat)?;
-                let ty = Ty::new_ref(self.tcx(), re_erased, ty, mutability);
+                let ty = Ty::new_ref(self.cx.tcx(), re_erased, ty, mutability);
                 // A deref pattern generates a temporary.
                 let place = self.cat_rvalue(pat.hir_id, ty);
                 self.cat_pattern_(place, subpat, op)?;
@@ -1561,6 +1589,7 @@
                 let Some(element_ty) = place_with_id.place.ty().builtin_index() else {
                     debug!("explicit index of non-indexable type {:?}", place_with_id);
                     return Err(self
+                        .cx
                         .tcx()
                         .dcx()
                         .span_delayed_bug(pat.span, "explicit index of non-indexable type"));
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index 2bf4f51..9f71073 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -253,11 +253,8 @@
         }
 
         euv::ExprUseVisitor::new(
+            &FnCtxt::new(self, self.tcx.param_env(closure_def_id), closure_def_id),
             &mut delegate,
-            &self.infcx,
-            closure_def_id,
-            self.param_env,
-            &self.typeck_results.borrow(),
         )
         .consume_body(body);