diff options
Diffstat (limited to 'compiler/rustc_mir_build/src')
17 files changed, 126 insertions, 355 deletions
diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index 7c39a93a8eb..dca4906c07d 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -15,9 +15,6 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { @call("mir_retag", args) => { Ok(StatementKind::Retag(RetagKind::Default, Box::new(self.parse_place(args[0])?))) }, - @call("mir_retag_raw", args) => { - Ok(StatementKind::Retag(RetagKind::Raw, Box::new(self.parse_place(args[0])?))) - }, @call("mir_set_discriminant", args) => { let place = self.parse_place(args[0])?; let var = self.parse_integer_literal(args[1])? as u32; 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 3b7ed818dc9..1d96893c7a3 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -66,14 +66,14 @@ pub fn as_constant_inner<'tcx>( let literal = ConstantKind::Val(ConstValue::Scalar(Scalar::Int(lit)), ty); - Constant { span, user_ty: user_ty, literal } + Constant { span, user_ty, literal } } ExprKind::ZstLiteral { ref user_ty } => { let user_ty = user_ty.as_ref().map(push_cuta).flatten(); let literal = ConstantKind::Val(ConstValue::ZeroSized, ty); - Constant { span, user_ty: user_ty, literal } + Constant { span, user_ty, literal } } ExprKind::NamedConst { def_id, substs, ref user_ty } => { let user_ty = user_ty.as_ref().map(push_cuta).flatten(); 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 c8610af7038..dbcb0132c9f 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_operand.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_operand.rs @@ -72,7 +72,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { /// will actually provide a pointer to the interior of the box, and not move the `dyn Debug` /// value to the stack. /// - /// See #68034 for more details. + /// See #68304 for more details. pub(crate) fn as_local_call_operand( &mut self, block: BasicBlock, 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 23a4f85386b..e22fa6365dc 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -7,7 +7,6 @@ use rustc_hir::def_id::LocalDefId; use rustc_middle::hir::place::Projection as HirProjection; use rustc_middle::hir::place::ProjectionKind as HirProjectionKind; use rustc_middle::middle::region; -use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::AssertKind::BoundsCheck; use rustc_middle::mir::*; use rustc_middle::thir::*; @@ -19,31 +18,23 @@ use rustc_target::abi::VariantIdx; use rustc_index::vec::Idx; use std::assert_matches::assert_matches; -use std::convert::From; use std::iter; -/// `PlaceBuilder` is used to create places during MIR construction. It allows you to "build up" a -/// place by pushing more and more projections onto the end, and then convert the final set into a -/// place using the `into_place` method. -/// -/// 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(in crate::build) enum PlaceBuilder<'tcx> { +/// The "outermost" place that holds this value. +#[derive(Copy, Clone, Debug, PartialEq)] +pub(crate) enum PlaceBase { /// Denotes the start of a `Place`. - /// - /// We use `PlaceElem` since this has all `Field` types available. - Local { local: Local, projection: Vec<PlaceElem<'tcx>> }, + Local(Local), /// When building place for an expression within a closure, the place might start off a /// captured path. When `capture_disjoint_fields` is enabled, we might not know the capture /// index (within the desugared closure) of the captured path until most of the projections - /// are applied. We use `PlaceBuilder::Upvar` to keep track of the root variable off of which the + /// are applied. We use `PlaceBase::Upvar` to keep track of the root variable off of which the /// captured path starts, the closure the capture belongs to and the trait the closure /// implements. /// - /// Once we have figured out the capture index, we can convert the place builder to - /// `PlaceBuilder::Local`. + /// Once we have figured out the capture index, we can convert the place builder to start from + /// `PlaceBase::Local`. /// /// Consider the following example /// ```rust @@ -64,16 +55,24 @@ pub(in crate::build) enum PlaceBuilder<'tcx> { /// /// When `capture_disjoint_fields` is enabled, `t.0.0.0` is captured and we won't be able to /// figure out that it is captured until all the `Field` projections are applied. - /// - /// Note: in contrast to `PlaceBuilder::Local` we have not yet determined all `Field` types - /// and will only do so once converting to `PlaceBuilder::Local`. - Upvar { upvar: Upvar, projection: Vec<UpvarProjectionElem<'tcx>> }, + Upvar { + /// HirId of the upvar + var_hir_id: LocalVarId, + /// DefId of the closure + closure_def_id: LocalDefId, + }, } -#[derive(Copy, Clone, Debug, PartialEq)] -pub(crate) struct Upvar { - var_hir_id: LocalVarId, - closure_def_id: LocalDefId, +/// `PlaceBuilder` is used to create places during MIR construction. It allows you to "build up" a +/// place by pushing more and more projections onto the end, and then convert the final set into a +/// place using the `to_place` method. +/// +/// 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(in crate::build) struct PlaceBuilder<'tcx> { + base: PlaceBase, + projection: Vec<PlaceElem<'tcx>>, } /// Given a list of MIR projections, convert them to list of HIR ProjectionKind. @@ -82,8 +81,8 @@ pub(crate) struct Upvar { /// ProjectionElems `Downcast`, `ConstantIndex`, `Index`, or `Subslice` because those will never be /// part of a path that is captured by a closure. We stop applying projections once we see the first /// projection that isn't captured by a closure. -fn convert_to_hir_projections_and_truncate_for_capture<'tcx>( - mir_projections: &[UpvarProjectionElem<'tcx>], +fn convert_to_hir_projections_and_truncate_for_capture( + mir_projections: &[PlaceElem<'_>], ) -> Vec<HirProjectionKind> { let mut hir_projections = Vec::new(); let mut variant = None; @@ -157,7 +156,7 @@ fn is_ancestor_or_same_capture( fn find_capture_matching_projections<'a, 'tcx>( upvars: &'a CaptureMap<'tcx>, var_hir_id: LocalVarId, - projections: &[UpvarProjectionElem<'tcx>], + projections: &[PlaceElem<'tcx>], ) -> Option<(usize, &'a Capture<'tcx>)> { let hir_projections = convert_to_hir_projections_and_truncate_for_capture(projections); @@ -175,7 +174,7 @@ fn to_upvars_resolved_place_builder<'tcx>( cx: &Builder<'_, 'tcx>, var_hir_id: LocalVarId, closure_def_id: LocalDefId, - projection: &[UpvarProjectionElem<'tcx>], + projection: &[PlaceElem<'tcx>], ) -> Option<PlaceBuilder<'tcx>> { let Some((capture_index, capture)) = find_capture_matching_projections( @@ -197,32 +196,23 @@ fn to_upvars_resolved_place_builder<'tcx>( var_hir_id, projection, ); } - return None; }; // Access the capture by accessing the field within the Closure struct. let capture_info = &cx.upvars[capture_index]; - let Place { local: upvar_resolved_local, projection: local_projection } = - capture_info.use_place; + 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. - let upvar_projection = strip_prefix( + trace!(?capture.captured_place, ?projection); + let remaining_projections = strip_prefix( capture.captured_place.place.base_ty, projection, &capture.captured_place.place.projections, ); - - let upvar_resolved_place_builder = PlaceBuilder::construct_local_place_builder( - cx, - upvar_resolved_local, - local_projection.as_slice(), - upvar_projection, - ); - - assert!(matches!(upvar_resolved_place_builder, PlaceBuilder::Local { .. })); + upvar_resolved_place_builder.projection.extend(remaining_projections); Some(upvar_resolved_place_builder) } @@ -235,17 +225,15 @@ fn to_upvars_resolved_place_builder<'tcx>( /// projection kinds are unsupported. fn strip_prefix<'a, 'tcx>( mut base_ty: Ty<'tcx>, - projections: &'a [UpvarProjectionElem<'tcx>], + projections: &'a [PlaceElem<'tcx>], prefix_projections: &[HirProjection<'tcx>], -) -> impl Iterator<Item = UpvarProjectionElem<'tcx>> + 'a { +) -> impl Iterator<Item = PlaceElem<'tcx>> + 'a { let mut iter = projections .iter() .copied() // Filter out opaque casts, they are unnecessary in the prefix. .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(..))); for projection in prefix_projections { - debug!(?projection, ?projection.ty); - match projection.kind { HirProjectionKind::Deref => { assert_matches!(iter.next(), Some(ProjectionElem::Deref)); @@ -260,10 +248,8 @@ fn strip_prefix<'a, 'tcx>( bug!("unexpected projection kind: {:?}", projection); } } - base_ty = projection.ty; } - iter } @@ -276,9 +262,9 @@ impl<'tcx> PlaceBuilder<'tcx> { pub(in crate::build) fn try_to_place(&self, cx: &Builder<'_, 'tcx>) -> Option<Place<'tcx>> { let resolved = self.resolve_upvar(cx); let builder = resolved.as_ref().unwrap_or(self); - let PlaceBuilder::Local{local, ref projection} = builder else { return None }; - let projection = cx.tcx.intern_place_elems(projection); - Some(Place { local: *local, projection }) + let PlaceBase::Local(local) = builder.base else { return None }; + let projection = cx.tcx.intern_place_elems(&builder.projection); + Some(Place { local, projection }) } /// Attempts to resolve the `PlaceBuilder`. @@ -295,31 +281,22 @@ impl<'tcx> PlaceBuilder<'tcx> { &self, cx: &Builder<'_, 'tcx>, ) -> Option<PlaceBuilder<'tcx>> { - let PlaceBuilder::Upvar{ upvar: Upvar {var_hir_id, closure_def_id }, projection} = self else { + let PlaceBase::Upvar { var_hir_id, closure_def_id } = self.base else { return None; }; - - to_upvars_resolved_place_builder(cx, *var_hir_id, *closure_def_id, &projection) + to_upvars_resolved_place_builder(cx, var_hir_id, closure_def_id, &self.projection) } - #[instrument(skip(cx), level = "debug")] - pub(crate) fn field(self, cx: &Builder<'_, 'tcx>, f: Field) -> Self { - match self.clone() { - PlaceBuilder::Local { local, projection } => { - let base_place = PlaceBuilder::Local { local, projection }; - let PlaceTy { ty, variant_index } = - base_place.to_place(cx).ty(&cx.local_decls, cx.tcx); - let base_ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty); + pub(crate) fn base(&self) -> PlaceBase { + self.base + } - let field_ty = PlaceBuilder::compute_field_ty(cx, f, base_ty, variant_index); + pub(crate) fn projection(&self) -> &[PlaceElem<'tcx>] { + &self.projection + } - self.project(ProjectionElem::Field(f, field_ty)) - } - PlaceBuilder::Upvar { upvar, mut projection } => { - projection.push(ProjectionElem::Field(f, ())); - PlaceBuilder::Upvar { upvar, projection } - } - } + pub(crate) fn field(self, f: Field, ty: Ty<'tcx>) -> Self { + self.project(PlaceElem::Field(f, ty)) } pub(crate) fn deref(self) -> Self { @@ -334,236 +311,35 @@ impl<'tcx> PlaceBuilder<'tcx> { self.project(PlaceElem::Index(index)) } - #[instrument(level = "debug")] - pub(crate) fn project(self, elem: PlaceElem<'tcx>) -> Self { - let result = match self { - PlaceBuilder::Local { local, mut projection } => { - projection.push(elem); - PlaceBuilder::Local { local, projection } - } - PlaceBuilder::Upvar { upvar, mut projection } => { - projection.push(elem.into()); - PlaceBuilder::Upvar { upvar, projection } - } - }; - - debug!(?result); - result + pub(crate) fn project(mut self, elem: PlaceElem<'tcx>) -> Self { + self.projection.push(elem); + self } /// Same as `.clone().project(..)` but more efficient pub(crate) fn clone_project(&self, elem: PlaceElem<'tcx>) -> Self { - match self { - PlaceBuilder::Local { local, projection } => PlaceBuilder::Local { - local: *local, - projection: Vec::from_iter(projection.iter().copied().chain([elem])), - }, - PlaceBuilder::Upvar { upvar, projection } => PlaceBuilder::Upvar { - upvar: *upvar, - projection: Vec::from_iter(projection.iter().copied().chain([elem.into()])), - }, + Self { + base: self.base, + projection: Vec::from_iter(self.projection.iter().copied().chain([elem])), } } - - /// Similar to `Place::ty` but needed during mir building. - /// - /// Applies the projections in the `PlaceBuilder` to the base - /// type. - /// - /// Fallible as the root of this place may be an upvar for - /// which no base type can be determined. - #[instrument(skip(cx), level = "debug")] - fn compute_field_ty( - cx: &Builder<'_, 'tcx>, - field: Field, - base_ty: Ty<'tcx>, - variant_index: Option<VariantIdx>, - ) -> Ty<'tcx> { - let field_idx = field.as_usize(); - let field_ty = match base_ty.kind() { - ty::Adt(adt_def, substs) if adt_def.is_enum() => { - let variant_idx = variant_index.unwrap(); - adt_def.variant(variant_idx).fields[field_idx].ty(cx.tcx, substs) - } - ty::Adt(adt_def, substs) => adt_def - .all_fields() - .nth(field_idx) - .unwrap_or_else(|| { - bug!( - "expected to take field with idx {:?} of fields of {:?}", - field_idx, - adt_def - ) - }) - .ty(cx.tcx, substs), - ty::Tuple(elems) => elems.iter().nth(field_idx).unwrap_or_else(|| { - bug!("expected to take field with idx {:?} of {:?}", field_idx, elems) - }), - ty::Closure(_, substs) => { - let substs = substs.as_closure(); - let Some(f_ty) = substs.upvar_tys().nth(field_idx) else { - bug!("expected to take field with idx {:?} of {:?}", field_idx, substs.upvar_tys().collect::<Vec<_>>()); - }; - - f_ty - } - &ty::Generator(def_id, substs, _) => { - if let Some(var) = variant_index { - let gen_body = cx.tcx.optimized_mir(def_id); - let Some(layout) = gen_body.generator_layout() else { - bug!("No generator layout for {:?}", base_ty); - }; - - let Some(&local) = layout.variant_fields[var].get(field) else { - bug!("expected to take field {:?} of {:?}", field, layout.variant_fields[var]); - }; - - let Some(&f_ty) = layout.field_tys.get(local) else { - bug!("expected to get element for {:?} in {:?}", local, layout.field_tys); - }; - - f_ty - } else { - let Some(f_ty) = substs.as_generator().prefix_tys().nth(field.index()) else { - bug!( - "expected to take index {:?} in {:?}", - field.index(), - substs.as_generator().prefix_tys().collect::<Vec<_>>() - ); - }; - - f_ty - } - } - _ => bug!("couldn't create field type, unexpected base type: {:?}", base_ty), - }; - - cx.tcx.normalize_erasing_regions(cx.param_env, field_ty) - } - - /// Creates a `PlaceBuilder::Local` from a `PlaceBuilder::Upvar` whose upvars - /// are resolved. This function takes two kinds of projections: `local_projection` - /// contains the projections of the captured upvar and `upvar_projection` the - /// projections that are applied to the captured upvar. The main purpose of this - /// function is to figure out the `Ty`s of the field projections in `upvar_projection`. - #[instrument(skip(cx, local, upvar_projection))] - fn construct_local_place_builder( - cx: &Builder<'_, 'tcx>, - local: Local, - local_projection: &[PlaceElem<'tcx>], - upvar_projection: impl Iterator<Item = UpvarProjectionElem<'tcx>>, - ) -> Self { - // We maintain a `Ty` to which we apply a projection in each iteration over `upvar_projection`. - // This `ancestor_ty` let's us infer the field type whenever we encounter a - // `ProjectionElem::Field`. - let (mut ancestor_ty, mut opt_variant_idx) = - local_projections_to_ty(cx, local, local_projection); - - // We add all projection elements we encounter to this `Vec`. - let mut local_projection = local_projection.to_vec(); - - for (i, proj) in upvar_projection.enumerate() { - debug!("i: {:?}, proj: {:?}, local_projection: {:?}", i, proj, local_projection); - match proj { - ProjectionElem::Field(field, _) => { - let field_ty = - PlaceBuilder::compute_field_ty(cx, field, ancestor_ty, opt_variant_idx); - debug!(?field_ty); - - local_projection.push(ProjectionElem::Field(field, field_ty)); - ancestor_ty = field_ty; - opt_variant_idx = None; - } - _ => { - let proj = upvar_proj_to_place_elem_no_field_proj(proj); - (ancestor_ty, opt_variant_idx) = project_ty(cx.tcx, ancestor_ty, proj); - local_projection.push(proj); - } - } - } - - PlaceBuilder::Local { local, projection: local_projection } - } } impl<'tcx> From<Local> for PlaceBuilder<'tcx> { fn from(local: Local) -> Self { - Self::Local { local, projection: Vec::new() } + Self { base: PlaceBase::Local(local), projection: Vec::new() } } } -impl<'tcx> From<Place<'tcx>> for PlaceBuilder<'tcx> { - fn from(p: Place<'tcx>) -> Self { - Self::Local { local: p.local, projection: p.projection.to_vec() } - } -} - -fn project_ty<'tcx>( - tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>, - elem: PlaceElem<'tcx>, -) -> (Ty<'tcx>, Option<VariantIdx>) { - match elem { - ProjectionElem::Deref => { - let updated_ty = ty - .builtin_deref(true) - .unwrap_or_else(|| bug!("deref projection of non-dereferenceable ty {:?}", ty)) - .ty; - - (updated_ty, None) - } - ProjectionElem::Index(_) | ProjectionElem::ConstantIndex { .. } => { - (ty.builtin_index().unwrap(), None) - } - ProjectionElem::Subslice { from, to, from_end } => { - let ty = match ty.kind() { - ty::Slice(..) => ty, - ty::Array(inner, _) if !from_end => tcx.mk_array(*inner, (to - from) as u64), - ty::Array(inner, size) if from_end => { - let size = size.eval_usize(tcx, ty::ParamEnv::empty()); - let len = size - (from as u64) - (to as u64); - tcx.mk_array(*inner, len) - } - _ => bug!("cannot subslice non-array type: `{:?}`", ty), - }; - - (ty, None) - } - ProjectionElem::Downcast(_, variant_idx) => (ty, Some(variant_idx)), - ProjectionElem::Field(_, ty) => (ty, None), - ProjectionElem::OpaqueCast(..) => bug!("didn't expect OpaqueCast"), +impl<'tcx> From<PlaceBase> for PlaceBuilder<'tcx> { + fn from(base: PlaceBase) -> Self { + Self { base, projection: Vec::new() } } } -fn local_projections_to_ty<'a, 'tcx>( - cx: &'a Builder<'a, 'tcx>, - local: Local, - projection: &'a [PlaceElem<'tcx>], -) -> (Ty<'tcx>, Option<VariantIdx>) { - let local_ty = cx.local_decls.local_decls()[local].ty; - projection.iter().fold((local_ty, None), |ty_variant_idx, elem| { - let ty = ty_variant_idx.0; - project_ty(cx.tcx, ty, *elem) - }) -} - -// Converts an `UpvarProjectionElem` to `PlaceElem`, ICE'ing when being passed a -// field projection. -fn upvar_proj_to_place_elem_no_field_proj<'tcx>( - upvar_proj: UpvarProjectionElem<'tcx>, -) -> PlaceElem<'tcx> { - match upvar_proj { - ProjectionElem::Deref => ProjectionElem::Deref, - ProjectionElem::Index(i) => ProjectionElem::Index(i), - ProjectionElem::ConstantIndex { offset, min_length, from_end } => { - ProjectionElem::ConstantIndex { offset, min_length, from_end } - } - ProjectionElem::Subslice { from, to, from_end } => { - ProjectionElem::Subslice { from, to, from_end } - } - ProjectionElem::Downcast(ty, variant_idx) => ProjectionElem::Downcast(ty, variant_idx), - ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty), - ProjectionElem::Field(..) => bug!("should not be called with `ProjectionElem::Field`"), +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() } } } @@ -627,7 +403,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { self.expr_as_place(block, expr, Mutability::Not, None) } - #[instrument(skip(self, fake_borrow_temps), level = "debug")] fn expr_as_place( &mut self, mut block: BasicBlock, @@ -635,6 +410,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { mutability: Mutability, fake_borrow_temps: Option<&mut Vec<Local>>, ) -> BlockAnd<PlaceBuilder<'tcx>> { + debug!("expr_as_place(block={:?}, expr={:?}, mutability={:?})", block, expr, mutability); + let this = self; let expr_span = expr.span; let source_info = this.source_info(expr_span); @@ -648,13 +425,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let lhs = &this.thir[lhs]; let mut place_builder = unpack!(block = this.expr_as_place(block, lhs, mutability, fake_borrow_temps,)); - debug!(?place_builder); if let ty::Adt(adt_def, _) = lhs.ty.kind() { if adt_def.is_enum() { place_builder = place_builder.downcast(*adt_def, variant_index); } } - block.and(place_builder.field(this, name)) + block.and(place_builder.field(name, expr.ty)) } ExprKind::Deref { arg } => { let place_builder = unpack!( @@ -796,7 +572,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } /// Lower a captured upvar. Note we might not know the actual capture index, - /// so we create a place starting from `Upvar`, which will be resolved + /// so we create a place starting from `PlaceBase::Upvar`, which will be resolved /// once all projections that allow us to identify a capture have been applied. fn lower_captured_upvar( &mut self, @@ -804,10 +580,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { closure_def_id: LocalDefId, var_hir_id: LocalVarId, ) -> BlockAnd<PlaceBuilder<'tcx>> { - block.and(PlaceBuilder::Upvar { - upvar: Upvar { var_hir_id, closure_def_id }, - projection: vec![], - }) + block.and(PlaceBuilder::from(PlaceBase::Upvar { var_hir_id, closure_def_id })) } /// Lower an index expression @@ -898,8 +671,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { source_info: SourceInfo, ) { let tcx = self.tcx; - let place_ty = base_place.ty(&self.local_decls, tcx); + let place_ty = base_place.ty(&self.local_decls, tcx); if let ty::Slice(_) = place_ty.ty.kind() { // We need to create fake borrows to ensure that the bounds // check that we just did stays valid. Since we can't assign to 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 b420e820171..c7b3eb44dc5 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -4,8 +4,9 @@ use rustc_index::vec::Idx; use rustc_middle::ty::util::IntTypeExt; use rustc_target::abi::{Abi, Primitive}; +use crate::build::expr::as_place::PlaceBase; use crate::build::expr::category::{Category, RvalueFunc}; -use crate::build::{BlockAnd, BlockAndExtension, Builder, NeedsTemporary, PlaceBuilder}; +use crate::build::{BlockAnd, BlockAndExtension, Builder, NeedsTemporary}; use rustc_hir::lang_items::LangItem; use rustc_middle::middle::region; use rustc_middle::mir::AssertKind; @@ -650,15 +651,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let arg_place_builder = unpack!(block = this.as_place_builder(block, arg)); - let mutability = match arg_place_builder { + let mutability = match arg_place_builder.base() { // We are capturing a path that starts off a local variable in the parent. // The mutability of the current capture is same as the mutability // of the local declaration in the parent. - PlaceBuilder::Local { local, .. } => this.local_decls[local].mutability, + PlaceBase::Local(local) => this.local_decls[local].mutability, // Parent is a closure and we are capturing a path that is captured // by the parent itself. The mutability of the current capture // is same as that of the capture in the parent closure. - PlaceBuilder::Upvar { .. } => { + PlaceBase::Upvar { .. } => { let enclosing_upvars_resolved = arg_place_builder.to_place(this); match enclosing_upvars_resolved.as_ref() { diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 895051d7590..38b1fa91d0a 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -355,13 +355,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // base-supplied field, generate an operand that // reads it from the base. iter::zip(field_names, &**field_types) - .map(|(n, _ty)| match fields_map.get(&n) { + .map(|(n, ty)| match fields_map.get(&n) { Some(v) => v.clone(), None => { - let place_builder = place_builder.clone(); - this.consume_by_copy_or_move( - place_builder.field(this, n).to_place(this), - ) + let place = place_builder.clone_project(PlaceElem::Field(n, *ty)); + this.consume_by_copy_or_move(place.to_place(this)) } }) .collect() diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 7edcd46a34f..f90aba80bf3 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -2210,7 +2210,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { BindingMode::ByValue => ty::BindingMode::BindByValue(mutability), BindingMode::ByRef(_) => ty::BindingMode::BindByReference(mutability), }; - let local = LocalDecl::<'tcx> { + let local = LocalDecl { mutability, ty: var_ty, user_ty: if user_ty.is_empty() { None } else { Some(Box::new(user_ty)) }, diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs index 36aa7693e82..f6b1955fdec 100644 --- a/compiler/rustc_mir_build/src/build/matches/simplify.rs +++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs @@ -272,9 +272,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { || !adt_def.is_variant_list_non_exhaustive()); if irrefutable { let place_builder = match_pair.place.downcast(adt_def, variant_index); - let field_match_pairs = - self.field_match_pairs(place_builder.clone(), subpatterns); - candidate.match_pairs.extend(field_match_pairs); + candidate + .match_pairs + .extend(self.field_match_pairs(place_builder, subpatterns)); Ok(()) } else { Err(match_pair) diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index 6c10704c5db..46e14cc9ac3 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -757,7 +757,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { 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(self, subpattern.field); + let place = downcast_place + .clone_project(PlaceElem::Field(subpattern.field, subpattern.pattern.ty)); // e.g., `(x as Variant).0 @ P1` MatchPair::new(place, &subpattern.pattern, self) }); diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index d95dbfca78e..cbd494862a0 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -1,3 +1,4 @@ +use crate::build::expr::as_place::PlaceBase; use crate::build::expr::as_place::PlaceBuilder; use crate::build::matches::MatchPair; use crate::build::Builder; @@ -16,8 +17,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { subpatterns .iter() .map(|fieldpat| { - let place = place.clone().field(self, fieldpat.field); - + let place = + place.clone_project(PlaceElem::Field(fieldpat.field, fieldpat.pattern.ty)); MatchPair::new(place, &fieldpat.pattern, self) }) .collect() @@ -106,9 +107,9 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> { // 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 { - PlaceBuilder::Local { local, ref projection } => { - let ty = Place::ty_from(local, projection, &cx.local_decls, cx.tcx).ty; + 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, diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 7af89dd472f..9daf68a15f4 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -28,10 +28,10 @@ use rustc_target::spec::abi::Abi; use super::lints; -pub(crate) fn mir_built<'tcx>( - tcx: TyCtxt<'tcx>, +pub(crate) fn mir_built( + tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>, -) -> &'tcx rustc_data_structures::steal::Steal<Body<'tcx>> { +) -> &rustc_data_structures::steal::Steal<Body<'_>> { if let Some(def) = def.try_upgrade(tcx) { return tcx.mir_built(def); } @@ -372,7 +372,7 @@ struct CFG<'tcx> { } rustc_index::newtype_index! { - struct ScopeId { .. } + struct ScopeId {} } #[derive(Debug)] @@ -625,12 +625,12 @@ fn construct_const<'a, 'tcx>( /// /// This is required because we may still want to run MIR passes on an item /// with type errors, but normal MIR construction can't handle that in general. -fn construct_error<'tcx>( - tcx: TyCtxt<'tcx>, +fn construct_error( + tcx: TyCtxt<'_>, def: LocalDefId, body_owner_kind: hir::BodyOwnerKind, err: ErrorGuaranteed, -) -> Body<'tcx> { +) -> Body<'_> { let span = tcx.def_span(def); let hir_id = tcx.hir().local_def_id_to_hir_id(def); let generator_kind = tcx.generator_kind(def); diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 33f49ffdaf6..c92634a609d 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -185,7 +185,7 @@ pub(crate) enum BreakableTarget { } rustc_index::newtype_index! { - struct DropIdx { .. } + struct DropIdx {} } const ROOT_NODE: DropIdx = DropIdx::from_u32(0); diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 99e96ff77ce..03a7f2d70fa 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -5,6 +5,7 @@ use rustc_middle::thir::visit::{self, Visitor}; use rustc_hir as hir; use rustc_middle::mir::BorrowKind; use rustc_middle::thir::*; +use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt}; use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE}; use rustc_session::lint::Level; @@ -524,17 +525,19 @@ impl UnsafeOpKind { hir_id: hir::HirId, span: Span, ) { + // FIXME: ideally we would want to trim the def paths, but this is not + // feasible with the current lint emission API (see issue #106126). match self { - CallToUnsafeFunction(did) if did.is_some() => tcx.emit_spanned_lint( + CallToUnsafeFunction(Some(did)) => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, span, UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { span, - function: &tcx.def_path_str(did.unwrap()), + function: &with_no_trimmed_paths!(tcx.def_path_str(*did)), }, ), - CallToUnsafeFunction(..) => tcx.emit_spanned_lint( + CallToUnsafeFunction(None) => tcx.emit_spanned_lint( UNSAFE_OP_IN_UNSAFE_FN, hir_id, span, @@ -594,7 +597,7 @@ impl UnsafeOpKind { span, UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { span, - function: &tcx.def_path_str(*did), + function: &with_no_trimmed_paths!(tcx.def_path_str(*did)), }, ), } @@ -607,24 +610,24 @@ impl UnsafeOpKind { unsafe_op_in_unsafe_fn_allowed: bool, ) { match self { - CallToUnsafeFunction(did) if did.is_some() && unsafe_op_in_unsafe_fn_allowed => { + CallToUnsafeFunction(Some(did)) if unsafe_op_in_unsafe_fn_allowed => { tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed { span, - function: &tcx.def_path_str(did.unwrap()), + function: &tcx.def_path_str(*did), }); } - CallToUnsafeFunction(did) if did.is_some() => { + CallToUnsafeFunction(Some(did)) => { tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafe { span, - function: &tcx.def_path_str(did.unwrap()), + function: &tcx.def_path_str(*did), }); } - CallToUnsafeFunction(..) if unsafe_op_in_unsafe_fn_allowed => { + CallToUnsafeFunction(None) if unsafe_op_in_unsafe_fn_allowed => { tcx.sess.emit_err( CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { span }, ); } - CallToUnsafeFunction(..) => { + CallToUnsafeFunction(None) => { tcx.sess.emit_err(CallToUnsafeFunctionRequiresUnsafeNameless { span }); } UseOfInlineAssembly if unsafe_op_in_unsafe_fn_allowed => { @@ -703,7 +706,7 @@ impl UnsafeOpKind { } } -pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalDefId>) { +pub fn check_unsafety(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) { // THIR unsafeck is gated under `-Z thir-unsafeck` if !tcx.sess.opts.unstable_opts.thir_unsafeck { return; @@ -749,7 +752,7 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalD visitor.visit_expr(&thir[expr]); } -pub(crate) fn thir_check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) { +pub(crate) fn thir_check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) { if let Some(def) = ty::WithOptConstParam::try_lookup(def_id, tcx) { tcx.thir_check_unsafety_for_const_arg(def) } else { @@ -757,8 +760,8 @@ pub(crate) fn thir_check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) { } } -pub(crate) fn thir_check_unsafety_for_const_arg<'tcx>( - tcx: TyCtxt<'tcx>, +pub(crate) fn thir_check_unsafety_for_const_arg( + tcx: TyCtxt<'_>, (did, param_did): (LocalDefId, DefId), ) { check_unsafety(tcx, ty::WithOptConstParam { did, const_param_did: Some(param_did) }) diff --git a/compiler/rustc_mir_build/src/thir/cx/mod.rs b/compiler/rustc_mir_build/src/thir/cx/mod.rs index b5c4b7b137d..a355e1bdab5 100644 --- a/compiler/rustc_mir_build/src/thir/cx/mod.rs +++ b/compiler/rustc_mir_build/src/thir/cx/mod.rs @@ -18,10 +18,10 @@ use rustc_middle::thir::*; use rustc_middle::ty::{self, RvalueScopes, TyCtxt}; use rustc_span::Span; -pub(crate) fn thir_body<'tcx>( - tcx: TyCtxt<'tcx>, +pub(crate) fn thir_body( + tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>, -) -> Result<(&'tcx Steal<Thir<'tcx>>, ExprId), ErrorGuaranteed> { +) -> Result<(&Steal<Thir<'_>>, ExprId), ErrorGuaranteed> { let hir = tcx.hir(); let body = hir.body(hir.body_owned_by(owner_def.did)); let mut cx = Cx::new(tcx, owner_def); @@ -52,10 +52,7 @@ pub(crate) fn thir_body<'tcx>( Ok((tcx.alloc_steal_thir(cx.thir), expr)) } -pub(crate) fn thir_tree<'tcx>( - tcx: TyCtxt<'tcx>, - owner_def: ty::WithOptConstParam<LocalDefId>, -) -> String { +pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: ty::WithOptConstParam<LocalDefId>) -> String { match thir_body(tcx, owner_def) { Ok((thir, _)) => format!("{:#?}", thir.steal()), Err(_) => "error".into(), diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index a94d8d6c643..e7ee0d9e908 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -247,14 +247,14 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> { fn check_let_chain(&mut self, cx: &mut MatchCheckCtxt<'p, 'tcx>, pat_id: HirId) -> bool { let hir = self.tcx.hir(); - let parent = hir.get_parent_node(pat_id); + let parent = hir.parent_id(pat_id); // First, figure out if the given pattern is part of a let chain, // and if so, obtain the top node of the chain. let mut top = parent; let mut part_of_chain = false; loop { - let new_top = hir.get_parent_node(top); + let new_top = hir.parent_id(top); if let hir::Node::Expr( hir::Expr { kind: hir::ExprKind::Binary(Spanned { node: hir::BinOpKind::And, .. }, lhs, rhs), @@ -1054,7 +1054,7 @@ pub enum LetSource { fn let_source(tcx: TyCtxt<'_>, pat_id: HirId) -> LetSource { let hir = tcx.hir(); - let parent = hir.get_parent_node(pat_id); + let parent = hir.parent_id(pat_id); let_source_parent(tcx, parent, Some(pat_id)) } @@ -1073,7 +1073,7 @@ fn let_source_parent(tcx: TyCtxt<'_>, parent: HirId, pat_id: Option<HirId>) -> L _ => {} } - let parent_parent = hir.get_parent_node(parent); + let parent_parent = hir.parent_id(parent); let parent_parent_node = hir.get(parent_parent); match parent_parent_node { hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), .. }) => { @@ -1085,8 +1085,8 @@ fn let_source_parent(tcx: TyCtxt<'_>, parent: HirId, pat_id: Option<HirId>) -> L _ => {} } - let parent_parent_parent = hir.get_parent_node(parent_parent); - let parent_parent_parent_parent = hir.get_parent_node(parent_parent_parent); + let parent_parent_parent = hir.parent_id(parent_parent); + let parent_parent_parent_parent = hir.parent_id(parent_parent_parent); let parent_parent_parent_parent_node = hir.get(parent_parent_parent_parent); if let hir::Node::Expr(hir::Expr { diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 7e1f708b0d6..6470efab2e9 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -70,7 +70,7 @@ mod fallback_to_const_ref { /// hoops to get a reference to the value. pub(super) struct FallbackToConstRef(()); - pub(super) fn fallback_to_const_ref<'tcx>(c2p: &super::ConstToPat<'tcx>) -> FallbackToConstRef { + pub(super) fn fallback_to_const_ref(c2p: &super::ConstToPat<'_>) -> FallbackToConstRef { assert!(c2p.behind_reference.get()); FallbackToConstRef(()) } diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 18e9c69c487..a95349d7670 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -404,7 +404,7 @@ impl SplitIntRange { } /// Iterate over the contained ranges. - fn iter<'a>(&'a self) -> impl Iterator<Item = IntRange> + Captures<'a> { + fn iter(&self) -> impl Iterator<Item = IntRange> + Captures<'_> { use IntBorder::*; let self_range = Self::to_borders(self.range.clone()); @@ -612,7 +612,7 @@ impl SplitVarLenSlice { } /// Iterate over the partition of this slice. - fn iter<'a>(&'a self) -> impl Iterator<Item = Slice> + Captures<'a> { + fn iter(&self) -> impl Iterator<Item = Slice> + Captures<'_> { let smaller_lengths = match self.array_len { // The only admissible fixed-length slice is one of the array size. Whether `max_slice` // is fixed-length or variable-length, it will be the only relevant slice to output |
