about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs58
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs11
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_temp.rs5
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs5
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs73
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs15
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs21
-rw-r--r--compiler/rustc_mir_build/src/build/matches/util.rs22
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs1
11 files changed, 92 insertions, 127 deletions
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index ebb56e5a233..3550c7470cd 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -69,7 +69,7 @@ pub(crate) enum PlaceBase {
 /// This is used internally when building a place for an expression like `a.b.c`. The fields `b`
 /// and `c` can be progressively pushed onto the place builder that is created when converting `a`.
 #[derive(Clone, Debug, PartialEq)]
-pub(crate) struct PlaceBuilder<'tcx> {
+pub(in crate::build) struct PlaceBuilder<'tcx> {
     base: PlaceBase,
     projection: Vec<PlaceElem<'tcx>>,
 }
@@ -168,22 +168,22 @@ fn find_capture_matching_projections<'a, 'tcx>(
 /// `PlaceBuilder` now starts from `PlaceBase::Local`.
 ///
 /// Returns a Result with the error being the PlaceBuilder (`from_builder`) that was not found.
-fn to_upvars_resolved_place_builder<'a, 'tcx>(
+#[instrument(level = "trace", skip(cx))]
+fn to_upvars_resolved_place_builder<'tcx>(
     from_builder: PlaceBuilder<'tcx>,
-    tcx: TyCtxt<'tcx>,
-    upvars: &'a CaptureMap<'tcx>,
+    cx: &Builder<'_, 'tcx>,
 ) -> Result<PlaceBuilder<'tcx>, PlaceBuilder<'tcx>> {
     match from_builder.base {
         PlaceBase::Local(_) => Ok(from_builder),
         PlaceBase::Upvar { var_hir_id, closure_def_id } => {
             let Some((capture_index, capture)) =
                 find_capture_matching_projections(
-                    upvars,
+                    &cx.upvars,
                     var_hir_id,
                     &from_builder.projection,
                 ) else {
-                let closure_span = tcx.def_span(closure_def_id);
-                if !enable_precise_capture(tcx, closure_span) {
+                let closure_span = cx.tcx.def_span(closure_def_id);
+                if !enable_precise_capture(cx.tcx, closure_span) {
                     bug!(
                         "No associated capture found for {:?}[{:#?}] even though \
                             capture_disjoint_fields isn't enabled",
@@ -200,18 +200,20 @@ fn to_upvars_resolved_place_builder<'a, 'tcx>(
             };
 
             // Access the capture by accessing the field within the Closure struct.
-            let capture_info = &upvars[capture_index];
+            let capture_info = &cx.upvars[capture_index];
 
             let mut upvar_resolved_place_builder = PlaceBuilder::from(capture_info.use_place);
 
             // We used some of the projections to build the capture itself,
             // now we apply the remaining to the upvar resolved place.
+            trace!(?capture.captured_place, ?from_builder.projection);
             let remaining_projections = strip_prefix(
                 capture.captured_place.place.base_ty,
                 from_builder.projection,
                 &capture.captured_place.place.projections,
             );
             upvar_resolved_place_builder.projection.extend(remaining_projections);
+            trace!(?upvar_resolved_place_builder);
 
             Ok(upvar_resolved_place_builder)
         }
@@ -251,24 +253,16 @@ fn strip_prefix<'tcx>(
 }
 
 impl<'tcx> PlaceBuilder<'tcx> {
-    pub(in crate::build) fn into_place<'a>(
-        self,
-        tcx: TyCtxt<'tcx>,
-        upvars: &'a CaptureMap<'tcx>,
-    ) -> Place<'tcx> {
+    pub(in crate::build) fn into_place(self, cx: &Builder<'_, 'tcx>) -> Place<'tcx> {
         if let PlaceBase::Local(local) = self.base {
-            Place { local, projection: tcx.intern_place_elems(&self.projection) }
+            Place { local, projection: cx.tcx.intern_place_elems(&self.projection) }
         } else {
-            self.expect_upvars_resolved(tcx, upvars).into_place(tcx, upvars)
+            self.expect_upvars_resolved(cx).into_place(cx)
         }
     }
 
-    fn expect_upvars_resolved<'a>(
-        self,
-        tcx: TyCtxt<'tcx>,
-        upvars: &'a CaptureMap<'tcx>,
-    ) -> PlaceBuilder<'tcx> {
-        to_upvars_resolved_place_builder(self, tcx, upvars).unwrap()
+    fn expect_upvars_resolved(self, cx: &Builder<'_, 'tcx>) -> PlaceBuilder<'tcx> {
+        to_upvars_resolved_place_builder(self, cx).unwrap()
     }
 
     /// Attempts to resolve the `PlaceBuilder`.
@@ -282,12 +276,11 @@ impl<'tcx> PlaceBuilder<'tcx> {
     /// not captured. This can happen because the final mir that will be
     /// generated doesn't require a read for this place. Failures will only
     /// happen inside closures.
-    pub(in crate::build) fn try_upvars_resolved<'a>(
+    pub(in crate::build) fn try_upvars_resolved(
         self,
-        tcx: TyCtxt<'tcx>,
-        upvars: &'a CaptureMap<'tcx>,
+        cx: &Builder<'_, 'tcx>,
     ) -> Result<PlaceBuilder<'tcx>, PlaceBuilder<'tcx>> {
-        to_upvars_resolved_place_builder(self, tcx, upvars)
+        to_upvars_resolved_place_builder(self, cx)
     }
 
     pub(crate) fn base(&self) -> PlaceBase {
@@ -353,7 +346,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         expr: &Expr<'tcx>,
     ) -> BlockAnd<Place<'tcx>> {
         let place_builder = unpack!(block = self.as_place_builder(block, expr));
-        block.and(place_builder.into_place(self.tcx, &self.upvars))
+        block.and(place_builder.into_place(self))
     }
 
     /// This is used when constructing a compound `Place`, so that we can avoid creating
@@ -377,7 +370,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         expr: &Expr<'tcx>,
     ) -> BlockAnd<Place<'tcx>> {
         let place_builder = unpack!(block = self.as_read_only_place_builder(block, expr));
-        block.and(place_builder.into_place(self.tcx, &self.upvars))
+        block.and(place_builder.into_place(self))
     }
 
     /// This is used when constructing a compound `Place`, so that we can avoid creating
@@ -472,7 +465,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             inferred_ty: expr.ty,
                         });
 
