diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 7db5dac3882d2..b2c26b6f0fe6e 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -1857,51 +1857,6 @@ impl<'tcx> Place<'tcx> { } } - pub fn field(self, f: Field, ty: Ty<'tcx>, tcx: TyCtxt<'tcx>) -> Place<'tcx> { - self.elem(ProjectionElem::Field(f, ty), tcx) - } - - pub fn deref(self, tcx: TyCtxt<'tcx>) -> Place<'tcx> { - self.elem(ProjectionElem::Deref, tcx) - } - - pub fn downcast( - self, - adt_def: &'tcx AdtDef, - variant_index: VariantIdx, - tcx: TyCtxt<'tcx>, - ) -> Place<'tcx> { - self.elem( - ProjectionElem::Downcast( - Some(adt_def.variants[variant_index].ident.name), - variant_index, - ), - tcx, - ) - } - - pub fn downcast_unnamed(self, variant_index: VariantIdx, tcx: TyCtxt<'tcx>) -> Place<'tcx> { - self.elem(ProjectionElem::Downcast(None, variant_index), tcx) - } - - pub fn index(self, index: Local, tcx: TyCtxt<'tcx>) -> Place<'tcx> { - self.elem(ProjectionElem::Index(index), tcx) - } - - /// This method copies `Place`'s projection, add an element and reintern it. Should not be used - /// to build a full `Place` it's just a convenient way to grab a projection and modify it in - /// flight. - // FIXME: It may be a better idea to move all these methods to `PlaceBuilder` - pub fn elem(self, elem: PlaceElem<'tcx>, tcx: TyCtxt<'tcx>) -> Place<'tcx> { - let mut projection = self.projection.to_vec(); - projection.push(elem); - - Place { - base: self.base, - projection: tcx.intern_place_elems(&projection), - } - } - /// Returns `true` if this `Place` contains a `Deref` projection. /// /// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 3269591c7455b..2c17817f7833d 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -21,7 +21,7 @@ use crate::middle::cstore::EncodedMetadata; use crate::middle::lang_items; use crate::middle::resolve_lifetime::{self, ObjectLifetimeDefault}; use crate::middle::stability; -use crate::mir::{Body, interpret, PlaceElem, ProjectionKind, Promoted}; +use crate::mir::{Body, Field, interpret, Local, Place, PlaceElem, ProjectionKind, Promoted}; use crate::mir::interpret::{ConstValue, Allocation, Scalar}; use crate::ty::subst::{GenericArg, InternalSubsts, SubstsRef, Subst}; use crate::ty::ReprOptions; @@ -2597,6 +2597,48 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_ty(Opaque(def_id, substs)) } + pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> { + self.mk_place_elem(place, PlaceElem::Field(f, ty)) + } + + pub fn mk_place_deref(self, place: Place<'tcx>) -> Place<'tcx> { + self.mk_place_elem(place, PlaceElem::Deref) + } + + pub fn mk_place_downcast( + self, + place: Place<'tcx>, + adt_def: &'tcx AdtDef, + variant_index: VariantIdx, + ) -> Place<'tcx> { + self.mk_place_elem( + place, + PlaceElem::Downcast(Some(adt_def.variants[variant_index].ident.name), variant_index), + ) + } + + pub fn mk_place_downcast_unnamed( + self, + place: Place<'tcx>, + variant_index: VariantIdx, + ) -> Place<'tcx> { + self.mk_place_elem(place, PlaceElem::Downcast(None, variant_index)) + } + + pub fn mk_place_index(self, place: Place<'tcx>, index: Local) -> Place<'tcx> { + self.mk_place_elem(place, PlaceElem::Index(index)) + } + + /// This method copies `Place`'s projection, add an element and reintern it. Should not be used + /// to build a full `Place` it's just a convenient way to grab a projection and modify it in + /// flight. + pub fn mk_place_elem(self, place: Place<'tcx>, elem: PlaceElem<'tcx>) -> Place<'tcx> { + let mut projection = place.projection.to_vec(); + projection.push(elem); + + Place { base: place.base, projection: self.intern_place_elems(&projection) } + } + pub fn intern_existential_predicates(self, eps: &[ExistentialPredicate<'tcx>]) -> &'tcx List> { assert!(!eps.is_empty()); diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index 916e919e399eb..4f1ac8e51dc20 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -139,7 +139,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // initialize the box contents: unpack!( block = this.into( - &Place::from(result).deref(this.hir.tcx()), + &this.hir.tcx().mk_place_deref(Place::from(result)), block, value ) ); @@ -296,10 +296,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .zip(field_types.into_iter()) .map(|(n, ty)| match fields_map.get(&n) { Some(v) => v.clone(), - None => this.consume_by_copy_or_move(base.clone().field( + None => this.consume_by_copy_or_move(this.hir.tcx().mk_place_field( + base.clone(), n, ty, - this.hir.tcx(), )), }) .collect() @@ -402,8 +402,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let val_fld = Field::new(0); let of_fld = Field::new(1); - let val = result_value.clone().field(val_fld, ty, self.hir.tcx()); - let of = result_value.field(of_fld, bool_ty, self.hir.tcx()); + let tcx = self.hir.tcx(); + let val = tcx.mk_place_field(result_value.clone(), val_fld, ty); + let of = tcx.mk_place_field(result_value, of_fld, bool_ty); let err = PanicInfo::Overflow(op); diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 634b9c61ec691..e7388b920548b 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -235,7 +235,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }); let ptr_temp = Place::from(ptr_temp); let block = unpack!(this.into(&ptr_temp, block, ptr)); - this.into(&ptr_temp.deref(this.hir.tcx()), block, val) + this.into(&this.hir.tcx().mk_place_deref(ptr_temp), block, val) } else { let args: Vec<_> = args .into_iter() diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index df97ad8574812..9b7bccca2ddf3 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -166,7 +166,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } }); if irrefutable { - let place = match_pair.place.downcast(adt_def, variant_index, tcx); + let place = tcx.mk_place_downcast(match_pair.place, adt_def, variant_index); candidate.match_pairs.extend(self.field_match_pairs(place, subpatterns)); Ok(()) } else { @@ -191,7 +191,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } PatKind::Deref { ref subpattern } => { - let place = match_pair.place.deref(tcx); + let place = tcx.mk_place_deref(match_pair.place); candidate.match_pairs.push(MatchPair::new(place, subpattern)); Ok(()) } diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 125d9e5eeb539..5c2f72c0a061f 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -743,23 +743,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { candidate: &mut Candidate<'pat, 'tcx>, ) { let match_pair = candidate.match_pairs.remove(match_pair_index); + let tcx = self.hir.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.variants[variant_index].ident.name), variant_index); - let downcast_place = match_pair.place.elem(elem, self.hir.tcx()); // `(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, - self.hir.tcx()); - // e.g., `(x as Variant).0 @ P1` - MatchPair::new(place, &subpattern.pattern) - }); + let downcast_place = tcx.mk_place_elem(match_pair.place, elem); // `(x as Variant)` + let consequent_match_pairs = subpatterns.iter().map(|subpattern| { + // e.g., `(x as Variant).0` + let place = + tcx.mk_place_field(downcast_place.clone(), subpattern.field, subpattern.pattern.ty); + // e.g., `(x as Variant).0 @ P1` + MatchPair::new(place, &subpattern.pattern) + }); candidate.match_pairs.extend(consequent_match_pairs); } diff --git a/src/librustc_mir/build/matches/util.rs b/src/librustc_mir/build/matches/util.rs index c993dafe00e7c..917535f31dc4b 100644 --- a/src/librustc_mir/build/matches/util.rs +++ b/src/librustc_mir/build/matches/util.rs @@ -6,18 +6,22 @@ use std::u32; use std::convert::TryInto; impl<'a, 'tcx> Builder<'a, 'tcx> { - pub fn field_match_pairs<'pat>(&mut self, - place: Place<'tcx>, - subpatterns: &'pat [FieldPat<'tcx>]) - -> Vec> { - subpatterns.iter() - .map(|fieldpat| { - let place = place.clone().field(fieldpat.field, - fieldpat.pattern.ty, - self.hir.tcx()); - MatchPair::new(place, &fieldpat.pattern) - }) - .collect() + pub fn field_match_pairs<'pat>( + &mut self, + place: Place<'tcx>, + subpatterns: &'pat [FieldPat<'tcx>], + ) -> Vec> { + subpatterns + .iter() + .map(|fieldpat| { + let place = self.hir.tcx().mk_place_field( + place.clone(), + fieldpat.field, + fieldpat.pattern.ty, + ); + MatchPair::new(place, &fieldpat.pattern) + }) + .collect() } pub fn prefix_slice_suffix<'pat>(&mut self, @@ -28,6 +32,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { suffix: &'pat [Pat<'tcx>]) { let min_length = prefix.len() + suffix.len(); let min_length = min_length.try_into().unwrap(); + let tcx = self.hir.tcx(); match_pairs.extend( prefix.iter() @@ -38,16 +43,16 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { min_length, from_end: false, }; - let place = place.clone().elem(elem, self.hir.tcx()); + let place = tcx.mk_place_elem(place.clone(), elem); MatchPair::new(place, subpattern) }) ); if let Some(subslice_pat) = opt_slice { - let subslice = place.clone().elem(ProjectionElem::Subslice { + let subslice = tcx.mk_place_elem(place.clone(),ProjectionElem::Subslice { from: prefix.len() as u32, to: suffix.len() as u32 - }, self.hir.tcx()); + }); match_pairs.push(MatchPair::new(subslice, subslice_pat)); } @@ -61,7 +66,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { min_length, from_end: true, }; - let place = place.clone().elem(elem, self.hir.tcx()); + let place = tcx.mk_place_elem(place.clone(), elem); MatchPair::new(place, subpattern) }) ); diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index 55da1e61f3c9d..52016d4c9363a 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -274,7 +274,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { // Box starts out uninitialized - need to create a separate // move-path for the interior so it will be separate from // the exterior. - self.create_move_path(&place.clone().deref(self.builder.tcx)); + self.create_move_path(&self.builder.tcx.mk_place_deref(place.clone())); self.gather_init(place.as_ref(), InitKind::Shallow); } else { self.gather_init(place.as_ref(), InitKind::Deep); diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 09c0b1ab7b965..177639956f717 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -231,7 +231,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) tcx, param_env }; - let dropee = dropee_ptr.deref(tcx); + let dropee = tcx.mk_place_deref(dropee_ptr); let resume_block = elaborator.patch.resume_block(); elaborate_drops::elaborate_drop( &mut elaborator, @@ -312,7 +312,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) - let is_copy = self_ty.is_copy_modulo_regions(tcx, param_env, builder.span); let dest = Place::return_place(); - let src = Place::from(Local::new(1+0)).deref(tcx); + let src = tcx.mk_place_deref(Place::from(Local::new(1+0))); match self_ty.kind { _ if is_copy => builder.copy_shim(), @@ -415,7 +415,7 @@ impl CloneShimBuilder<'tcx> { } fn copy_shim(&mut self) { - let rcvr = Place::from(Local::new(1+0)).deref(self.tcx); + let rcvr = self.tcx.mk_place_deref(Place::from(Local::new(1+0))); let ret_statement = self.make_statement( StatementKind::Assign( box( @@ -561,8 +561,8 @@ impl CloneShimBuilder<'tcx> { // BB #2 // `dest[i] = Clone::clone(src[beg])`; // Goto #3 if ok, #5 if unwinding happens. - let dest_field = dest.clone().index(beg, self.tcx); - let src_field = src.index(beg, self.tcx); + let dest_field = self.tcx.mk_place_index(dest.clone(), beg); + let src_field = self.tcx.mk_place_index(src, beg); self.make_clone_call(dest_field, src_field, ty, BasicBlock::new(3), BasicBlock::new(5)); @@ -616,7 +616,7 @@ impl CloneShimBuilder<'tcx> { // BB #7 (cleanup) // `drop(dest[beg])`; self.block(vec![], TerminatorKind::Drop { - location: dest.index(beg, self.tcx), + location: self.tcx.mk_place_index(dest, beg), target: BasicBlock::new(8), unwind: None, }, true); @@ -648,9 +648,9 @@ impl CloneShimBuilder<'tcx> { let mut previous_field = None; for (i, ity) in tys.enumerate() { let field = Field::new(i); - let src_field = src.clone().field(field, ity, self.tcx); + let src_field = self.tcx.mk_place_field(src.clone(), field, ity); - let dest_field = dest.clone().field(field, ity, self.tcx); + let dest_field = self.tcx.mk_place_field(dest.clone(), field, ity); // #(2i + 1) is the cleanup block for the previous clone operation let cleanup_block = self.block_index_offset(1); @@ -721,14 +721,14 @@ fn build_call_shim<'tcx>( let rcvr = match rcvr_adjustment { Adjustment::Identity => Operand::Move(rcvr_l), - Adjustment::Deref => Operand::Copy(rcvr_l.deref(tcx)), + Adjustment::Deref => Operand::Copy(tcx.mk_place_deref(rcvr_l)), Adjustment::DerefMove => { // fn(Self, ...) -> fn(*mut Self, ...) let arg_ty = local_decls[rcvr_arg].ty; debug_assert!(tcx.generics_of(def_id).has_self && arg_ty == tcx.types.self_param); local_decls[rcvr_arg].ty = tcx.mk_mut_ptr(arg_ty); - Operand::Move(rcvr_l.deref(tcx)) + Operand::Move(tcx.mk_place_deref(rcvr_l)) } Adjustment::RefMut => { // let rcvr = &mut rcvr; @@ -772,7 +772,7 @@ fn build_call_shim<'tcx>( if let Some(untuple_args) = untuple_args { args.extend(untuple_args.iter().enumerate().map(|(i, ity)| { let arg_place = Place::from(Local::new(1+1)); - Operand::Move(arg_place.field(Field::new(i), *ity, tcx)) + Operand::Move(tcx.mk_place_field(arg_place, Field::new(i), *ity)) })); } else { args.extend((1..sig.inputs().len()).map(|i| { diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 51e4d34fb1174..911901be36b24 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -246,7 +246,7 @@ impl TransformVisitor<'tcx> { // Create a Place referencing a generator struct field fn make_field(&self, variant_index: VariantIdx, idx: usize, ty: Ty<'tcx>) -> Place<'tcx> { let self_place = Place::from(self_arg()); - let base = self_place.downcast_unnamed(variant_index, self.tcx); + let base = self.tcx.mk_place_downcast_unnamed(self_place, variant_index); let mut projection = base.projection.to_vec(); projection.push(ProjectionElem::Field(Field::new(idx), ty)); diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index c92025812f946..5a34e3f471f66 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -461,7 +461,7 @@ impl Inliner<'tcx> { }; caller_body[callsite.bb] .statements.push(stmt); - tmp.deref(self.tcx) + self.tcx.mk_place_deref(tmp) } else { destination.0 }; @@ -560,10 +560,10 @@ impl Inliner<'tcx> { let tuple_tmp_args = tuple_tys.iter().enumerate().map(|(i, ty)| { // This is e.g., `tuple_tmp.0` in our example above. - let tuple_field = Operand::Move(tuple.clone().field( + let tuple_field = Operand::Move(tcx.mk_place_field( + tuple.clone(), Field::new(i), ty.expect_ty(), - tcx, )); // Spill to a local to make e.g., `tmp0`. diff --git a/src/librustc_mir/util/aggregate.rs b/src/librustc_mir/util/aggregate.rs index f972069b677e5..e6c3e4384d7ae 100644 --- a/src/librustc_mir/util/aggregate.rs +++ b/src/librustc_mir/util/aggregate.rs @@ -30,7 +30,7 @@ pub fn expand_aggregate<'tcx>( }, source_info, }); - lhs = lhs.downcast(adt_def, variant_index, tcx); + lhs = tcx.mk_place_downcast(lhs, adt_def, variant_index); } active_field_index } @@ -59,15 +59,15 @@ pub fn expand_aggregate<'tcx>( // FIXME(eddyb) `offset` should be u64. let offset = i as u32; assert_eq!(offset as usize, i); - lhs.clone().elem(ProjectionElem::ConstantIndex { + tcx.mk_place_elem(lhs.clone(), ProjectionElem::ConstantIndex { offset, // FIXME(eddyb) `min_length` doesn't appear to be used. min_length: offset + 1, from_end: false - }, tcx) + }) } else { let field = Field::new(active_field_index.unwrap_or(i)); - lhs.clone().field(field, ty, tcx) + tcx.mk_place_field(lhs.clone(), field, ty) }; Statement { source_info, diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 4eb35022b59e1..a1846a1fb5eaf 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -200,13 +200,14 @@ where variant.fields.iter().enumerate().map(|(i, f)| { let field = Field::new(i); let subpath = self.elaborator.field_subpath(variant_path, field); + let tcx = self.tcx(); assert_eq!(self.elaborator.param_env().reveal, Reveal::All); - let field_ty = self.tcx().normalize_erasing_regions( + let field_ty = tcx.normalize_erasing_regions( self.elaborator.param_env(), - f.ty(self.tcx(), substs), + f.ty(tcx, substs), ); - (base_place.clone().field(field, field_ty, self.tcx()), subpath) + (tcx.mk_place_field(base_place.clone(), field, field_ty), subpath) }).collect() } @@ -323,7 +324,7 @@ where debug!("open_drop_for_tuple({:?}, {:?})", self, tys); let fields = tys.iter().enumerate().map(|(i, &ty)| { - (self.place.clone().field(Field::new(i), ty, self.tcx()), + (self.tcx().mk_place_field(self.place.clone(), Field::new(i), ty), self.elaborator.field_subpath(self.path, Field::new(i))) }).collect(); @@ -334,7 +335,7 @@ where fn open_drop_for_box(&mut self, adt: &'tcx ty::AdtDef, substs: SubstsRef<'tcx>) -> BasicBlock { debug!("open_drop_for_box({:?}, {:?}, {:?})", self, adt, substs); - let interior = self.place.clone().deref(self.tcx()); + let interior = self.tcx().mk_place_deref(self.place.clone()); let interior_path = self.elaborator.deref_subpath(self.path); let succ = self.succ; // FIXME(#43234) @@ -406,14 +407,19 @@ where }; let mut have_otherwise = false; + let tcx = self.tcx(); - for (variant_index, discr) in adt.discriminants(self.tcx()) { + for (variant_index, discr) in adt.discriminants(tcx) { let subpath = self.elaborator.downcast_subpath( self.path, variant_index); if let Some(variant_path) = subpath { - let base_place = self.place.clone().elem( - ProjectionElem::Downcast(Some(adt.variants[variant_index].ident.name), - variant_index), self.tcx()); + let base_place = tcx.mk_place_elem( + self.place.clone(), + ProjectionElem::Downcast( + Some(adt.variants[variant_index].ident.name), + variant_index, + ), + ); let fields = self.move_paths_for_fields( &base_place, variant_path, @@ -586,7 +592,7 @@ where BorrowKind::Mut { allow_two_phase_borrow: false }, Place { base: PlaceBase::Local(cur), - projection: self.tcx().intern_place_elems(&vec![ProjectionElem::Deref]), + projection: tcx.intern_place_elems(&vec![ProjectionElem::Deref]), } ), Rvalue::BinaryOp(BinOp::Offset, move_(&Place::from(cur)), one)) @@ -594,7 +600,7 @@ where (Rvalue::Ref( tcx.lifetimes.re_erased, BorrowKind::Mut { allow_two_phase_borrow: false }, - self.place.clone().index(cur, self.tcx())), + tcx.mk_place_index(self.place.clone(), cur)), Rvalue::BinaryOp(BinOp::Add, move_(&Place::from(cur)), one)) }; @@ -627,7 +633,7 @@ where let loop_block = self.elaborator.patch().new_block(loop_block); self.elaborator.patch().patch_terminator(drop_block, TerminatorKind::Drop { - location: ptr.clone().deref(tcx), + location: tcx.mk_place_deref(ptr.clone()), target: loop_block, unwind: unwind.into_option() }); @@ -644,18 +650,27 @@ where // ptr_based_loop // } + let tcx = self.tcx(); + if let Some(size) = opt_size { let size: u32 = size.try_into().unwrap_or_else(|_| { bug!("move out check isn't implemented for array sizes bigger than u32::MAX"); }); - let fields: Vec<(Place<'tcx>, Option)> = (0..size).map(|i| { - (self.place.clone().elem(ProjectionElem::ConstantIndex{ - offset: i, - min_length: size, - from_end: false - }, self.tcx()), - self.elaborator.array_subpath(self.path, i, size)) - }).collect(); + let fields: Vec<(Place<'tcx>, Option)> = (0..size) + .map(|i| { + ( + tcx.mk_place_elem( + self.place.clone(), + ProjectionElem::ConstantIndex { + offset: i, + min_length: size, + from_end: false, + }, + ), + self.elaborator.array_subpath(self.path, i, size), + ) + }) + .collect(); if fields.iter().any(|(_,path)| path.is_some()) { let (succ, unwind) = self.drop_ladder_bottom(); @@ -664,7 +679,6 @@ where } let move_ = |place: &Place<'tcx>| Operand::Move(place.clone()); - let tcx = self.tcx(); let elem_size = &Place::from(self.new_temp(tcx.types.usize)); let len = &Place::from(self.new_temp(tcx.types.usize)); @@ -900,8 +914,8 @@ where ); let args = adt.variants[VariantIdx::new(0)].fields.iter().enumerate().map(|(i, f)| { let field = Field::new(i); - let field_ty = f.ty(self.tcx(), substs); - Operand::Move(self.place.clone().field(field, field_ty, self.tcx())) + let field_ty = f.ty(tcx, substs); + Operand::Move(tcx.mk_place_field(self.place.clone(), field, field_ty)) }).collect(); let call = TerminatorKind::Call {