about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaul Daniel Faria <Nashenas88@users.noreply.github.com>2019-11-21 10:50:52 -0500
committerPaul Daniel Faria <Nashenas88@users.noreply.github.com>2019-12-02 08:42:24 -0500
commit64654ce1f171faad7461db90435bffefe0390151 (patch)
tree5dfde746d1b0388b22c97c187507a015ef495ffc
parent598797c6e76c041b449a838d09f1c829b0adc437 (diff)
downloadrust-64654ce1f171faad7461db90435bffefe0390151.tar.gz
rust-64654ce1f171faad7461db90435bffefe0390151.zip
Fix type errors created during rebasing
-rw-r--r--src/librustc/mir/cache.rs9
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs48
-rw-r--r--src/librustc_mir/transform/check_consts/mod.rs4
-rw-r--r--src/librustc_mir/transform/check_consts/qualifs.rs6
-rw-r--r--src/librustc_mir/transform/check_consts/resolver.rs2
-rw-r--r--src/librustc_mir/transform/check_consts/validation.rs28
-rw-r--r--src/librustc_mir/transform/mod.rs2
-rw-r--r--src/librustc_mir/transform/promote_consts.rs38
8 files changed, 67 insertions, 70 deletions
diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs
index 30f383ff331..f61b7e74d34 100644
--- a/src/librustc/mir/cache.rs
+++ b/src/librustc/mir/cache.rs
@@ -114,7 +114,7 @@ impl Cache {
     }
 }
 
-#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
+#[derive(Clone, Debug, RustcEncodable, RustcDecodable, TypeFoldable)]
 pub struct BodyCache<'tcx> {
     cache: Cache,
     body: Body<'tcx>,
@@ -302,10 +302,3 @@ impl_stable_hash_for!(struct BodyCache<'tcx> {
     cache,
     body,
 });
-
-BraceStructTypeFoldableImpl! {
-    impl<'tcx> TypeFoldable<'tcx> for BodyCache<'tcx> {
-        cache,
-        body
-    }
-}
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 5a8fd3f707d..3fcc6e9e176 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -220,7 +220,7 @@ fn type_check_internal<'a, 'tcx, R>(
 
     if !errors_reported {
         // if verifier failed, don't do further checks to avoid ICEs
-        checker.typeck_mir(&body);
+        checker.typeck_mir(body);
     }
 
     extra(&mut checker)
@@ -588,7 +588,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
 
         if !self.errors_reported {
             // if verifier failed, don't do further checks to avoid ICEs
-            self.cx.typeck_mir(&promoted_body);
+            self.cx.typeck_mir(promoted_body);
         }
 
         self.body = parent_body;
@@ -1374,7 +1374,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         self.infcx.tcx
     }
 
