From 20431706a863f92cb37dc512fef6e48d192aaf2c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:11:38 +0200 Subject: Merging upstream version 1.66.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_mir_build/src/build/block.rs | 37 +++--- .../rustc_mir_build/src/build/expr/as_constant.rs | 7 +- .../rustc_mir_build/src/build/expr/as_operand.rs | 5 +- .../rustc_mir_build/src/build/expr/as_place.rs | 76 ++++++------ .../rustc_mir_build/src/build/expr/as_rvalue.rs | 24 +--- compiler/rustc_mir_build/src/build/expr/as_temp.rs | 5 +- compiler/rustc_mir_build/src/build/expr/into.rs | 5 +- compiler/rustc_mir_build/src/build/matches/mod.rs | 96 +++++++-------- .../rustc_mir_build/src/build/matches/simplify.rs | 35 +++--- compiler/rustc_mir_build/src/build/matches/test.rs | 25 ++-- compiler/rustc_mir_build/src/build/matches/util.rs | 51 +++++--- compiler/rustc_mir_build/src/build/mod.rs | 132 ++++++++++----------- compiler/rustc_mir_build/src/build/scope.rs | 4 +- 13 files changed, 245 insertions(+), 257 deletions(-) (limited to 'compiler/rustc_mir_build/src/build') diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs index 784583d94..183db56d7 100644 --- a/compiler/rustc_mir_build/src/build/block.rs +++ b/compiler/rustc_mir_build/src/build/block.rs @@ -221,26 +221,32 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let init = &this.thir[*initializer]; let initializer_span = init.span; - this.declare_bindings( - visibility_scope, - remainder_span, - pattern, - ArmHasGuard(false), - Some((None, initializer_span)), - ); - this.visit_primary_bindings( - pattern, - UserTypeProjections::none(), - &mut |this, _, _, _, node, span, _, _| { - this.storage_live_binding(block, node, span, OutsideGuard, true); - }, - ); let failure = unpack!( block = this.in_opt_scope( opt_destruction_scope.map(|de| (de, source_info)), |this| { let scope = (*init_scope, source_info); this.in_scope(scope, *lint_level, |this| { + this.declare_bindings( + visibility_scope, + remainder_span, + pattern, + ArmHasGuard(false), + Some((None, initializer_span)), + ); + this.visit_primary_bindings( + pattern, + UserTypeProjections::none(), + &mut |this, _, _, _, node, span, _, _| { + this.storage_live_binding( + block, + node, + span, + OutsideGuard, + true, + ); + }, + ); this.ast_let_else( block, init, @@ -305,7 +311,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ArmHasGuard(false), Some((None, initializer_span)), ); - this.expr_into_pattern(block, &pattern, init) // irrefutable pattern + this.expr_into_pattern(block, &pattern, init) + // irrefutable pattern }) }, ) diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index c9bec130c..37dc1ad9f 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -2,6 +2,7 @@ use crate::build::{parse_float_into_constval, Builder}; use rustc_ast as ast; +use rustc_middle::mir; use rustc_middle::mir::interpret::{ Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar, }; @@ -66,7 +67,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }) }); - let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs); + let uneval = + mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); let literal = ConstantKind::Unevaluated(uneval, ty); Constant { user_ty, span, literal } @@ -79,7 +81,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Constant { user_ty: None, span, literal } } ExprKind::ConstBlock { did: def_id, substs } => { - let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs); + let uneval = + mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); let literal = ConstantKind::Unevaluated(uneval, ty); Constant { user_ty: None, span, literal } diff --git a/compiler/rustc_mir_build/src/build/expr/as_operand.rs b/compiler/rustc_mir_build/src/build/expr/as_operand.rs index e707c373f..c8610af70 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs @@ -153,12 +153,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if tcx.features().unsized_fn_params { let ty = expr.ty; - let span = expr.span; let param_env = this.param_env; - if !ty.is_sized(tcx.at(span), param_env) { + if !ty.is_sized(tcx, param_env) { // !sized means !copy, so this is an unsized move - assert!(!ty.is_copy_modulo_regions(tcx.at(span), param_env)); + assert!(!ty.is_copy_modulo_regions(tcx, param_env)); // As described above, detect the case where we are passing a value of unsized // type, and that value is coming from the deref of a box. 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 ebb56e5a2..396782d45 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -17,6 +17,7 @@ use rustc_target::abi::VariantIdx; use rustc_index::vec::Idx; +use std::assert_matches::assert_matches; use std::iter; /// The "outermost" place that holds this value. @@ -69,7 +70,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>, } @@ -102,6 +103,8 @@ fn convert_to_hir_projections_and_truncate_for_capture<'tcx>( variant = Some(*idx); continue; } + // These do not affect anything, they just make sure we know the right type. + ProjectionElem::OpaqueCast(_) => continue, ProjectionElem::Index(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => { @@ -168,22 +171,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), ret)] +fn to_upvars_resolved_place_builder<'tcx>( from_builder: PlaceBuilder<'tcx>, - tcx: TyCtxt<'tcx>, - upvars: &'a CaptureMap<'tcx>, + cx: &Builder<'_, 'tcx>, ) -> Result, 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,12 +203,13 @@ 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, @@ -229,17 +233,20 @@ fn strip_prefix<'tcx>( projections: Vec>, prefix_projections: &[HirProjection<'tcx>], ) -> impl Iterator> { - let mut iter = projections.into_iter(); + let mut iter = projections + .into_iter() + // Filter out opaque casts, they are unnecessary in the prefix. + .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(..))); for projection in prefix_projections { match projection.kind { HirProjectionKind::Deref => { - assert!(matches!(iter.next(), Some(ProjectionElem::Deref))); + assert_matches!(iter.next(), Some(ProjectionElem::Deref)); } HirProjectionKind::Field(..) => { if base_ty.is_enum() { - assert!(matches!(iter.next(), Some(ProjectionElem::Downcast(..)))); + assert_matches!(iter.next(), Some(ProjectionElem::Downcast(..))); } - assert!(matches!(iter.next(), Some(ProjectionElem::Field(..)))); + assert_matches!(iter.next(), Some(ProjectionElem::Field(..))); } HirProjectionKind::Index | HirProjectionKind::Subslice => { bug!("unexpected projection kind: {:?}", projection); @@ -251,24 +258,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,18 +281,21 @@ 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>> { - to_upvars_resolved_place_builder(self, tcx, upvars) + to_upvars_resolved_place_builder(self, cx) } pub(crate) fn base(&self) -> PlaceBase { self.base } + pub(crate) fn projection(&self) -> &[PlaceElem<'tcx>] { + &self.projection + } + pub(crate) fn field(self, f: Field, ty: Ty<'tcx>) -> Self { self.project(PlaceElem::Field(f, ty)) } @@ -353,7 +355,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { expr: &Expr<'tcx>, ) -> BlockAnd> { 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 +379,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { expr: &Expr<'tcx>, ) -> BlockAnd> { 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 +474,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 +612,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 +640,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, @@ -723,6 +720,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ProjectionElem::Field(..) | ProjectionElem::Downcast(..) + | ProjectionElem::OpaqueCast(..) | ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => (), } 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 f88ab63f0..3dafdcb78 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -12,7 +12,7 @@ use rustc_middle::mir::AssertKind; use rustc_middle::mir::Place; use rustc_middle::mir::*; use rustc_middle::thir::*; -use rustc_middle::ty::cast::CastTy; +use rustc_middle::ty::cast::{mir_cast_kind, CastTy}; use rustc_middle::ty::{self, Ty, UpvarSubsts}; use rustc_span::Span; @@ -217,16 +217,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let from_ty = CastTy::from_ty(ty); let cast_ty = CastTy::from_ty(expr.ty); debug!("ExprKind::Cast from_ty={from_ty:?}, cast_ty={:?}/{cast_ty:?}", expr.ty,); - let cast_kind = match (from_ty, cast_ty) { - (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => { - CastKind::PointerExposeAddress - } - (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => { - CastKind::PointerFromExposedAddress - } - (_, Some(CastTy::DynStar)) => CastKind::DynStar, - (_, _) => CastKind::Misc, - }; + let cast_kind = mir_cast_kind(ty, expr.ty); block.and(Rvalue::Cast(cast_kind, source, expr.ty)) } ExprKind::Pointer { cast, source } => { @@ -329,10 +320,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 +612,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 +649,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 e5dafb820..0ca4e3745 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 { - 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 224a1b80f..24ecd0a53 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 93f382cc6..3f813e0af 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); } @@ -246,7 +244,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .map(|arm| { let arm = &self.thir[arm]; let arm_has_guard = arm.guard.is_some(); - let arm_candidate = Candidate::new(scrutinee.clone(), &arm.pattern, arm_has_guard); + let arm_candidate = + Candidate::new(scrutinee.clone(), &arm.pattern, arm_has_guard, self); (arm, arm_candidate) }) .collect() @@ -349,9 +348,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( @@ -584,7 +583,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { initializer: PlaceBuilder<'tcx>, set_match_place: bool, ) -> BlockAnd<()> { - let mut candidate = Candidate::new(initializer.clone(), &irrefutable_pat, false); + let mut candidate = Candidate::new(initializer.clone(), &irrefutable_pat, false, self); let fake_borrow_temps = self.lower_match_tree( block, irrefutable_pat.span, @@ -601,12 +600,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 @@ -621,10 +614,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); } } @@ -654,6 +651,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, @@ -662,7 +660,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { has_guard: ArmHasGuard, opt_match_place: Option<(Option<&Place<'tcx>>, Span)>, ) -> Option { - debug!("declare_bindings: pattern={:?}", pattern); self.visit_primary_bindings( &pattern, UserTypeProjections::none(), @@ -868,11 +865,16 @@ struct Candidate<'pat, 'tcx> { } impl<'tcx, 'pat> Candidate<'pat, 'tcx> { - fn new(place: PlaceBuilder<'tcx>, pattern: &'pat Pat<'tcx>, has_guard: bool) -> Self { + fn new( + place: PlaceBuilder<'tcx>, + pattern: &'pat Pat<'tcx>, + has_guard: bool, + cx: &Builder<'_, 'tcx>, + ) -> Self { Candidate { span: pattern.span, has_guard, - match_pairs: smallvec![MatchPair { place, pattern }], + match_pairs: smallvec![MatchPair::new(place, pattern, cx)], bindings: Vec::new(), ascriptions: Vec::new(), subcandidates: Vec::new(), @@ -1048,6 +1050,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, @@ -1057,11 +1060,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidates: &mut [&mut Candidate<'pat, 'tcx>], fake_borrows: &mut Option>>, ) { - 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. @@ -1380,6 +1378,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>, @@ -1389,10 +1391,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { place: PlaceBuilder<'tcx>, fake_borrows: &mut Option>>, ) { - 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)) + .map(|pat| Candidate::new(place.clone(), pat, candidate.has_guard, self)) .collect(); let mut or_candidate_refs: Vec<_> = or_candidates.iter_mut().collect(); let otherwise = if candidate.otherwise_block.is_some() { @@ -1605,9 +1607,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); } @@ -1634,9 +1636,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 @@ -1783,8 +1790,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let expr_span = expr.span; let expr_place_builder = unpack!(block = self.lower_scrutinee(block, expr, expr_span)); let wildcard = Pat::wildcard_from_ty(pat.ty); - let mut guard_candidate = Candidate::new(expr_place_builder.clone(), &pat, false); - let mut otherwise_candidate = Candidate::new(expr_place_builder.clone(), &wildcard, false); + let mut guard_candidate = Candidate::new(expr_place_builder.clone(), &pat, false, self); + let mut otherwise_candidate = + Candidate::new(expr_place_builder.clone(), &wildcard, false, self); let fake_borrow_temps = self.lower_match_tree( block, pat.span, @@ -1794,8 +1802,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(); @@ -2209,6 +2217,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, @@ -2223,19 +2232,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { opt_match_place: Option<(Option>, 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, @@ -2285,7 +2287,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); } @@ -2302,8 +2304,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let (matching, failure) = self.in_if_then_scope(*let_else_scope, else_block_span, |this| { let scrutinee = unpack!(block = this.lower_scrutinee(block, init, initializer_span)); let pat = Pat { ty: init.ty, span: else_block_span, kind: PatKind::Wild }; - let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false); - let mut candidate = Candidate::new(scrutinee.clone(), pattern, false); + let mut wildcard = Candidate::new(scrutinee.clone(), &pat, false, this); + let mut candidate = Candidate::new(scrutinee.clone(), pattern, false, this); let fake_borrow_temps = this.lower_match_tree( block, initializer_span, diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index df221d356..924d2f555 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 @@ -131,7 +132,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ) -> Vec> { pats.iter() .map(|box pat| { - let mut candidate = Candidate::new(place.clone(), pat, candidate.has_guard); + let mut candidate = Candidate::new(place.clone(), pat, candidate.has_guard, self); self.simplify_candidate(&mut candidate); candidate }) @@ -155,17 +156,15 @@ 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, }); } - candidate.match_pairs.push(MatchPair::new(match_pair.place, subpattern)); + candidate.match_pairs.push(MatchPair::new(match_pair.place, subpattern, self)); Ok(()) } @@ -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, }); @@ -197,7 +194,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { if let Some(subpattern) = subpattern.as_ref() { // this is the `x @ P` case; have to keep matching against `P` now - candidate.match_pairs.push(MatchPair::new(match_pair.place, subpattern)); + candidate.match_pairs.push(MatchPair::new(match_pair.place, subpattern, self)); } Ok(()) @@ -267,14 +264,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| { i == variant_index || { self.tcx.features().exhaustive_patterns - && !v - .uninhabited_from( - self.tcx, - substs, - adt_def.adt_kind(), - self.param_env, - ) - .is_empty() + && v.inhabited_predicate(self.tcx, adt_def) + .subst(self.tcx, substs) + .apply_any_module(self.tcx, self.param_env) + != Some(true) } }) && (adt_def.did().is_local() || !adt_def.is_variant_list_non_exhaustive()); @@ -308,7 +301,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { PatKind::Deref { ref subpattern } => { let place_builder = match_pair.place.deref(); - candidate.match_pairs.push(MatchPair::new(place_builder, subpattern)); + candidate.match_pairs.push(MatchPair::new(place_builder, subpattern, self)); Ok(()) } diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 47d05a6e3..b597ecfaa 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -14,8 +14,8 @@ use rustc_hir::{LangItem, RangeEnd}; use rustc_index::bit_set::BitSet; use rustc_middle::mir::*; use rustc_middle::thir::*; -use rustc_middle::ty::subst::{GenericArg, Subst}; use rustc_middle::ty::util::IntTypeExt; +use rustc_middle::ty::GenericArg; use rustc_middle::ty::{self, adjustment::PointerCast, Ty, TyCtxt}; use rustc_span::def_id::DefId; use rustc_span::symbol::{sym, Symbol}; @@ -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, ) { - 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,14 +724,12 @@ 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); // e.g., `(x as Variant).0 @ P1` - MatchPair::new(place, &subpattern.pattern) + MatchPair::new(place, &subpattern.pattern, self) }); candidate.match_pairs.extend(consequent_match_pairs); diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index b61c4fe50..b854ba47f 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -1,9 +1,11 @@ +use crate::build::expr::as_place::PlaceBase; use crate::build::expr::as_place::PlaceBuilder; use crate::build::matches::MatchPair; use crate::build::Builder; use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty; +use rustc_middle::ty::TypeVisitable; use smallvec::SmallVec; use std::convert::TryInto; @@ -17,7 +19,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .iter() .map(|fieldpat| { let place = place.clone().field(fieldpat.field, fieldpat.pattern.ty); - MatchPair::new(place, &fieldpat.pattern) + MatchPair::new(place, &fieldpat.pattern, self) }) .collect() } @@ -31,23 +33,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { suffix: &'pat [Box>], ) { 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 = ProjectionElem::ConstantIndex { offset: idx as u64, min_length, from_end: false }; let place = place.clone().project(elem); - MatchPair::new(place, subpattern) + MatchPair::new(place, subpattern, self) })); if let Some(subslice_pat) = opt_slice { @@ -57,7 +57,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { to: if exact_size { min_length - suffix_len } else { suffix_len }, from_end: !exact_size, }); - match_pairs.push(MatchPair::new(subslice, subslice_pat)); + match_pairs.push(MatchPair::new(subslice, subslice_pat, self)); } match_pairs.extend(suffix.iter().rev().enumerate().map(|(idx, subpattern)| { @@ -68,7 +68,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { from_end: !exact_size, }; let place = place.clone().project(elem); - MatchPair::new(place, subpattern) + MatchPair::new(place, subpattern, self) })); } @@ -96,10 +96,29 @@ 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>, + cx: &Builder<'_, 'tcx>, ) -> MatchPair<'pat, 'tcx> { + // Force the place type to the pattern's type. + // FIXME(oli-obk): can we use this to simplify slice/array pattern hacks? + let mut place = match place.try_upvars_resolved(cx) { + Ok(val) | Err(val) => val, + }; + + // Only add the OpaqueCast projection if the given place is an opaque type and the + // expected type from the pattern is not. + let may_need_cast = match place.base() { + PlaceBase::Local(local) => { + let ty = Place::ty_from(local, place.projection(), &cx.local_decls, cx.tcx).ty; + ty != pattern.ty && ty.has_opaque_types() + } + _ => true, + }; + if may_need_cast { + place = place.project(ProjectionElem::OpaqueCast(pattern.ty)); + } MatchPair { place, pattern } } } diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 25c4e51cb..cbcf9cd12 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -157,7 +157,7 @@ struct BlockContext(Vec); struct Builder<'a, 'tcx> { tcx: TyCtxt<'tcx>, - infcx: InferCtxt<'a, 'tcx>, + infcx: InferCtxt<'tcx>, typeck_results: &'tcx TypeckResults<'tcx>, region_scope_tree: &'tcx region::ScopeTree, param_env: ty::ParamEnv<'tcx>, @@ -481,54 +481,49 @@ fn construct_fn<'tcx>( (None, fn_sig.output()) }; - let mut body = tcx.infer_ctxt().enter(|infcx| { - let mut builder = Builder::new( - thir, - infcx, - fn_def, - fn_id, - span_with_body, - arguments.len(), - safety, - return_ty, - return_ty_span, - generator_kind, - ); + let infcx = tcx.infer_ctxt().build(); + let mut builder = Builder::new( + thir, + infcx, + fn_def, + fn_id, + span_with_body, + arguments.len(), + safety, + return_ty, + return_ty_span, + generator_kind, + ); - let call_site_scope = - region::Scope { id: body_id.hir_id.local_id, data: region::ScopeData::CallSite }; - let arg_scope = - region::Scope { id: body_id.hir_id.local_id, data: region::ScopeData::Arguments }; - let source_info = builder.source_info(span); - let call_site_s = (call_site_scope, source_info); - unpack!(builder.in_scope(call_site_s, LintLevel::Inherited, |builder| { - let arg_scope_s = (arg_scope, source_info); - // Attribute epilogue to function's closing brace - let fn_end = span_with_body.shrink_to_hi(); - let return_block = unpack!(builder.in_breakable_scope( - None, - Place::return_place(), - fn_end, - |builder| { - Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| { - builder.args_and_body( - START_BLOCK, - fn_def.did, - arguments, - arg_scope, - &thir[expr], - ) - })) - } - )); - let source_info = builder.source_info(fn_end); - builder.cfg.terminate(return_block, source_info, TerminatorKind::Return); - builder.build_drop_trees(); - return_block.unit() - })); - - builder.finish() - }); + let call_site_scope = + region::Scope { id: body_id.hir_id.local_id, data: region::ScopeData::CallSite }; + let arg_scope = + region::Scope { id: body_id.hir_id.local_id, data: region::ScopeData::Arguments }; + let source_info = builder.source_info(span); + let call_site_s = (call_site_scope, source_info); + unpack!(builder.in_scope(call_site_s, LintLevel::Inherited, |builder| { + let arg_scope_s = (arg_scope, source_info); + // Attribute epilogue to function's closing brace + let fn_end = span_with_body.shrink_to_hi(); + let return_block = + unpack!(builder.in_breakable_scope(None, Place::return_place(), fn_end, |builder| { + Some(builder.in_scope(arg_scope_s, LintLevel::Inherited, |builder| { + builder.args_and_body( + START_BLOCK, + fn_def.did, + arguments, + arg_scope, + &thir[expr], + ) + })) + })); + let source_info = builder.source_info(fn_end); + builder.cfg.terminate(return_block, source_info, TerminatorKind::Return); + builder.build_drop_trees(); + return_block.unit() + })); + + let mut body = builder.finish(); body.spread_arg = if abi == Abi::RustCall { // RustCall pseudo-ABI untuples the last argument. @@ -584,30 +579,29 @@ fn construct_const<'a, 'tcx>( let typeck_results = tcx.typeck_opt_const_arg(def); let const_ty = typeck_results.node_type(hir_id); - tcx.infer_ctxt().enter(|infcx| { - let mut builder = Builder::new( - thir, - infcx, - def, - hir_id, - span, - 0, - Safety::Safe, - const_ty, - const_ty_span, - None, - ); + let infcx = tcx.infer_ctxt().build(); + let mut builder = Builder::new( + thir, + infcx, + def, + hir_id, + span, + 0, + Safety::Safe, + const_ty, + const_ty_span, + None, + ); - let mut block = START_BLOCK; - unpack!(block = builder.expr_into_dest(Place::return_place(), block, &thir[expr])); + let mut block = START_BLOCK; + unpack!(block = builder.expr_into_dest(Place::return_place(), block, &thir[expr])); - let source_info = builder.source_info(span); - builder.cfg.terminate(block, source_info, TerminatorKind::Return); + let source_info = builder.source_info(span); + builder.cfg.terminate(block, source_info, TerminatorKind::Return); - builder.build_drop_trees(); + builder.build_drop_trees(); - builder.finish() - }) + builder.finish() } /// Construct MIR for an item that has had errors in type checking. @@ -683,7 +677,7 @@ fn construct_error<'tcx>( impl<'a, 'tcx> Builder<'a, 'tcx> { fn new( thir: &'a Thir<'tcx>, - infcx: InferCtxt<'a, 'tcx>, + infcx: InferCtxt<'tcx>, def: ty::WithOptConstParam, hir_id: hir::HirId, span: Span, diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index ff66ca595..3cebd5ebe 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -555,6 +555,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( &mut self, region_scope: (region::Scope, SourceInfo), @@ -564,7 +565,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { where F: FnOnce(&mut Builder<'a, 'tcx>) -> BlockAnd, { - 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 { @@ -591,7 +591,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) } -- cgit v1.2.3