diff options
Diffstat (limited to '')
-rw-r--r-- | compiler/rustc_mir_build/src/build/expr/as_constant.rs | 40 | ||||
-rw-r--r-- | compiler/rustc_mir_build/src/build/expr/as_operand.rs | 5 | ||||
-rw-r--r-- | compiler/rustc_mir_build/src/build/expr/as_place.rs | 188 | ||||
-rw-r--r-- | compiler/rustc_mir_build/src/build/expr/as_rvalue.rs | 45 | ||||
-rw-r--r-- | compiler/rustc_mir_build/src/build/expr/as_temp.rs | 10 | ||||
-rw-r--r-- | compiler/rustc_mir_build/src/build/expr/into.rs | 28 | ||||
-rw-r--r-- | compiler/rustc_mir_build/src/build/expr/stmt.rs | 22 |
7 files changed, 134 insertions, 204 deletions
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 648d10b9e..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,26 +2,19 @@ use crate::build::{parse_float_into_constval, Builder}; use rustc_ast as ast; -use rustc_hir::def_id::DefId; +use rustc_middle::mir; use rustc_middle::mir::interpret::{ Allocation, ConstValue, LitToConstError, LitToConstInput, Scalar, }; use rustc_middle::mir::*; use rustc_middle::thir::*; -use rustc_middle::ty::subst::SubstsRef; -use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt}; +use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, TyCtxt}; use rustc_target::abi::Size; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Compile `expr`, yielding a compile-time constant. Assumes that /// `expr` is a valid compile-time constant! pub(crate) fn as_constant(&mut self, expr: &Expr<'tcx>) -> Constant<'tcx> { - let create_uneval_from_def_id = - |tcx: TyCtxt<'tcx>, def_id: DefId, ty: Ty<'tcx>, substs: SubstsRef<'tcx>| { - let uneval = ty::Unevaluated::new(ty::WithOptConstParam::unknown(def_id), substs); - tcx.mk_const(ty::ConstS { kind: ty::ConstKind::Unevaluated(uneval), ty }) - }; - let this = self; let tcx = this.tcx; let Expr { ty, temp_lifetime: _, span, ref kind } = *expr; @@ -41,11 +34,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Constant { span, user_ty: None, literal } } - ExprKind::NonHirLiteral { lit, user_ty } => { - let user_ty = user_ty.map(|user_ty| { + ExprKind::NonHirLiteral { lit, ref user_ty } => { + let user_ty = user_ty.as_ref().map(|user_ty| { this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { span, - user_ty, + user_ty: user_ty.clone(), inferred_ty: ty, }) }); @@ -53,11 +46,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Constant { span, user_ty: user_ty, literal } } - ExprKind::ZstLiteral { user_ty } => { - let user_ty = user_ty.map(|user_ty| { + ExprKind::ZstLiteral { ref user_ty } => { + let user_ty = user_ty.as_ref().map(|user_ty| { this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { span, - user_ty, + user_ty: user_ty.clone(), inferred_ty: ty, }) }); @@ -65,15 +58,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Constant { span, user_ty: user_ty, literal } } - ExprKind::NamedConst { def_id, substs, user_ty } => { - let user_ty = user_ty.map(|user_ty| { + ExprKind::NamedConst { def_id, substs, ref user_ty } => { + let user_ty = user_ty.as_ref().map(|user_ty| { this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { span, - user_ty, + user_ty: user_ty.clone(), inferred_ty: ty, }) }); - let literal = ConstantKind::Ty(create_uneval_from_def_id(tcx, def_id, ty, substs)); + + let uneval = + mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); + let literal = ConstantKind::Unevaluated(uneval, ty); Constant { user_ty, span, literal } } @@ -85,7 +81,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { Constant { user_ty: None, span, literal } } ExprKind::ConstBlock { did: def_id, substs } => { - let literal = ConstantKind::Ty(create_uneval_from_def_id(tcx, def_id, ty, substs)); + let uneval = + mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); + let literal = ConstantKind::Unevaluated(uneval, ty); Constant { user_ty: None, span, literal } } @@ -144,7 +142,7 @@ pub(crate) fn lit_to_mir_constant<'tcx>( } (ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)), (ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)), - (ast::LitKind::Err(_), _) => return Err(LitToConstError::Reported), + (ast::LitKind::Err, _) => return Err(LitToConstError::Reported), _ => return Err(LitToConstError::TypeError), }; 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 0c06aad4e..396782d45 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -2,7 +2,7 @@ use crate::build::expr::category::Category; use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; -use crate::build::{BlockAnd, BlockAndExtension, Builder}; +use crate::build::{BlockAnd, BlockAndExtension, Builder, Capture, CaptureMap}; use rustc_hir::def_id::LocalDefId; use rustc_middle::hir::place::Projection as HirProjection; use rustc_middle::hir::place::ProjectionKind as HirProjectionKind; @@ -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. @@ -59,8 +60,6 @@ pub(crate) enum PlaceBase { var_hir_id: LocalVarId, /// DefId of the closure closure_def_id: LocalDefId, - /// The trait closure implements, `Fn`, `FnMut`, `FnOnce` - closure_kind: ty::ClosureKind, }, } @@ -71,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<PlaceElem<'tcx>>, } @@ -104,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 { .. } => { @@ -145,27 +146,6 @@ fn is_ancestor_or_same_capture( iter::zip(proj_possible_ancestor, proj_capture).all(|(a, b)| a == b) } -/// Computes the index of a capture within the desugared closure provided the closure's -/// `closure_min_captures` and the capture's index of the capture in the -/// `ty::MinCaptureList` of the root variable `var_hir_id`. -fn compute_capture_idx<'tcx>( - closure_min_captures: &ty::RootVariableMinCaptureList<'tcx>, - var_hir_id: LocalVarId, - root_var_idx: usize, -) -> usize { - let mut res = 0; - for (var_id, capture_list) in closure_min_captures { - if *var_id == var_hir_id.0 { - res += root_var_idx; - break; - } else { - res += capture_list.len(); - } - } - - res -} - /// Given a closure, returns the index of a capture within the desugared closure struct and the /// `ty::CapturedPlace` which is the ancestor of the Place represented using the `var_hir_id` /// and `projection`. @@ -174,58 +154,39 @@ fn compute_capture_idx<'tcx>( /// /// Returns None, when the ancestor is not found. fn find_capture_matching_projections<'a, 'tcx>( - typeck_results: &'a ty::TypeckResults<'tcx>, + upvars: &'a CaptureMap<'tcx>, var_hir_id: LocalVarId, - closure_def_id: LocalDefId, projections: &[PlaceElem<'tcx>], -) -> Option<(usize, &'a ty::CapturedPlace<'tcx>)> { - let closure_min_captures = typeck_results.closure_min_captures.get(&closure_def_id)?; - let root_variable_min_captures = closure_min_captures.get(&var_hir_id.0)?; - +) -> Option<(usize, &'a Capture<'tcx>)> { let hir_projections = convert_to_hir_projections_and_truncate_for_capture(projections); - // If an ancestor is found, `idx` is the index within the list of captured places - // for root variable `var_hir_id` and `capture` is the `ty::CapturedPlace` itself. - let (idx, capture) = root_variable_min_captures.iter().enumerate().find(|(_, capture)| { + upvars.get_by_key_enumerated(var_hir_id.0).find(|(_, capture)| { let possible_ancestor_proj_kinds: Vec<_> = - capture.place.projections.iter().map(|proj| proj.kind).collect(); + capture.captured_place.place.projections.iter().map(|proj| proj.kind).collect(); is_ancestor_or_same_capture(&possible_ancestor_proj_kinds, &hir_projections) - })?; - - // Convert index to be from the perspective of the entire closure_min_captures map - // instead of just the root variable capture list - Some((compute_capture_idx(closure_min_captures, var_hir_id, idx), capture)) + }) } /// Takes a PlaceBuilder and resolves the upvar (if any) within it, so that the /// `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>, - typeck_results: &'a ty::TypeckResults<'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, closure_kind } => { - let mut upvar_resolved_place_builder = PlaceBuilder::from(ty::CAPTURE_STRUCT_LOCAL); - match closure_kind { - ty::ClosureKind::Fn | ty::ClosureKind::FnMut => { - upvar_resolved_place_builder = upvar_resolved_place_builder.deref(); - } - ty::ClosureKind::FnOnce => {} - } - + PlaceBase::Upvar { var_hir_id, closure_def_id } => { let Some((capture_index, capture)) = find_capture_matching_projections( - typeck_results, + &cx.upvars, var_hir_id, - closure_def_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", @@ -241,39 +202,18 @@ fn to_upvars_resolved_place_builder<'a, 'tcx>( return Err(from_builder); }; - // We won't be building MIR if the closure wasn't local - let closure_hir_id = tcx.hir().local_def_id_to_hir_id(closure_def_id); - let closure_ty = typeck_results.node_type(closure_hir_id); - - let substs = match closure_ty.kind() { - ty::Closure(_, substs) => ty::UpvarSubsts::Closure(substs), - ty::Generator(_, substs, _) => ty::UpvarSubsts::Generator(substs), - _ => bug!("Lowering capture for non-closure type {:?}", closure_ty), - }; - // Access the capture by accessing the field within the Closure struct. - // - // We must have inferred the capture types since we are building MIR, therefore - // it's safe to call `tuple_element_ty` and we can unwrap here because - // we know that the capture exists and is the `capture_index`-th capture. - let var_ty = substs.tupled_upvars_ty().tuple_fields()[capture_index]; - - upvar_resolved_place_builder = - upvar_resolved_place_builder.field(Field::new(capture_index), var_ty); - - // If the variable is captured via ByRef(Immutable/Mutable) Borrow, - // we need to deref it - upvar_resolved_place_builder = match capture.info.capture_kind { - ty::UpvarCapture::ByRef(_) => upvar_resolved_place_builder.deref(), - ty::UpvarCapture::ByValue => upvar_resolved_place_builder, - }; + 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.place.base_ty, + capture.captured_place.place.base_ty, from_builder.projection, - &capture.place.projections, + &capture.captured_place.place.projections, ); upvar_resolved_place_builder.projection.extend(remaining_projections); @@ -293,17 +233,20 @@ fn strip_prefix<'tcx>( projections: Vec<PlaceElem<'tcx>>, prefix_projections: &[HirProjection<'tcx>], ) -> impl Iterator<Item = PlaceElem<'tcx>> { - 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); @@ -315,24 +258,16 @@ fn strip_prefix<'tcx>( } impl<'tcx> PlaceBuilder<'tcx> { - pub(crate) fn into_place<'a>( - self, - tcx: TyCtxt<'tcx>, - typeck_results: &'a ty::TypeckResults<'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, typeck_results).into_place(tcx, typeck_results) + self.expect_upvars_resolved(cx).into_place(cx) } } - fn expect_upvars_resolved<'a>( - self, - tcx: TyCtxt<'tcx>, - typeck_results: &'a ty::TypeckResults<'tcx>, - ) -> PlaceBuilder<'tcx> { - to_upvars_resolved_place_builder(self, tcx, typeck_results).unwrap() + fn expect_upvars_resolved(self, cx: &Builder<'_, 'tcx>) -> PlaceBuilder<'tcx> { + to_upvars_resolved_place_builder(self, cx).unwrap() } /// Attempts to resolve the `PlaceBuilder`. @@ -346,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(crate) fn try_upvars_resolved<'a>( + pub(in crate::build) fn try_upvars_resolved( self, - tcx: TyCtxt<'tcx>, - typeck_results: &'a ty::TypeckResults<'tcx>, + cx: &Builder<'_, 'tcx>, ) -> Result<PlaceBuilder<'tcx>, PlaceBuilder<'tcx>> { - to_upvars_resolved_place_builder(self, tcx, typeck_results) + 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)) } @@ -392,6 +330,12 @@ impl<'tcx> From<PlaceBase> for PlaceBuilder<'tcx> { } } +impl<'tcx> From<Place<'tcx>> for PlaceBuilder<'tcx> { + fn from(p: Place<'tcx>) -> Self { + Self { base: PlaceBase::Local(p.local), projection: p.projection.to_vec() } + } +} + impl<'a, 'tcx> Builder<'a, 'tcx> { /// Compile `expr`, yielding a place that we can move from etc. /// @@ -411,7 +355,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.typeck_results)) + block.and(place_builder.into_place(self)) } /// This is used when constructing a compound `Place`, so that we can avoid creating @@ -435,7 +379,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.typeck_results)) + block.and(place_builder.into_place(self)) } /// This is used when constructing a compound `Place`, so that we can avoid creating @@ -513,7 +457,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block.and(place_builder) } - ExprKind::PlaceTypeAscription { source, user_ty } => { + ExprKind::PlaceTypeAscription { source, ref user_ty } => { let place_builder = unpack!( block = this.expr_as_place( block, @@ -526,11 +470,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let annotation_index = this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { span: source_info.span, - user_ty, + user_ty: user_ty.clone(), inferred_ty: expr.ty, }); - let place = place_builder.clone().into_place(this.tcx, this.typeck_results); + let place = place_builder.clone().into_place(this); this.cfg.push( block, Statement { @@ -547,7 +491,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } block.and(place_builder) } - ExprKind::ValueTypeAscription { source, user_ty } => { + ExprKind::ValueTypeAscription { source, ref user_ty } => { let source = &this.thir[source]; let temp = unpack!(block = this.as_temp(block, source.temp_lifetime, source, mutability)); @@ -555,7 +499,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let annotation_index = this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { span: source_info.span, - user_ty, + user_ty: user_ty.clone(), inferred_ty: expr.ty, }); this.cfg.push( @@ -629,17 +573,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { closure_def_id: LocalDefId, var_hir_id: LocalVarId, ) -> BlockAnd<PlaceBuilder<'tcx>> { - let closure_ty = - self.typeck_results.node_type(self.tcx.hir().local_def_id_to_hir_id(closure_def_id)); - - let closure_kind = if let ty::Closure(_, closure_substs) = closure_ty.kind() { - self.infcx.closure_kind(closure_substs).unwrap() - } else { - // Generators are considered FnOnce. - ty::ClosureKind::FnOnce - }; - - block.and(PlaceBuilder::from(PlaceBase::Upvar { var_hir_id, closure_def_id, closure_kind })) + block.and(PlaceBuilder::from(PlaceBase::Upvar { var_hir_id, closure_def_id })) } /// Lower an index expression @@ -678,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.typeck_results); + base_place = base_place.expect_upvars_resolved(self); self.add_fake_borrows_of_base( &base_place, block, @@ -706,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.typeck_results)), - ); + self.cfg.push_assign(block, source_info, len, Rvalue::Len(slice.into_place(self))); // lt = idx < len self.cfg.push_assign( block, @@ -791,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 15f2d17c4..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; @@ -197,13 +197,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // create all the steps directly in MIR with operations all backends need to support anyway. let (source, ty) = if let ty::Adt(adt_def, ..) = source.ty.kind() && adt_def.is_enum() { let discr_ty = adt_def.repr().discr_type().to_ty(this.tcx); - let place = unpack!(block = this.as_place(block, source)); + let temp = unpack!(block = this.as_temp(block, scope, source, Mutability::Not)); let discr = this.temp(discr_ty, source.span); this.cfg.push_assign( block, source_info, discr, - Rvalue::Discriminant(place), + Rvalue::Discriminant(temp.into()), ); (Operand::Move(discr), discr_ty) @@ -216,15 +216,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }; let from_ty = CastTy::from_ty(ty); let cast_ty = CastTy::from_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 - } - (_, _) => CastKind::Misc, - }; + debug!("ExprKind::Cast from_ty={from_ty:?}, cast_ty={:?}/{cast_ty:?}", expr.ty,); + let cast_kind = mir_cast_kind(ty, expr.ty); block.and(Rvalue::Cast(cast_kind, source, expr.ty)) } ExprKind::Pointer { cast, source } => { @@ -302,7 +295,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { block.and(Rvalue::Aggregate(Box::new(AggregateKind::Tuple), fields)) } - ExprKind::Closure { closure_id, substs, ref upvars, movability, ref fake_reads } => { + ExprKind::Closure(box ClosureExpr { + closure_id, + substs, + ref upvars, + movability, + ref fake_reads, + }) => { // Convert the closure fake reads, if any, from `ExprRef` to mir `Place` // and push the fake reads. // This must come before creating the operands. This is required in case @@ -321,11 +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.typeck_results) - { - let mir_place = - place_builder_resolved.into_place(this.tcx, this.typeck_results); + 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)), @@ -616,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.typeck_results); + let enclosing_upvars_resolved = arg_place_builder.clone().into_place(this); match enclosing_upvars_resolved.as_ref() { PlaceRef { @@ -637,12 +632,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); // Not in a closure debug_assert!( - this.upvar_mutbls.len() > upvar_index.index(), - "Unexpected capture place, upvar_mutbls={:#?}, upvar_index={:?}", - this.upvar_mutbls, + this.upvars.len() > upvar_index.index(), + "Unexpected capture place, upvars={:#?}, upvar_index={:?}", + this.upvars, upvar_index ); - this.upvar_mutbls[upvar_index.index()] + this.upvars[upvar_index.index()].mutability } _ => bug!("Unexpected capture place"), } @@ -654,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.typeck_results); + 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 724b72f87..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<Local> { - debug!( - "as_temp(block={:?}, temp_lifetime={:?}, expr={:?}, mutability={:?})", - block, temp_lifetime, expr, mutability - ); let this = self; let expr_span = expr.span; @@ -83,8 +80,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Don't bother with StorageLive and Dead for these temporaries, // they are never assigned. ExprKind::Break { .. } | ExprKind::Continue { .. } | ExprKind::Return { .. } => (), - ExprKind::Block { body: Block { expr: None, targeted_by_break: false, .. } } - if expr_ty.is_never() => {} + ExprKind::Block { block } + if let Block { expr: None, targeted_by_break: false, .. } = this.thir[block] + && expr_ty.is_never() => {} _ => { this.cfg .push(block, Statement { source_info, kind: StatementKind::StorageLive(temp) }); diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 017d43d10..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 @@ -46,7 +45,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }) }) } - ExprKind::Block { body: ref ast_block } => { + ExprKind::Block { block: ast_block } => { this.ast_block(destination, block, ast_block, source_info) } ExprKind::Match { scrutinee, ref arms } => { @@ -75,7 +74,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.source_info(then_expr.span) }; let (then_block, else_block) = - this.in_if_then_scope(condition_scope, |this| { + this.in_if_then_scope(condition_scope, then_expr.span, |this| { let then_blk = unpack!(this.then_else_break( block, &this.thir[cond], @@ -108,7 +107,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } ExprKind::Let { expr, ref pat } => { let scope = this.local_scope(); - let (true_block, false_block) = this.in_if_then_scope(scope, |this| { + let (true_block, false_block) = this.in_if_then_scope(scope, expr_span, |this| { this.lower_let_expr(block, &this.thir[expr], pat, scope, None, expr_span) }); @@ -314,11 +313,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { this.cfg.push_assign(block, source_info, destination, address_of); block.unit() } - ExprKind::Adt(box Adt { + ExprKind::Adt(box AdtExpr { adt_def, variant_index, substs, - user_ty, + ref user_ty, ref fields, ref base, }) => { @@ -366,9 +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.typeck_results), + place_builder.field(n, *ty).into_place(this), ) } }) @@ -378,10 +375,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }; let inferred_ty = expr.ty; - let user_ty = user_ty.map(|ty| { + let user_ty = user_ty.as_ref().map(|user_ty| { this.canonical_user_type_annotations.push(CanonicalUserTypeAnnotation { span: source_info.span, - user_ty: ty, + user_ty: user_ty.clone(), inferred_ty, }) }); @@ -400,7 +397,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); block.unit() } - ExprKind::InlineAsm { template, ref operands, options, line_spans } => { + ExprKind::InlineAsm(box InlineAsmExpr { + template, + ref operands, + options, + line_spans, + }) => { use rustc_middle::{mir, thir}; let operands = operands .into_iter() diff --git a/compiler/rustc_mir_build/src/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs index a7e1331aa..00dbcaeb0 100644 --- a/compiler/rustc_mir_build/src/build/expr/stmt.rs +++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs @@ -116,14 +116,22 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // it is usually better to focus on `the_value` rather // than the entirety of block(s) surrounding it. let adjusted_span = (|| { - if let ExprKind::Block { body } = &expr.kind && let Some(tail_ex) = body.expr { + if let ExprKind::Block { block } = expr.kind + && let Some(tail_ex) = this.thir[block].expr + { let mut expr = &this.thir[tail_ex]; - while let ExprKind::Block { - body: Block { expr: Some(nested_expr), .. }, - } - | ExprKind::Scope { value: nested_expr, .. } = expr.kind - { - expr = &this.thir[nested_expr]; + loop { + match expr.kind { + ExprKind::Block { block } + if let Some(nested_expr) = this.thir[block].expr => + { + expr = &this.thir[nested_expr]; + } + ExprKind::Scope { value: nested_expr, .. } => { + expr = &this.thir[nested_expr]; + } + _ => break, + } } this.block_context.push(BlockFrame::TailExpr { tail_result_is_ignored: true, |