-    fn check_stmt(&mut self, body: &Body<'tcx>, stmt: &Statement<'tcx>, location: Location) {
+    fn check_stmt(&mut self, body: ReadOnlyBodyCache<'_, 'tcx>, stmt: &Statement<'tcx>, location: Location) {
         debug!("check_stmt: {:?}", stmt);
         let tcx = self.tcx();
         match stmt.kind {
@@ -1406,9 +1406,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     _ => ConstraintCategory::Assignment,
                 };
 
-                let place_ty = place.ty(body, tcx).ty;
+                let place_ty = place.ty(body.body(), tcx).ty;
                 let place_ty = self.normalize(place_ty, location);
-                let rv_ty = rv.ty(body, tcx);
+                let rv_ty = rv.ty(body.body(), tcx);
                 let rv_ty = self.normalize(rv_ty, location);
                 if let Err(terr) =
                     self.sub_types_or_anon(rv_ty, place_ty, location.to_locations(), category)
@@ -1460,7 +1460,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 ref place,
                 variant_index,
             } => {
-                let place_type = place.ty(body, tcx).ty;
+                let place_type = place.ty(body.body(), tcx).ty;
                 let adt = match place_type.kind {
                     ty::Adt(adt, _) if adt.is_enum() => adt,
                     _ => {
@@ -1482,7 +1482,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 };
             }
             StatementKind::AscribeUserType(box(ref place, ref projection), variance) => {
-                let place_ty = place.ty(body, tcx).ty;
+                let place_ty = place.ty(body.body(), tcx).ty;
                 if let Err(terr) = self.relate_type_and_user_type(
                     place_ty,
                     variance,
@@ -1985,12 +1985,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         }
     }
 
-    fn check_rvalue(&mut self, body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
+    fn check_rvalue(&mut self, body: ReadOnlyBodyCache<'_, 'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
         let tcx = self.tcx();
 
         match rvalue {
             Rvalue::Aggregate(ak, ops) => {
-                self.check_aggregate_rvalue(body, rvalue, ak, ops, location)
+                self.check_aggregate_rvalue(&body, rvalue, ak, ops, location)
             }
 
             Rvalue::Repeat(operand, len) => if *len > 1 {
@@ -1998,7 +1998,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     // While this is located in `nll::typeck` this error is not an NLL error, it's
                     // a required check to make sure that repeated elements implement `Copy`.
                     let span = body.source_info(location).span;
-                    let ty = operand.ty(body, tcx);
+                    let ty = operand.ty(body.body(), tcx);
                     if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty, span) {
                         // To determine if `const_in_array_repeat_expressions` feature gate should
                         // be mentioned, need to check if the rvalue is promotable.
@@ -2052,7 +2052,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             Rvalue::Cast(cast_kind, op, ty) => {
                 match cast_kind {
                     CastKind::Pointer(PointerCast::ReifyFnPointer) => {
-                        let fn_sig = op.ty(body, tcx).fn_sig(tcx);
+                        let fn_sig = op.ty(body.body(), tcx).fn_sig(tcx);
 
                         // The type that we see in the fcx is like
                         // `foo::<'a, 'b>`, where `foo` is the path to a
@@ -2081,7 +2081,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     }
 
                     CastKind::Pointer(PointerCast::ClosureFnPointer(unsafety)) => {
-                        let sig = match op.ty(body, tcx).kind {
+                        let sig = match op.ty(body.body(), tcx).kind {
                             ty::Closure(def_id, substs) => {
                                 substs.as_closure().sig_ty(def_id, tcx).fn_sig(tcx)
                             }
@@ -2107,7 +2107,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     }
 
                     CastKind::Pointer(PointerCast::UnsafeFnPointer) => {
-                        let fn_sig = op.ty(body, tcx).fn_sig(tcx);
+                        let fn_sig = op.ty(body.body(), tcx).fn_sig(tcx);
 
                         // The type that we see in the fcx is like
                         // `foo::<'a, 'b>`, where `foo` is the path to a
@@ -2139,7 +2139,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         let &ty = ty;
                         let trait_ref = ty::TraitRef {
                             def_id: tcx.lang_items().coerce_unsized_trait().unwrap(),
-                            substs: tcx.mk_substs_trait(op.ty(body, tcx), &[ty.into()]),
+                            substs: tcx.mk_substs_trait(op.ty(body.body(), tcx), &[ty.into()]),
                         };
 
                         self.prove_trait_ref(
@@ -2150,7 +2150,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     }
 
                     CastKind::Pointer(PointerCast::MutToConstPointer) => {
-                        let ty_from = match op.ty(body, tcx).kind {
+                        let ty_from = match op.ty(body.body(), tcx).kind {
                             ty::RawPtr(ty::TypeAndMut {
                                 ty: ty_from,
                                 mutbl: hir::Mutability::Mutable,
@@ -2198,7 +2198,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     }
 
                     CastKind::Pointer(PointerCast::ArrayToPointer)  => {
-                        let ty_from = op.ty(body, tcx);
+                        let ty_from = op.ty(body.body(), tcx);
 
                         let opt_ty_elem = match ty_from.kind {
                             ty::RawPtr(
@@ -2260,7 +2260,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     }
 
                     CastKind::Misc => {
-                        let ty_from = op.ty(body, tcx);
+                        let ty_from = op.ty(body.body(), tcx);
                         let cast_ty_from = CastTy::from_ty(ty_from);
                         let cast_ty_to = CastTy::from_ty(ty);
                         match (cast_ty_from, cast_ty_to) {
@@ -2318,7 +2318,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             }
 
             Rvalue::Ref(region, _borrow_kind, borrowed_place) => {
-                self.add_reborrow_constraint(body, location, region, borrowed_place);
+                self.add_reborrow_constraint(&body, location, region, borrowed_place);
             }
 
             Rvalue::BinaryOp(BinOp::Eq, left, right)
@@ -2327,9 +2327,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             | Rvalue::BinaryOp(BinOp::Le, left, right)
             | Rvalue::BinaryOp(BinOp::Gt, left, right)
             | Rvalue::BinaryOp(BinOp::Ge, left, right) => {
-                let ty_left = left.ty(body, tcx);
+                let ty_left = left.ty(body.body(), tcx);
                 if let ty::RawPtr(_) | ty::FnPtr(_) = ty_left.kind {
-                    let ty_right = right.ty(body, tcx);
+                    let ty_right = right.ty(body.body(), tcx);
                     let common_ty = self.infcx.next_ty_var(
                         TypeVariableOrigin {
                             kind: TypeVariableOriginKind::MiscVariable,
@@ -2754,12 +2754,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
         })
     }
 
-    fn typeck_mir(&mut self, body: &Body<'tcx>) {
+    fn typeck_mir(&mut self, body: ReadOnlyBodyCache<'_, 'tcx>) {
         self.last_span = body.span;
         debug!("run_on_mir: {:?}", body.span);
 
         for (local, local_decl) in body.local_decls.iter_enumerated() {
-            self.check_local(body, local, local_decl);
+            self.check_local(&body, local, local_decl);
         }
 
         for (block, block_data) in body.basic_blocks().iter_enumerated() {
@@ -2775,8 +2775,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 location.statement_index += 1;
             }
 
-            self.check_terminator(body, block_data.terminator(), location);
-            self.check_iscleanup(body, block_data);
+            self.check_terminator(&body, block_data.terminator(), location);
+            self.check_iscleanup(&body, block_data);
         }
     }
 
diff --git a/src/librustc_mir/transform/check_consts/mod.rs b/src/librustc_mir/transform/check_consts/mod.rs
index 4d00aaf7abc..7095b3fa0aa 100644
--- a/src/librustc_mir/transform/check_consts/mod.rs
+++ b/src/librustc_mir/transform/check_consts/mod.rs
@@ -20,7 +20,7 @@ pub mod validation;
 /// Information about the item currently being const-checked, as well as a reference to the global
 /// context.
 pub struct Item<'mir, 'tcx> {
-    pub body: &'mir mir::Body<'tcx>,
+    pub body: mir::ReadOnlyBodyCache<'mir, 'tcx>,
     pub tcx: TyCtxt<'tcx>,
     pub def_id: DefId,
     pub param_env: ty::ParamEnv<'tcx>,
@@ -31,7 +31,7 @@ impl Item<'mir, 'tcx> {
     pub fn new(
         tcx: TyCtxt<'tcx>,
         def_id: DefId,
-        body: &'mir mir::Body<'tcx>,
+        body: mir::ReadOnlyBodyCache<'mir, 'tcx>,
     ) -> Self {
         let param_env = tcx.param_env(def_id);
         let const_kind = ConstKind::for_item(tcx, def_id);
diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs
index 2d5a0a2afcd..718988b26d8 100644
--- a/src/librustc_mir/transform/check_consts/qualifs.rs
+++ b/src/librustc_mir/transform/check_consts/qualifs.rs
@@ -51,7 +51,7 @@ pub trait Qualif {
             });
             let qualif = base_qualif && Self::in_any_value_of_ty(
                 cx,
-                Place::ty_from(place.base, proj_base, cx.body, cx.tcx)
+                Place::ty_from(place.base, proj_base, cx.body.body(), cx.tcx)
                     .projection_ty(cx.tcx, elem)
                     .ty,
             );
@@ -155,7 +155,7 @@ pub trait Qualif {
                 // Special-case reborrows to be more like a copy of the reference.
                 if let &[ref proj_base @ .., elem] = place.projection.as_ref() {
                     if ProjectionElem::Deref == elem {
-                        let base_ty = Place::ty_from(&place.base, proj_base, cx.body, cx.tcx).ty;
+                        let base_ty = Place::ty_from(&place.base, proj_base, cx.body.body(), cx.tcx).ty;
                         if let ty::Ref(..) = base_ty.kind {
                             return Self::in_place(cx, per_local, PlaceRef {
                                 base: &place.base,
@@ -221,7 +221,7 @@ impl Qualif for HasMutInterior {
             Rvalue::Aggregate(ref kind, _) => {
                 if let AggregateKind::Adt(def, ..) = **kind {
                     if Some(def.did) == cx.tcx.lang_items().unsafe_cell_type() {
-                        let ty = rvalue.ty(cx.body, cx.tcx);
+                        let ty = rvalue.ty(cx.body.body(), cx.tcx);
                         assert_eq!(Self::in_any_value_of_ty(cx, ty), true);
                         return true;
                     }
diff --git a/src/librustc_mir/transform/check_consts/resolver.rs b/src/librustc_mir/transform/check_consts/resolver.rs
index 8909ef7db68..7db649e6ba0 100644
--- a/src/librustc_mir/transform/check_consts/resolver.rs
+++ b/src/librustc_mir/transform/check_consts/resolver.rs
@@ -77,7 +77,7 @@ where
         args: &[mir::Operand<'tcx>],
         return_place: &mir::Place<'tcx>,
     ) {
-        let return_ty = return_place.ty(self.item.body, self.item.tcx).ty;
+        let return_ty = return_place.ty(self.item.body.body(), self.item.tcx).ty;
         let qualif = Q::in_call(
             self.item,
             &|l| self.qualifs_per_local.contains(l),
diff --git a/src/librustc_mir/transform/check_consts/validation.rs b/src/librustc_mir/transform/check_consts/validation.rs
index 783c64ece73..63b100dc86d 100644
--- a/src/librustc_mir/transform/check_consts/validation.rs
+++ b/src/librustc_mir/transform/check_consts/validation.rs
@@ -39,9 +39,9 @@ impl<Q: Qualif> QualifCursor<'a, 'mir, 'tcx, Q> {
     ) -> Self {
         let analysis = FlowSensitiveAnalysis::new(q, item);
         let results =
-            dataflow::Engine::new(item.tcx, item.body, item.def_id, dead_unwinds, analysis)
+            dataflow::Engine::new(item.tcx, &item.body, item.def_id, dead_unwinds, analysis)
                 .iterate_to_fixpoint();
-        let cursor = dataflow::ResultsCursor::new(item.body, results);
+        let cursor = dataflow::ResultsCursor::new(item.body.body(), results);
 
         let mut in_any_value_of_ty = BitSet::new_empty(item.body.local_decls.len());
         for (local, decl) in item.body.local_decls.iter_enumerated() {
@@ -172,17 +172,17 @@ impl Validator<'a, 'mir, 'tcx> {
 
         let indirectly_mutable = old_dataflow::do_dataflow(
             item.tcx,
-            item.body,
+            item.body.body(),
             item.def_id,
             &item.tcx.get_attrs(item.def_id),
             &dead_unwinds,
-            old_dataflow::IndirectlyMutableLocals::new(item.tcx, item.body, item.param_env),
+            old_dataflow::IndirectlyMutableLocals::new(item.tcx, item.body.body(), item.param_env),
             |_, local| old_dataflow::DebugFormatted::new(&local),
         );
 
         let indirectly_mutable = old_dataflow::DataflowResultsCursor::new(
             indirectly_mutable,
-            item.body,
+            item.body.body(),
         );
 
         let qualifs = Qualifs {
@@ -208,7 +208,7 @@ impl Validator<'a, 'mir, 'tcx> {
         if use_min_const_fn_checks {
             // Enforce `min_const_fn` for stable `const fn`s.
             use crate::transform::qualify_min_const_fn::is_min_const_fn;
-            if let Err((span, err)) = is_min_const_fn(tcx, def_id, body) {
+            if let Err((span, err)) = is_min_const_fn(tcx, def_id, &body) {
                 error_min_const_fn_violation(tcx, span, err);
                 return;
             }
@@ -230,7 +230,7 @@ impl Validator<'a, 'mir, 'tcx> {
 
         if should_check_for_sync {
             let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
-            check_return_ty_is_sync(tcx, body, hir_id);
+            check_return_ty_is_sync(tcx, &body, hir_id);
         }
     }
 
@@ -304,7 +304,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
 
         // Special-case reborrows to be more like a copy of a reference.
         if let Rvalue::Ref(_, kind, ref place) = *rvalue {
-            if let Some(reborrowed_proj) = place_as_reborrow(self.tcx, self.body, place) {
+            if let Some(reborrowed_proj) = place_as_reborrow(self.tcx, self.body.body(), place) {
                 let ctx = match kind {
                     BorrowKind::Shared => PlaceContext::NonMutatingUse(
                         NonMutatingUseContext::SharedBorrow,
@@ -390,7 +390,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
             }
 
             Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) => {
-                let operand_ty = operand.ty(self.body, self.tcx);
+                let operand_ty = operand.ty(self.body.body(), self.tcx);
                 let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
                 let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
 
@@ -401,7 +401,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
             }
 
             Rvalue::BinaryOp(op, ref lhs, _) => {
-                if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.body, self.tcx).kind {
+                if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.body.body(), self.tcx).kind {
                     assert!(op == BinOp::Eq || op == BinOp::Ne ||
                             op == BinOp::Le || op == BinOp::Lt ||
                             op == BinOp::Ge || op == BinOp::Gt ||
@@ -475,7 +475,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
 
         match elem {
             ProjectionElem::Deref => {
-                let base_ty = Place::ty_from(place_base, proj_base, self.body, self.tcx).ty;
+                let base_ty = Place::ty_from(place_base, proj_base, self.body.body(), self.tcx).ty;
                 if let ty::RawPtr(_) = base_ty.kind {
                     if proj_base.is_empty() {
                         if let (PlaceBase::Local(local), []) = (place_base, proj_base) {
@@ -499,7 +499,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
             ProjectionElem::Subslice {..} |
             ProjectionElem::Field(..) |
             ProjectionElem::Index(_) => {
-                let base_ty = Place::ty_from(place_base, proj_base, self.body, self.tcx).ty;
+                let base_ty = Place::ty_from(place_base, proj_base, self.body.body(), self.tcx).ty;
                 match base_ty.ty_adt_def() {
                     Some(def) if def.is_union() => {
                         self.check_op(ops::UnionAccess);
@@ -548,7 +548,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
 
         match kind {
             TerminatorKind::Call { func, .. } => {
-                let fn_ty = func.ty(self.body, self.tcx);
+                let fn_ty = func.ty(self.body.body(), self.tcx);
 
                 let def_id = match fn_ty.kind {
                     ty::FnDef(def_id, _) => def_id,
@@ -609,7 +609,7 @@ impl Visitor<'tcx> for Validator<'_, 'mir, 'tcx> {
                 // Check to see if the type of this place can ever have a drop impl. If not, this
                 // `Drop` terminator is frivolous.
                 let ty_needs_drop = dropped_place
-                    .ty(self.body, self.tcx)
+                    .ty(self.body.body(), self.tcx)
                     .ty
                     .needs_drop(self.tcx, self.param_env);
 
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index 05d9787531b..3273588ec1a 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -205,7 +205,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> ConstQualifs {
     }
 
     let item = check_consts::Item {
-        body,
+        body: body.unwrap_read_only(),
         tcx,
         def_id,
         const_kind,
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 49ae759fd55..1a2eeb9025b 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -63,7 +63,7 @@ impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> {
         let mut rpo = traversal::reverse_postorder(body);
         let (temps, all_candidates) = collect_temps_and_candidates(tcx, body, &mut rpo);
 
-        let promotable_candidates = validate_candidates(tcx, body, def_id, &temps, &all_candidates);
+        let promotable_candidates = validate_candidates(tcx, read_only, def_id, &temps, &all_candidates);
 
         let promoted = promote_candidates(def_id, body, tcx, temps, promotable_candidates);
         self.promoted_fragments.set(promoted);
@@ -346,10 +346,14 @@ impl<'tcx> Validator<'_, 'tcx> {
                             while let [proj_base @ .., elem] = place_projection {
                                 // FIXME(eddyb) this is probably excessive, with
                                 // the exception of `union` member accesses.
-                                let ty =
-                                    Place::ty_from(&place.base, proj_base, self.body, self.tcx)
-                                        .projection_ty(self.tcx, elem)
-                                        .ty;
+                                let ty = Place::ty_from(
+                                        &place.base,
+                                        proj_base,
+                                        self.body.body(),
+                                        self.tcx
+                                    )
+                                    .projection_ty(self.tcx, elem)
+                                    .ty;
                                 if ty.is_freeze(self.tcx, self.param_env, DUMMY_SP) {
                                     has_mut_interior = false;
                                     break;
@@ -368,7 +372,7 @@ impl<'tcx> Validator<'_, 'tcx> {
                         }
 
                         if let BorrowKind::Mut { .. } = kind {
-                            let ty = place.ty(self.body, self.tcx).ty;
+                            let ty = place.ty(self.body.body(), self.tcx).ty;
 
                             // In theory, any zero-sized value could be borrowed
                             // mutably without consequences. However, only &mut []
@@ -517,7 +521,7 @@ impl<'tcx> Validator<'_, 'tcx> {
                     ProjectionElem::Field(..) => {
                         if self.const_kind.is_none() {
                             let base_ty =
-                                Place::ty_from(place.base, proj_base, self.body, self.tcx).ty;
+                                Place::ty_from(place.base, proj_base, self.body.body(), self.tcx).ty;
                             if let Some(def) = base_ty.ty_adt_def() {
                                 // No promotion of union field accesses.
                                 if def.is_union() {
@@ -566,7 +570,7 @@ impl<'tcx> Validator<'_, 'tcx> {
     fn validate_rvalue(&self, rvalue: &Rvalue<'tcx>) -> Result<(), Unpromotable> {
         match *rvalue {
             Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) if self.const_kind.is_none() => {
-                let operand_ty = operand.ty(self.body, self.tcx);
+                let operand_ty = operand.ty(self.body.body(), self.tcx);
                 let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
                 let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
                 match (cast_in, cast_out) {
@@ -580,7 +584,7 @@ impl<'tcx> Validator<'_, 'tcx> {
             }
 
             Rvalue::BinaryOp(op, ref lhs, _) if self.const_kind.is_none() => {
-                if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.body, self.tcx).kind {
+                if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.body.body(), self.tcx).kind {
                     assert!(op == BinOp::Eq || op == BinOp::Ne ||
                             op == BinOp::Le || op == BinOp::Lt ||
                             op == BinOp::Ge || op == BinOp::Gt ||
@@ -615,7 +619,7 @@ impl<'tcx> Validator<'_, 'tcx> {
 
             Rvalue::Ref(_, kind, place) => {
                 if let BorrowKind::Mut { .. } = kind {
-                    let ty = place.ty(self.body, self.tcx).ty;
+                    let ty = place.ty(self.body.body(), self.tcx).ty;
 
                     // In theory, any zero-sized value could be borrowed
                     // mutably without consequences. However, only &mut []
@@ -642,7 +646,7 @@ impl<'tcx> Validator<'_, 'tcx> {
                 let mut place = place.as_ref();
                 if let [proj_base @ .., ProjectionElem::Deref] = &place.projection {
                     let base_ty =
-                        Place::ty_from(&place.base, proj_base, self.body, self.tcx).ty;
+                        Place::ty_from(&place.base, proj_base, self.body.body(), self.tcx).ty;
                     if let ty::Ref(..) = base_ty.kind {
                         place = PlaceRef {
                             base: &place.base,
@@ -668,7 +672,7 @@ impl<'tcx> Validator<'_, 'tcx> {
                     while let [proj_base @ .., elem] = place_projection {
                         // FIXME(eddyb) this is probably excessive, with
                         // the exception of `union` member accesses.
-                        let ty = Place::ty_from(place.base, proj_base, self.body, self.tcx)
+                        let ty = Place::ty_from(place.base, proj_base, self.body.body(), self.tcx)
                             .projection_ty(self.tcx, elem)
                             .ty;
                         if ty.is_freeze(self.tcx, self.param_env, DUMMY_SP) {
@@ -701,7 +705,7 @@ impl<'tcx> Validator<'_, 'tcx> {
         callee: &Operand<'tcx>,
         args: &[Operand<'tcx>],
     ) -> Result<(), Unpromotable> {
-        let fn_ty = callee.ty(self.body, self.tcx);
+        let fn_ty = callee.ty(self.body.body(), self.tcx);
 
         if !self.explicit && self.const_kind.is_none() {
             if let ty::FnDef(def_id, _) = fn_ty.kind {
@@ -737,7 +741,7 @@ impl<'tcx> Validator<'_, 'tcx> {
 // FIXME(eddyb) remove the differences for promotability in `static`, `const`, `const fn`.
 pub fn validate_candidates(
     tcx: TyCtxt<'tcx>,
-    body: &Body<'tcx>,
+    body: ReadOnlyBodyCache<'_, 'tcx>,
     def_id: DefId,
     temps: &IndexVec<Local, TempState>,
     candidates: &[Candidate],
@@ -1146,11 +1150,11 @@ pub fn promote_candidates<'tcx>(
 crate fn should_suggest_const_in_array_repeat_expressions_attribute<'tcx>(
     tcx: TyCtxt<'tcx>,
     mir_def_id: DefId,
-    body: &Body<'tcx>,
+    body: ReadOnlyBodyCache<'_, 'tcx>,
     operand: &Operand<'tcx>,
 ) -> bool {
-    let mut rpo = traversal::reverse_postorder(body);
-    let (temps, _) = collect_temps_and_candidates(tcx, body, &mut rpo);
+    let mut rpo = traversal::reverse_postorder(&body);
+    let (temps, _) = collect_temps_and_candidates(tcx, &body, &mut rpo);
     let validator = Validator {
         item: Item::new(tcx, mir_def_id, body),
         temps: &temps,