-                    let place = place_builder.clone().into_place(this.tcx, &this.upvars);
+                    let place = place_builder.clone().into_place(this);
                     this.cfg.push(
                         block,
                         Statement {
@@ -610,7 +603,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         if is_outermost_index {
             self.read_fake_borrows(block, fake_borrow_temps, source_info)
         } else {
-            base_place = base_place.expect_upvars_resolved(self.tcx, &self.upvars);
+            base_place = base_place.expect_upvars_resolved(self);
             self.add_fake_borrows_of_base(
                 &base_place,
                 block,
@@ -638,12 +631,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let lt = self.temp(bool_ty, expr_span);
 
         // len = len(slice)
-        self.cfg.push_assign(
-            block,
-            source_info,
-            len,
-            Rvalue::Len(slice.into_place(self.tcx, &self.upvars)),
-        );
+        self.cfg.push_assign(block, source_info, len, Rvalue::Len(slice.into_place(self)));
         // lt = idx < len
         self.cfg.push_assign(
             block,
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 98bdaf0bc62..16295b1b19a 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -329,10 +329,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     let place_builder =
                         unpack!(block = this.as_place_builder(block, &this.thir[*thir_place]));
 
-                    if let Ok(place_builder_resolved) =
-                        place_builder.try_upvars_resolved(this.tcx, &this.upvars)
-                    {
-                        let mir_place = place_builder_resolved.into_place(this.tcx, &this.upvars);
+                    if let Ok(place_builder_resolved) = place_builder.try_upvars_resolved(this) {
+                        let mir_place = place_builder_resolved.into_place(this);
                         this.cfg.push_fake_read(
                             block,
                             this.source_info(this.tcx.hir().span(*hir_id)),
@@ -623,8 +621,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             // by the parent itself. The mutability of the current capture
             // is same as that of the capture in the parent closure.
             PlaceBase::Upvar { .. } => {
-                let enclosing_upvars_resolved =
-                    arg_place_builder.clone().into_place(this.tcx, &this.upvars);
+                let enclosing_upvars_resolved = arg_place_builder.clone().into_place(this);
 
                 match enclosing_upvars_resolved.as_ref() {
                     PlaceRef {
@@ -661,7 +658,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             Mutability::Mut => BorrowKind::Mut { allow_two_phase_borrow: false },
         };
 
-        let arg_place = arg_place_builder.into_place(this.tcx, &this.upvars);
+        let arg_place = arg_place_builder.into_place(this);
 
         this.cfg.push_assign(
             block,
diff --git a/compiler/rustc_mir_build/src/build/expr/as_temp.rs b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
index e5dafb820bf..0ca4e374519 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_temp.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_temp.rs
@@ -23,6 +23,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         ensure_sufficient_stack(|| self.as_temp_inner(block, temp_lifetime, expr, mutability))
     }
 
+    #[instrument(skip(self), level = "debug")]
     fn as_temp_inner(
         &mut self,
         mut block: BasicBlock,
@@ -30,10 +31,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         expr: &Expr<'tcx>,
         mutability: Mutability,
     ) -> BlockAnd<Local> {
-        debug!(
-            "as_temp(block={:?}, temp_lifetime={:?}, expr={:?}, mutability={:?})",
-            block, temp_lifetime, expr, mutability
-        );
         let this = self;
 
         let expr_span = expr.span;
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index 6ed5f1fc0d3..4b8c134b9d0 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -15,14 +15,13 @@ use std::iter;
 impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// Compile `expr`, storing the result into `destination`, which
     /// is assumed to be uninitialized.
+    #[instrument(level = "debug", skip(self))]
     pub(crate) fn expr_into_dest(
         &mut self,
         destination: Place<'tcx>,
         mut block: BasicBlock,
         expr: &Expr<'tcx>,
     ) -> BlockAnd<()> {
-        debug!("expr_into_dest(destination={:?}, block={:?}, expr={:?})", destination, block, expr);
-
         // since we frequently have to reference `self` from within a
         // closure, where `self` would be shadowed, it's easier to
         // just use the name `this` uniformly
@@ -366,7 +365,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                             None => {
                                 let place_builder = place_builder.clone();
                                 this.consume_by_copy_or_move(
-                                    place_builder.field(n, *ty).into_place(this.tcx, &this.upvars),
+                                    place_builder.field(n, *ty).into_place(this),
                                 )
                             }
                         })
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index e0727725f68..d283c33a005 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -220,10 +220,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let cause_matched_place = FakeReadCause::ForMatchedPlace(None);
         let source_info = self.source_info(scrutinee_span);
 
-        if let Ok(scrutinee_builder) =
-            scrutinee_place_builder.clone().try_upvars_resolved(self.tcx, &self.upvars)
-        {
-            let scrutinee_place = scrutinee_builder.into_place(self.tcx, &self.upvars);
+        if let Ok(scrutinee_builder) = scrutinee_place_builder.clone().try_upvars_resolved(self) {
+            let scrutinee_place = scrutinee_builder.into_place(self);
             self.cfg.push_fake_read(block, source_info, cause_matched_place, scrutinee_place);
         }
 
@@ -349,9 +347,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     let mut opt_scrutinee_place: Option<(Option<&Place<'tcx>>, Span)> = None;
                     let scrutinee_place: Place<'tcx>;
                     if let Ok(scrutinee_builder) =
-                        scrutinee_place_builder.clone().try_upvars_resolved(this.tcx, &this.upvars)
+                        scrutinee_place_builder.clone().try_upvars_resolved(this)
                     {
-                        scrutinee_place = scrutinee_builder.into_place(this.tcx, &this.upvars);
+                        scrutinee_place = scrutinee_builder.into_place(this);
                         opt_scrutinee_place = Some((Some(&scrutinee_place), scrutinee_span));
                     }
                     let scope = this.declare_bindings(
@@ -597,12 +595,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             while let Some(next) = {
                 for binding in &candidate_ref.bindings {
                     let local = self.var_local_id(binding.var_id, OutsideGuard);
-
-                    let Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
-                        VarBindingForm { opt_match_place: Some((ref mut match_place, _)), .. },
-                    )))) = self.local_decls[local].local_info else {
-                        bug!("Let binding to non-user variable.")
-                    };
                     // `try_upvars_resolved` may fail if it is unable to resolve the given
                     // `PlaceBuilder` inside a closure. In this case, we don't want to include
                     // a scrutinee place. `scrutinee_place_builder` will fail for destructured
@@ -617,10 +609,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     //    let (v1, v2) = foo;
                     // };
                     // ```
-                    if let Ok(match_pair_resolved) =
-                        initializer.clone().try_upvars_resolved(self.tcx, &self.upvars)
-                    {
-                        let place = match_pair_resolved.into_place(self.tcx, &self.upvars);
+                    if let Ok(match_pair_resolved) = initializer.clone().try_upvars_resolved(self) {
+                        let place = match_pair_resolved.into_place(self);
+
+                        let Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
+                            VarBindingForm { opt_match_place: Some((ref mut match_place, _)), .. },
+                        )))) = self.local_decls[local].local_info else {
+                            bug!("Let binding to non-user variable.")
+                        };
                         *match_place = Some(place);
                     }
                 }
@@ -649,6 +645,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// scope for the bindings in these patterns, if such a scope had to be
     /// created. NOTE: Declaring the bindings should always be done in their
     /// drop scope.
+    #[instrument(skip(self), level = "debug")]
     pub(crate) fn declare_bindings(
         &mut self,
         mut visibility_scope: Option<SourceScope>,
@@ -657,7 +654,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         has_guard: ArmHasGuard,
         opt_match_place: Option<(Option<&Place<'tcx>>, Span)>,
     ) -> Option<SourceScope> {
-        debug!("declare_bindings: pattern={:?}", pattern);
         self.visit_primary_bindings(
             &pattern,
             UserTypeProjections::none(),
@@ -867,7 +863,7 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
         Candidate {
             span: pattern.span,
             has_guard,
-            match_pairs: smallvec![MatchPair { place, pattern }],
+            match_pairs: smallvec![MatchPair::new(place, pattern)],
             bindings: Vec::new(),
             ascriptions: Vec::new(),
             subcandidates: Vec::new(),
@@ -1043,6 +1039,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// if `x.0` matches `false` (for the third arm). In the (impossible at
     /// runtime) case when `x.0` is now `true`, we branch to
     /// `otherwise_block`.
+    #[instrument(skip(self, fake_borrows), level = "debug")]
     fn match_candidates<'pat>(
         &mut self,
         span: Span,
@@ -1052,11 +1049,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         candidates: &mut [&mut Candidate<'pat, 'tcx>],
         fake_borrows: &mut Option<FxIndexSet<Place<'tcx>>>,
     ) {
-        debug!(
-            "matched_candidate(span={:?}, candidates={:?}, start_block={:?}, otherwise_block={:?})",
-            span, candidates, start_block, otherwise_block,
-        );
-
         // Start by simplifying candidates. Once this process is complete, all
         // the match pairs which remain require some form of test, whether it
         // be a switch or pattern comparison.
@@ -1375,6 +1367,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         )
     }
 
+    #[instrument(
+        skip(self, otherwise, or_span, place, fake_borrows, candidate, pats),
+        level = "debug"
+    )]
     fn test_or_pattern<'pat>(
         &mut self,
         candidate: &mut Candidate<'pat, 'tcx>,
@@ -1384,7 +1380,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         place: PlaceBuilder<'tcx>,
         fake_borrows: &mut Option<FxIndexSet<Place<'tcx>>>,
     ) {
-        debug!("test_or_pattern:\ncandidate={:#?}\npats={:#?}", candidate, pats);
+        debug!("candidate={:#?}\npats={:#?}", candidate, pats);
         let mut or_candidates: Vec<_> = pats
             .iter()
             .map(|pat| Candidate::new(place.clone(), pat, candidate.has_guard))
@@ -1600,9 +1596,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
         // Insert a Shallow borrow of any places that is switched on.
         if let Some(fb) = fake_borrows && let Ok(match_place_resolved) =
-            match_place.clone().try_upvars_resolved(self.tcx, &self.upvars)
+            match_place.clone().try_upvars_resolved(self)
         {
-            let resolved_place = match_place_resolved.into_place(self.tcx, &self.upvars);
+            let resolved_place = match_place_resolved.into_place(self);
             fb.insert(resolved_place);
         }
 
@@ -1629,9 +1625,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             candidates = rest;
         }
         // at least the first candidate ought to be tested
-        assert!(total_candidate_count > candidates.len());
-        debug!("test_candidates: tested_candidates: {}", total_candidate_count - candidates.len());
-        debug!("test_candidates: untested_candidates: {}", candidates.len());
+        assert!(
+            total_candidate_count > candidates.len(),
+            "{}, {:#?}",
+            total_candidate_count,
+            candidates
+        );
+        debug!("tested_candidates: {}", total_candidate_count - candidates.len());
+        debug!("untested_candidates: {}", candidates.len());
 
         // HACK(matthewjasper) This is a closure so that we can let the test
         // create its blocks before the rest of the match. This currently
@@ -1789,8 +1790,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         );
         let mut opt_expr_place: Option<(Option<&Place<'tcx>>, Span)> = None;
         let expr_place: Place<'tcx>;
-        if let Ok(expr_builder) = expr_place_builder.try_upvars_resolved(self.tcx, &self.upvars) {
-            expr_place = expr_builder.into_place(self.tcx, &self.upvars);
+        if let Ok(expr_builder) = expr_place_builder.try_upvars_resolved(self) {
+            expr_place = expr_builder.into_place(self);
             opt_expr_place = Some((Some(&expr_place), expr_span));
         }
         let otherwise_post_guard_block = otherwise_candidate.pre_binding_block.unwrap();
@@ -2188,6 +2189,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// first local is a binding for occurrences of `var` in the guard, which
     /// will have type `&T`. The second local is a binding for occurrences of
     /// `var` in the arm body, which will have type `T`.
+    #[instrument(skip(self), level = "debug")]
     fn declare_binding(
         &mut self,
         source_info: SourceInfo,
@@ -2202,19 +2204,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         opt_match_place: Option<(Option<Place<'tcx>>, Span)>,
         pat_span: Span,
     ) {
-        debug!(
-            "declare_binding(var_id={:?}, name={:?}, mode={:?}, var_ty={:?}, \
-             visibility_scope={:?}, source_info={:?})",
-            var_id, name, mode, var_ty, visibility_scope, source_info
-        );
-
         let tcx = self.tcx;
         let debug_source_info = SourceInfo { span: source_info.span, scope: visibility_scope };
         let binding_mode = match mode {
             BindingMode::ByValue => ty::BindingMode::BindByValue(mutability),
             BindingMode::ByRef(_) => ty::BindingMode::BindByReference(mutability),
         };
-        debug!("declare_binding: user_ty={:?}", user_ty);
         let local = LocalDecl::<'tcx> {
             mutability,
             ty: var_ty,
@@ -2264,7 +2259,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         } else {
             LocalsForNode::One(for_arm_body)
         };
-        debug!("declare_binding: vars={:?}", locals);
+        debug!(?locals);
         self.var_indices.insert(var_id, locals);
     }
 
diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index df221d35603..7117554933d 100644
--- a/compiler/rustc_mir_build/src/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
@@ -37,12 +37,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     ///
     /// only generates a single switch. If this happens this method returns
     /// `true`.
+    #[instrument(skip(self, candidate), level = "debug")]
     pub(super) fn simplify_candidate<'pat>(
         &mut self,
         candidate: &mut Candidate<'pat, 'tcx>,
     ) -> bool {
         // repeatedly simplify match pairs until fixed point is reached
-        debug!(?candidate, "simplify_candidate");
+        debug!("{candidate:#?}");
 
         // existing_bindings and new_bindings exists to keep the semantics in order.
         // Reversing the binding order for bindings after `@` changes the binding order in places
@@ -155,12 +156,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 ascription: thir::Ascription { ref annotation, variance },
             } => {
                 // Apply the type ascription to the value at `match_pair.place`, which is the
-                if let Ok(place_resolved) =
-                    match_pair.place.clone().try_upvars_resolved(self.tcx, &self.upvars)
-                {
+                if let Ok(place_resolved) = match_pair.place.clone().try_upvars_resolved(self) {
                     candidate.ascriptions.push(Ascription {
                         annotation: annotation.clone(),
-                        source: place_resolved.into_place(self.tcx, &self.upvars),
+                        source: place_resolved.into_place(self),
                         variance,
                     });
                 }
@@ -184,12 +183,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 ref subpattern,
                 is_primary: _,
             } => {
-                if let Ok(place_resolved) =
-                    match_pair.place.clone().try_upvars_resolved(self.tcx, &self.upvars)
-                {
+                if let Ok(place_resolved) = match_pair.place.clone().try_upvars_resolved(self) {
                     candidate.bindings.push(Binding {
                         span: match_pair.pattern.span,
-                        source: place_resolved.into_place(self.tcx, &self.upvars),
+                        source: place_resolved.into_place(self),
                         var_id: var,
                         binding_mode: mode,
                     });
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index 47d05a6e32c..a8adf490db8 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -144,6 +144,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
     }
 
+    #[instrument(skip(self, make_target_blocks, place_builder), level = "debug")]
     pub(super) fn perform_test(
         &mut self,
         match_start_span: Span,
@@ -153,19 +154,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         test: &Test<'tcx>,
         make_target_blocks: impl FnOnce(&mut Self) -> Vec<BasicBlock>,
     ) {
-        let place: Place<'tcx>;
-        if let Ok(test_place_builder) = place_builder.try_upvars_resolved(self.tcx, &self.upvars) {
-            place = test_place_builder.into_place(self.tcx, &self.upvars);
-        } else {
-            return;
-        }
-        debug!(
-            "perform_test({:?}, {:?}: {:?}, {:?})",
-            block,
-            place,
-            place.ty(&self.local_decls, self.tcx),
-            test
-        );
+        let place = place_builder.into_place(self);
+        let place_ty = place.ty(&self.local_decls, self.tcx);
+        debug!(?place, ?place_ty,);
 
         let source_info = self.source_info(test.span);
         match test.kind {
@@ -733,9 +724,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         // So, if we have a match-pattern like `x @ Enum::Variant(P1, P2)`,
         // we want to create a set of derived match-patterns like
         // `(x as Variant).0 @ P1` and `(x as Variant).1 @ P1`.
-        let elem =
-            ProjectionElem::Downcast(Some(adt_def.variant(variant_index).name), variant_index);
-        let downcast_place = match_pair.place.project(elem); // `(x as Variant)`
+        let downcast_place = match_pair.place.downcast(adt_def, variant_index); // `(x as Variant)`
         let consequent_match_pairs = subpatterns.iter().map(|subpattern| {
             // e.g., `(x as Variant).0`
             let place = downcast_place.clone().field(subpattern.field, subpattern.pattern.ty);
diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs
index b61c4fe50dd..f47626731eb 100644
--- a/compiler/rustc_mir_build/src/build/matches/util.rs
+++ b/compiler/rustc_mir_build/src/build/matches/util.rs
@@ -31,17 +31,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         suffix: &'pat [Box<Pat<'tcx>>],
     ) {
         let tcx = self.tcx;
-        let (min_length, exact_size) = if let Ok(place_resolved) =
-            place.clone().try_upvars_resolved(tcx, &self.upvars)
-        {
-            match place_resolved.into_place(tcx, &self.upvars).ty(&self.local_decls, tcx).ty.kind()
-            {
-                ty::Array(_, length) => (length.eval_usize(tcx, self.param_env), true),
-                _ => ((prefix.len() + suffix.len()).try_into().unwrap(), false),
-            }
-        } else {
-            ((prefix.len() + suffix.len()).try_into().unwrap(), false)
-        };
+        let (min_length, exact_size) =
+            if let Ok(place_resolved) = place.clone().try_upvars_resolved(self) {
+                match place_resolved.into_place(self).ty(&self.local_decls, tcx).ty.kind() {
+                    ty::Array(_, length) => (length.eval_usize(tcx, self.param_env), true),
+                    _ => ((prefix.len() + suffix.len()).try_into().unwrap(), false),
+                }
+            } else {
+                ((prefix.len() + suffix.len()).try_into().unwrap(), false)
+            };
 
         match_pairs.extend(prefix.iter().enumerate().map(|(idx, subpattern)| {
             let elem =
@@ -96,7 +94,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 }
 
 impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
-    pub(crate) fn new(
+    pub(in crate::build) fn new(
         place: PlaceBuilder<'tcx>,
         pattern: &'pat Pat<'tcx>,
     ) -> MatchPair<'pat, 'tcx> {
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index b2fd9f25bdd..2c7d6a572f4 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -553,6 +553,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
     /// Convenience wrapper that pushes a scope and then executes `f`
     /// to build its contents, popping the scope afterwards.
+    #[instrument(skip(self, f), level = "debug")]
     pub(crate) fn in_scope<F, R>(
         &mut self,
         region_scope: (region::Scope, SourceInfo),
@@ -562,7 +563,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     where
         F: FnOnce(&mut Builder<'a, 'tcx>) -> BlockAnd<R>,
     {
-        debug!("in_scope(region_scope={:?})", region_scope);
         let source_scope = self.source_scope;
         let tcx = self.tcx;
         if let LintLevel::Explicit(current_hir_id) = lint_level {
@@ -589,7 +589,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let rv = unpack!(block = f(self));
         unpack!(block = self.pop_scope(region_scope, block));
         self.source_scope = source_scope;
-        debug!("in_scope: exiting region_scope={:?} block={:?}", region_scope, block);
+        debug!(?block);
         block.and(rv)
     }
 
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index d059877f8e7..3f8a9d21cd8 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -48,6 +48,8 @@ impl<'tcx> Cx<'tcx> {
             _ => None,
         };
 
+        trace!(?expr.ty);
+
         // Now apply adjustments, if any.
         for adjustment in self.typeck_results.expr_adjustments(hir_expr) {
             trace!(?expr, ?adjustment);
@@ -56,6 +58,8 @@ impl<'tcx> Cx<'tcx> {
                 self.apply_adjustment(hir_expr, expr, adjustment, adjustment_span.unwrap_or(span));
         }
 
+        trace!(?expr.ty, "after adjustments");
+
         // Next, wrap this up in the expr's scope.
         expr = Expr {
             temp_lifetime,
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 2c131a26d3a..a679ea8bed0 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -200,6 +200,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         }
     }
 
+    #[instrument(skip(self), level = "debug")]
     fn lower_pattern_unadjusted(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
         let mut ty = self.typeck_results.node_type(pat.hir_id);
         let mut span = pat.span;