about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSantiago Pastorino <spastorino@gmail.com>2019-10-20 21:04:59 -0400
committerSantiago Pastorino <spastorino@gmail.com>2019-10-22 10:33:36 -0300
commit180fc413fb1b10f5b172ae40bf50f7cee3d55b13 (patch)
tree4d0515c0080d656e8e59aa2212faaa4d1672358e
parentd32c2865d64e53cdd1b716b2b8966e4d1a4bfa38 (diff)
downloadrust-180fc413fb1b10f5b172ae40bf50f7cee3d55b13.tar.gz
rust-180fc413fb1b10f5b172ae40bf50f7cee3d55b13.zip
Move Place::elem methods and friends to TyCtxt
-rw-r--r--src/librustc/mir/mod.rs45
-rw-r--r--src/librustc/ty/context.rs44
-rw-r--r--src/librustc_mir/build/expr/as_rvalue.rs11
-rw-r--r--src/librustc_mir/build/expr/into.rs2
-rw-r--r--src/librustc_mir/build/matches/simplify.rs4
-rw-r--r--src/librustc_mir/build/matches/test.rs20
-rw-r--r--src/librustc_mir/build/matches/util.rs37
-rw-r--r--src/librustc_mir/dataflow/move_paths/builder.rs2
-rw-r--r--src/librustc_mir/shim.rs22
-rw-r--r--src/librustc_mir/transform/generator.rs2
-rw-r--r--src/librustc_mir/transform/inline.rs6
-rw-r--r--src/librustc_mir/util/aggregate.rs8
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs60
13 files changed, 139 insertions, 124 deletions
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 7db5dac3882..b2c26b6f0fe 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 3269591c745..2c17817f783 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<ExistentialPredicate<'tcx>> {
         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 916e919e399..4f1ac8e51dc 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 634b9c61ec6..e7388b92054 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 df97ad85748..9b7bccca2dd 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 125d9e5eeb5..5c2f72c0a06 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 c993dafe00e..917535f31dc 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<MatchPair<'pat, 'tcx>> {
-        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<MatchPair<'pat, 'tcx>> {
+        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 55da1e61f3c..52016d4c936 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 09c0b1ab7b9..177639956f7 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<Ty<'tcx>>)
                 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 51e4d34fb11..911901be36b 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 c92025812f9..5a34e3f471f 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 f972069b677..e6c3e4384d7 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 4eb35022b59..a1846a1fb5e 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<D::Path>)> = (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<D::Path>)> = (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 {