From fc6b58d0a809b4994cd1a633ccb04e89234ff0b8 Mon Sep 17 00:00:00 2001 From: Paul Daniel Faria Date: Sat, 26 Oct 2019 01:41:17 -0400 Subject: [PATCH] Simplify BodyCache impl and fix all remaining type errors in librustc_mir (lifetime errors still exist) --- src/librustc/arena.rs | 8 +- src/librustc/mir/cache.rs | 186 +++++++-------- src/librustc/mir/mod.rs | 4 +- src/librustc/mir/visit.rs | 4 +- src/librustc/query/mod.rs | 26 ++- src/librustc/ty/context.rs | 14 +- src/librustc/ty/mod.rs | 10 +- src/librustc_codegen_ssa/base.rs | 3 - src/librustc_codegen_ssa/mir/analyze.rs | 16 +- src/librustc_codegen_ssa/mir/block.rs | 58 ++--- src/librustc_codegen_ssa/mir/constant.rs | 2 +- src/librustc_codegen_ssa/mir/mod.rs | 17 +- src/librustc_codegen_ssa/mir/operand.rs | 2 +- src/librustc_codegen_ssa/mir/place.rs | 2 +- src/librustc_codegen_ssa/mir/rvalue.rs | 4 +- src/librustc_codegen_ssa/mir/statement.rs | 2 +- src/librustc_metadata/rmeta/decoder.rs | 7 +- src/librustc_metadata/rmeta/mod.rs | 4 +- src/librustc_mir/borrow_check/borrow_set.rs | 6 +- src/librustc_mir/borrow_check/mod.rs | 21 +- .../borrow_check/mutability_errors.rs | 4 +- .../borrow_check/nll/invalidation.rs | 4 +- src/librustc_mir/borrow_check/nll/mod.rs | 20 +- .../borrow_check/nll/region_infer/values.rs | 2 +- src/librustc_mir/borrow_check/nll/renumber.rs | 6 +- .../nll/type_check/liveness/local_use_map.rs | 2 +- .../nll/type_check/liveness/mod.rs | 4 +- .../nll/type_check/liveness/polonius.rs | 2 +- .../nll/type_check/liveness/trace.rs | 8 +- .../borrow_check/nll/type_check/mod.rs | 18 +- src/librustc_mir/borrow_check/used_muts.rs | 2 +- src/librustc_mir/build/mod.rs | 4 +- src/librustc_mir/const_eval.rs | 4 +- .../dataflow/impls/storage_liveness.rs | 8 +- src/librustc_mir/interpret/eval_context.rs | 6 +- src/librustc_mir/monomorphize/collector.rs | 8 +- src/librustc_mir/shim.rs | 25 +- src/librustc_mir/transform/add_call_guards.rs | 14 +- .../transform/add_moves_for_packed_drops.rs | 12 +- src/librustc_mir/transform/add_retag.rs | 6 +- src/librustc_mir/transform/check_unsafety.rs | 2 +- .../transform/cleanup_post_borrowck.rs | 6 +- src/librustc_mir/transform/const_prop.rs | 41 ++-- src/librustc_mir/transform/copy_prop.rs | 41 ++-- src/librustc_mir/transform/deaggregator.rs | 4 +- src/librustc_mir/transform/dump_mir.rs | 4 +- src/librustc_mir/transform/elaborate_drops.rs | 10 +- src/librustc_mir/transform/erase_regions.rs | 4 +- src/librustc_mir/transform/generator.rs | 215 +++++++++--------- src/librustc_mir/transform/inline.rs | 46 ++-- src/librustc_mir/transform/instcombine.rs | 11 +- src/librustc_mir/transform/mod.rs | 42 ++-- src/librustc_mir/transform/no_landing_pads.rs | 6 +- src/librustc_mir/transform/promote_consts.rs | 67 +++--- .../transform/remove_noop_landing_pads.rs | 26 +-- src/librustc_mir/transform/rustc_peek.rs | 32 +-- src/librustc_mir/transform/simplify.rs | 46 ++-- .../transform/simplify_branches.rs | 4 +- .../transform/uniform_array_move_out.rs | 26 +-- src/librustc_mir/util/collect_writes.rs | 2 +- src/librustc_mir/util/def_use.rs | 6 +- src/librustc_mir/util/liveness.rs | 4 +- src/librustc_mir/util/patch.rs | 2 +- 63 files changed, 589 insertions(+), 613 deletions(-) diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index 1d6a3420ed95..364a35f1b6fa 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -23,17 +23,17 @@ macro_rules! arena_types { [] generics: rustc::ty::Generics, [] trait_def: rustc::ty::TraitDef, [] adt_def: rustc::ty::AdtDef, - [] steal_mir: rustc::ty::steal::Steal>, - [] mir: rustc::mir::Body<$tcx>, + [] steal_mir: rustc::ty::steal::Steal>, + [] mir: rustc::mir::BodyCache<$tcx>, [] steal_promoted: rustc::ty::steal::Steal< rustc_index::vec::IndexVec< rustc::mir::Promoted, - rustc::mir::Body<$tcx> + rustc::mir::BodyCache<$tcx> > >, [] promoted: rustc_index::vec::IndexVec< rustc::mir::Promoted, - rustc::mir::Body<$tcx> + rustc::mir::BodyCache<$tcx> >, [] tables: rustc::ty::TypeckTables<$tcx>, [] const_allocs: rustc::mir::interpret::Allocation, diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs index b66824706064..8958a31b51cb 100644 --- a/src/librustc/mir/cache.rs +++ b/src/librustc/mir/cache.rs @@ -1,7 +1,7 @@ use rustc_index::vec::IndexVec; -//use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -//use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; -//use crate::ich::StableHashingContext; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; +use rustc_serialize::{Encodable, Encoder, Decodable, Decoder}; +use crate::ich::StableHashingContext; use crate::mir::{BasicBlock, BasicBlockData, Body, LocalDecls, Location, Successors}; use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors}; use rustc_data_structures::graph::dominators::{dominators, Dominators}; @@ -14,23 +14,23 @@ pub struct Cache { predecessors: Option>>, } -//impl<'tcx, T> rustc_serialize::Encodable for Cache<'tcx, T> { -// fn encode(&self, s: &mut S) -> Result<(), S::Error> { -// Encodable::encode(&(), s) -// } -//} -// -//impl<'tcx, T> rustc_serialize::Decodable for Cache<'tcx, T> { -// fn decode(d: &mut D) -> Result { -// Decodable::decode(d).map(|_v: ()| Self::new()) -// } -//} -// -//impl<'a, 'tcx, T> HashStable> for Cache<'tcx, T> { -// fn hash_stable(&self, _: &mut StableHashingContext<'a>, _: &mut StableHasher) { -// // Do nothing. -// } -//} +impl rustc_serialize::Encodable for Cache { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + Encodable::encode(&(), s) + } +} + +impl rustc_serialize::Decodable for Cache { + fn decode(d: &mut D) -> Result { + Decodable::decode(d).map(|_v: ()| Self::new()) + } +} + +impl<'a> HashStable> for Cache { + fn hash_stable(&self, _: &mut StableHashingContext<'a>, _: &mut StableHasher) { + // Do nothing. + } +} macro_rules! get_predecessors { (mut $self:ident, $block:expr, $body:expr) => { @@ -98,13 +98,13 @@ impl Cache { #[inline] /// This will recompute the predecessors cache if it is not available - pub fn predecessors(&mut self, body: &Body<'_>) -> &IndexVec> { + fn predecessors(&mut self, body: &Body<'_>) -> &IndexVec> { self.ensure_predecessors(body); self.predecessors.as_ref().unwrap() } #[inline] - pub fn predecessors_for(&mut self, bb: BasicBlock, body: &Body<'_>) -> &[BasicBlock] { + fn predecessors_for(&mut self, bb: BasicBlock, body: &Body<'_>) -> &[BasicBlock] { &self.predecessors(body)[bb] } @@ -136,109 +136,58 @@ impl Cache { } } -pub struct BodyCache { +#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] +pub struct BodyCache<'tcx> { cache: Cache, - body: T, + body: Body<'tcx>, } -impl BodyCache { - pub fn new(body: T) -> Self { +impl BodyCache<'tcx> { + pub fn new(body: Body<'tcx>) -> Self { Self { cache: Cache::new(), - body + body, } } } -impl<'a, 'tcx> BodyCache<&'a Body<'tcx>> { - #[inline] - pub fn predecessors_for(&mut self, bb: BasicBlock) -> &[BasicBlock] { - self.cache.predecessors_for(bb, self.body) +impl BodyCache<'tcx> { + pub fn ensure_predecessors(&mut self) { + self.cache.ensure_predecessors(&self.body); } - #[inline] - pub fn body(&self) -> &'a Body<'tcx> { - self.body + pub fn predecessors(&mut self) -> &IndexVec> { + self.cache.predecessors(&self.body) } - #[inline] - pub fn read_only(mut self) -> ReadOnlyBodyCache<'a, 'tcx> { - self.cache.ensure_predecessors(self.body); + pub fn read_only(&self) -> ReadOnlyBodyCache<'_, '_> { + assert!(self.cache.predecessors.is_some(), ""); ReadOnlyBodyCache { - cache: self.cache, - body: self.body, + cache: &self.cache, + body: &self.body, } } - #[inline] - pub fn basic_blocks(&self) -> &IndexVec> { - &self.body.basic_blocks - } -} - -impl<'a, 'tcx> Deref for BodyCache<&'a Body<'tcx>> { - type Target = Body<'tcx>; - - fn deref(&self) -> &Self::Target { - self.body - } -} - -impl<'a, 'tcx> Index for BodyCache<&'a Body<'tcx>> { - type Output = BasicBlockData<'tcx>; - - #[inline] - fn index(&self, index: BasicBlock) -> &BasicBlockData<'tcx> { - &self.body[index] - } -} - -impl<'a, 'tcx> BodyCache<&'a mut Body<'tcx>> { - #[inline] pub fn body(&self) -> &Body<'tcx> { - self.body + &self.body } - #[inline] pub fn body_mut(&mut self) -> &mut Body<'tcx> { - self.body + &mut self.body } - #[inline] - pub fn read_only(mut self) -> ReadOnlyBodyCache<'a, 'tcx> { - self.cache.ensure_predecessors(self.body); - ReadOnlyBodyCache { - cache: self.cache, - body: self.body, - } - } - - #[inline] - pub fn basic_blocks(&self) -> &IndexVec> { - &self.body.basic_blocks - } - - #[inline] pub fn basic_blocks_mut(&mut self) -> &mut IndexVec> { self.cache.basic_blocks_mut(&mut self.body) } -} -impl<'a, 'tcx> Deref for BodyCache<&'a mut Body<'tcx>> { - type Target = Body<'tcx>; - - fn deref(&self) -> &Self::Target { - self.body + pub fn basic_blocks_and_local_decls_mut( + &mut self + ) -> (&mut IndexVec>, &mut LocalDecls<'tcx>) { + self.cache.basic_blocks_and_local_decls_mut(&mut self.body) } } -impl<'a, 'tcx> DerefMut for BodyCache<&'a mut Body<'tcx>> { - fn deref_mut(&mut self) -> &mut Body<'tcx> { - self.body - } -} - -impl<'a, 'tcx> Index for BodyCache<&'a mut Body<'tcx>> { +impl<'tcx> Index for BodyCache<'tcx> { type Output = BasicBlockData<'tcx>; #[inline] @@ -247,15 +196,29 @@ impl<'a, 'tcx> Index for BodyCache<&'a mut Body<'tcx>> { } } -impl<'a, 'tcx> IndexMut for BodyCache<&'a mut Body<'tcx>> { +impl<'tcx> IndexMut for BodyCache<'tcx> { fn index_mut(&mut self, index: BasicBlock) -> &mut Self::Output { - self.cache.invalidate_predecessors(); - &mut self.body.basic_blocks[index] + &mut self.basic_blocks_mut()[index] } } +impl<'tcx> Deref for BodyCache<'tcx> { + type Target = Body<'tcx>; + + fn deref(&self) -> &Self::Target { + &self.body + } +} + +impl<'tcx> DerefMut for BodyCache<'tcx> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.body + } +} + +#[derive(Copy, Clone, Debug)] pub struct ReadOnlyBodyCache<'a, 'tcx> { - cache: Cache, + cache: &'a Cache, body: &'a Body<'tcx>, } @@ -289,13 +252,6 @@ impl ReadOnlyBodyCache<'a, 'tcx> { pub fn dominators(&self) -> Dominators { dominators(self) } - - pub fn to_owned(self) -> BodyCache<&'a Body<'tcx>> { - BodyCache { - cache: self.cache, - body: self.body, - } - } } impl graph::DirectedGraph for ReadOnlyBodyCache<'a, 'tcx> { @@ -358,4 +314,20 @@ impl Index for ReadOnlyBodyCache<'a, 'tcx> { fn index(&self, index: BasicBlock) -> &BasicBlockData<'tcx> { &self.body[index] } -} \ No newline at end of file +} + +CloneTypeFoldableAndLiftImpls! { + Cache, +} + +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/mod.rs b/src/librustc/mir/mod.rs index 57d396ae9330..b6d1c78cc4f5 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -107,7 +107,7 @@ pub struct Body<'tcx> { pub yield_ty: Option>, /// Generator drop glue. - pub generator_drop: Option>>, + pub generator_drop: Option>>, /// The layout of a generator. Produced by the state transformation. pub generator_layout: Option>, @@ -2600,7 +2600,7 @@ impl Location { pub fn is_predecessor_of<'tcx>( &self, other: Location, - body_cache: &ReadOnlyBodyCache<'_, 'tcx> + body_cache: ReadOnlyBodyCache<'_, 'tcx> ) -> bool { // If we are in the same block as the other location and are an earlier statement // then we are a predecessor of `other`. diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index c464247c4b4c..68694f1b7171 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -67,10 +67,10 @@ use syntax_pos::Span; macro_rules! body_cache_type { (mut $a:lifetime, $tcx:lifetime) => { - &mut BodyCache<& $a mut Body<$tcx>> + &mut BodyCache<$tcx> }; ($a:lifetime, $tcx:lifetime) => { - &ReadOnlyBodyCache<$a, $tcx> + ReadOnlyBodyCache<$a, $tcx> }; } diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index d715ddb1b81d..cdfdcee5823e 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -106,42 +106,46 @@ rustc_queries! { /// Fetch the MIR for a given `DefId` right after it's built - this includes /// unreachable code. - query mir_built(_: DefId) -> &'tcx Steal> {} + query mir_built(_: DefId) -> &'tcx Steal> {} /// Fetch the MIR for a given `DefId` up till the point where it is /// ready for const evaluation. /// /// See the README for the `mir` module for details. - query mir_const(_: DefId) -> &'tcx Steal> { + query mir_const(_: DefId) -> &'tcx Steal> { no_hash } query mir_validated(_: DefId) -> ( - &'tcx Steal>, - &'tcx Steal>> + &'tcx Steal>, + &'tcx Steal>> ) { no_hash } /// MIR after our optimization passes have run. This is MIR that is ready /// for codegen. This is also the only query that can fetch non-local MIR, at present. - query optimized_mir(key: DefId) -> &'tcx mir::Body<'tcx> { + query optimized_mir(key: DefId) -> &'tcx mir::BodyCache<'tcx> { cache_on_disk_if { key.is_local() } load_cached(tcx, id) { - let mir: Option> = tcx.queries.on_disk_cache - .try_load_query_result(tcx, id); - mir.map(|x| &*tcx.arena.alloc(x)) + let mir: Option> + = tcx.queries.on_disk_cache.try_load_query_result(tcx, id); + mir.map(|x| { + let cache = tcx.arena.alloc(x); + cache.ensure_predecessors(); + &*cache + }) } } - query promoted_mir(key: DefId) -> &'tcx IndexVec> { + query promoted_mir(key: DefId) -> &'tcx IndexVec> { cache_on_disk_if { key.is_local() } load_cached(tcx, id) { let promoted: Option< rustc_index::vec::IndexVec< crate::mir::Promoted, - crate::mir::Body<'tcx> + crate::mir::BodyCache<'tcx> >> = tcx.queries.on_disk_cache.try_load_query_result(tcx, id); promoted.map(|p| &*tcx.arena.alloc(p)) } @@ -502,7 +506,7 @@ rustc_queries! { /// in the case of closures, this will be redirected to the enclosing function. query region_scope_tree(_: DefId) -> &'tcx region::ScopeTree {} - query mir_shims(key: ty::InstanceDef<'tcx>) -> &'tcx mir::Body<'tcx> { + query mir_shims(key: ty::InstanceDef<'tcx>) -> &'tcx mir::BodyCache<'tcx> { no_force desc { |tcx| "generating MIR shim for `{}`", tcx.def_path_str(key.def_id()) } } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 776ae7dc141c..07d86a5f86a4 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -22,7 +22,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, Field, interpret, Local, Place, PlaceElem, ProjectionKind, Promoted}; +use crate::mir::{BodyCache, 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; @@ -1083,17 +1083,17 @@ impl<'tcx> TyCtxt<'tcx> { &self.hir_map } - pub fn alloc_steal_mir(self, mir: Body<'tcx>) -> &'tcx Steal> { - self.arena.alloc(Steal::new(mir)) + pub fn alloc_steal_mir(self, mir_cache: BodyCache<'tcx>) -> &'tcx Steal> { + self.arena.alloc(Steal::new(mir_cache)) } - pub fn alloc_steal_promoted(self, promoted: IndexVec>) -> - &'tcx Steal>> { + pub fn alloc_steal_promoted(self, promoted: IndexVec>) -> + &'tcx Steal>> { self.arena.alloc(Steal::new(promoted)) } - pub fn intern_promoted(self, promoted: IndexVec>) -> - &'tcx IndexVec> { + pub fn intern_promoted(self, promoted: IndexVec>) -> + &'tcx IndexVec> { self.arena.alloc(promoted) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 8ccfc467f4a0..f8feff0def97 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -18,7 +18,7 @@ use crate::infer::canonical::Canonical; use crate::middle::cstore::CrateStoreDyn; use crate::middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem}; use crate::middle::resolve_lifetime::ObjectLifetimeDefault; -use crate::mir::Body; +use crate::mir::ReadOnlyBodyCache; use crate::mir::interpret::{GlobalId, ErrorHandled}; use crate::mir::GeneratorLayout; use crate::session::CrateDisambiguator; @@ -2985,10 +2985,10 @@ impl<'tcx> TyCtxt<'tcx> { } /// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair. - pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> { + pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> ReadOnlyBodyCache<'tcx, 'tcx> { match instance { ty::InstanceDef::Item(did) => { - self.optimized_mir(did) + self.optimized_mir(did).read_only() } ty::InstanceDef::VtableShim(..) | ty::InstanceDef::ReifyShim(..) | @@ -2998,7 +2998,7 @@ impl<'tcx> TyCtxt<'tcx> { ty::InstanceDef::ClosureOnceShim { .. } | ty::InstanceDef::DropGlue(..) | ty::InstanceDef::CloneShim(..) => { - self.mir_shims(instance) + self.mir_shims(instance).read_only() } } } @@ -3023,7 +3023,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn generator_layout(self, def_id: DefId) -> &'tcx GeneratorLayout<'tcx> { - self.optimized_mir(def_id).generator_layout.as_ref().unwrap() + self.optimized_mir(def_id).body().generator_layout.as_ref().unwrap() } /// Given the `DefId` of an impl, returns the `DefId` of the trait it implements. diff --git a/src/librustc_codegen_ssa/base.rs b/src/librustc_codegen_ssa/base.rs index f50be08c15c1..e460a4a2e8c9 100644 --- a/src/librustc_codegen_ssa/base.rs +++ b/src/librustc_codegen_ssa/base.rs @@ -31,7 +31,6 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::middle::cstore::EncodedMetadata; use rustc::middle::lang_items::StartFnLangItem; use rustc::middle::weak_lang_items; -use rustc::mir::BodyCache; use rustc::mir::mono::{CodegenUnitNameBuilder, CodegenUnit, MonoItem}; use rustc::ty::{self, Ty, TyCtxt, Instance}; use rustc::ty::layout::{self, Align, TyLayout, LayoutOf, VariantIdx, HasTyCtxt}; @@ -375,8 +374,6 @@ pub fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>( let lldecl = cx.get_fn(instance); let mir = cx.tcx().instance_mir(instance.def); - // TODO(nashenas88) move this into instance_mir before merging PR - let mir = BodyCache::new(mir); mir::codegen_mir::(cx, lldecl, mir, instance, sig); } diff --git a/src/librustc_codegen_ssa/mir/analyze.rs b/src/librustc_codegen_ssa/mir/analyze.rs index fff011783410..830b7da8c037 100644 --- a/src/librustc_codegen_ssa/mir/analyze.rs +++ b/src/librustc_codegen_ssa/mir/analyze.rs @@ -16,8 +16,8 @@ use syntax_pos::DUMMY_SP; use super::FunctionCx; use crate::traits::*; -pub fn non_ssa_locals<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( - fx: &FunctionCx<'a, 'b, 'tcx, Bx> +pub fn non_ssa_locals<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( + fx: &FunctionCx<'a, 'tcx, Bx> ) -> BitSet { let mut analyzer = LocalAnalyzer::new(fx); @@ -56,8 +56,8 @@ pub fn non_ssa_locals<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( analyzer.non_ssa_locals } -struct LocalAnalyzer<'mir, 'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { - fx: &'mir FunctionCx<'a, 'b, 'tcx, Bx>, +struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { + fx: &'mir FunctionCx<'a, 'tcx, Bx>, dominators: Dominators, non_ssa_locals: BitSet, // The location of the first visited direct assignment to each @@ -65,8 +65,8 @@ struct LocalAnalyzer<'mir, 'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { first_assignment: IndexVec, } -impl<'mir, 'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'b, 'tcx, Bx> { - fn new(fx: &'mir FunctionCx<'a, 'b, 'tcx, Bx>) -> Self { +impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> { + fn new(fx: &'mir FunctionCx<'a, 'tcx, Bx>) -> Self { let invalid_location = mir::BasicBlock::new(fx.mir.basic_blocks().len()).start_location(); let dominators = fx.mir.dominators(); @@ -232,8 +232,8 @@ impl<'mir, 'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, ' } -impl<'mir, 'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> - for LocalAnalyzer<'mir, 'a, 'b, 'tcx, Bx> +impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx> + for LocalAnalyzer<'mir, 'a, 'tcx, Bx> { fn visit_assign(&mut self, place: &mir::Place<'tcx>, diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index e2cae0aa5651..f661e7bba806 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -33,19 +33,19 @@ struct TerminatorCodegenHelper<'a, 'tcx> { impl<'a, 'tcx> TerminatorCodegenHelper<'a, 'tcx> { /// Returns the associated funclet from `FunctionCx::funclets` for the /// `funclet_bb` member if it is not `None`. - fn funclet<'d, 'c, 'b, Bx: BuilderMethods<'b, 'tcx>>( + fn funclet<'c, 'b, Bx: BuilderMethods<'b, 'tcx>>( &self, - fx: &'d mut FunctionCx<'b, 'c, 'tcx, Bx>, - ) -> Option<&'d Bx::Funclet> { + fx: &'c mut FunctionCx<'b, 'tcx, Bx>, + ) -> Option<&'c Bx::Funclet> { match self.funclet_bb { Some(funcl) => fx.funclets[funcl].as_ref(), None => None, } } - fn lltarget<'b, 'c, 'd, Bx: BuilderMethods<'b, 'tcx>>( + fn lltarget<'b, 'c, Bx: BuilderMethods<'b, 'tcx>>( &self, - fx: &'d mut FunctionCx<'b, 'c, 'tcx, Bx>, + fx: &'c mut FunctionCx<'b, 'tcx, Bx>, target: mir::BasicBlock ) -> (Bx::BasicBlock, bool) { let span = self.terminator.source_info.span; @@ -63,9 +63,9 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'a, 'tcx> { } /// Create a basic block. - fn llblock<'d, 'c, 'b, Bx: BuilderMethods<'b, 'tcx>>( + fn llblock<'c, 'b, Bx: BuilderMethods<'b, 'tcx>>( &self, - fx: &'d mut FunctionCx<'b, 'c, 'tcx, Bx>, + fx: &'c mut FunctionCx<'b, 'tcx, Bx>, target: mir::BasicBlock ) -> Bx::BasicBlock { let (lltarget, is_cleanupret) = self.lltarget(fx, target); @@ -83,9 +83,9 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'a, 'tcx> { } } - fn funclet_br<'d, 'c, 'b, Bx: BuilderMethods<'b, 'tcx>>( + fn funclet_br<'c, 'b, Bx: BuilderMethods<'b, 'tcx>>( &self, - fx: &'d mut FunctionCx<'b, 'c, 'tcx, Bx>, + fx: &'c mut FunctionCx<'b, 'tcx, Bx>, bx: &mut Bx, target: mir::BasicBlock, ) { @@ -101,9 +101,9 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'a, 'tcx> { /// Call `fn_ptr` of `fn_abi` with the arguments `llargs`, the optional /// return destination `destination` and the cleanup function `cleanup`. - fn do_call<'d, 'c, 'b, Bx: BuilderMethods<'b, 'tcx>>( + fn do_call<'c, 'b, Bx: BuilderMethods<'b, 'tcx>>( &self, - fx: &'d mut FunctionCx<'b, 'c, 'tcx, Bx>, + fx: &'c mut FunctionCx<'b, 'tcx, Bx>, bx: &mut Bx, fn_abi: FnAbi<'tcx, Ty<'tcx>>, fn_ptr: Bx::Value, @@ -153,7 +153,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'a, 'tcx> { // a loop. fn maybe_sideeffect<'b, 'tcx2: 'b, Bx: BuilderMethods<'b, 'tcx2>>( &self, - mir: &mir::ReadOnlyBodyCache<'_, 'tcx>, + mir: mir::ReadOnlyBodyCache<'_, 'tcx>, bx: &mut Bx, targets: &[mir::BasicBlock], ) { @@ -171,7 +171,7 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'a, 'tcx> { } /// Codegen implementations for some terminator variants. -impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { +impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { /// Generates code for a `Resume` terminator. fn codegen_resume_terminator<'c>( &mut self, @@ -216,7 +216,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { let lltrue = helper.llblock(self, targets[0]); let llfalse = helper.llblock(self, targets[1]); if switch_ty == bx.tcx().types.bool { - helper.maybe_sideeffect(&self.mir, &mut bx, targets.as_slice()); + helper.maybe_sideeffect(self.mir, &mut bx, targets.as_slice()); // Don't generate trivial icmps when switching on bool if let [0] = values[..] { bx.cond_br(discr.immediate(), llfalse, lltrue); @@ -230,11 +230,11 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { ); let llval = bx.const_uint_big(switch_llty, values[0]); let cmp = bx.icmp(IntPredicate::IntEQ, discr.immediate(), llval); - helper.maybe_sideeffect(&self.mir, &mut bx, targets.as_slice()); + helper.maybe_sideeffect(self.mir, &mut bx, targets.as_slice()); bx.cond_br(cmp, lltrue, llfalse); } } else { - helper.maybe_sideeffect(&self.mir, &mut bx, targets.as_slice()); + helper.maybe_sideeffect(self.mir, &mut bx, targets.as_slice()); let (otherwise, targets) = targets.split_last().unwrap(); bx.switch( discr.immediate(), @@ -330,7 +330,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { if let ty::InstanceDef::DropGlue(_, None) = drop_fn.def { // we don't actually need to drop anything. - helper.maybe_sideeffect(&self.mir, &mut bx, &[target]); + helper.maybe_sideeffect(self.mir, &mut bx, &[target]); helper.funclet_br(self, &mut bx, target); return } @@ -361,7 +361,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { FnAbi::of_instance(&bx, drop_fn)) } }; - helper.maybe_sideeffect(&self.mir, &mut bx, &[target]); + helper.maybe_sideeffect(self.mir, &mut bx, &[target]); helper.do_call(self, &mut bx, fn_ty, drop_fn, args, Some((ReturnDest::Nothing, target)), unwind); @@ -397,7 +397,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { // Don't codegen the panic block if success if known. if const_cond == Some(expected) { - helper.maybe_sideeffect(&self.mir, &mut bx, &[target]); + helper.maybe_sideeffect(self.mir, &mut bx, &[target]); helper.funclet_br(self, &mut bx, target); return; } @@ -408,7 +408,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { // Create the failure block and the conditional branch to it. let lltarget = helper.llblock(self, target); let panic_block = self.new_block("panic"); - helper.maybe_sideeffect(&self.mir, &mut bx, &[target]); + helper.maybe_sideeffect(self.mir, &mut bx, &[target]); if expected { bx.cond_br(cond, lltarget, panic_block.llbb()); } else { @@ -493,7 +493,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { if let Some(destination_ref) = destination.as_ref() { let &(ref dest, target) = destination_ref; self.codegen_transmute(&mut bx, &args[0], dest); - helper.maybe_sideeffect(&self.mir, &mut bx, &[target]); + helper.maybe_sideeffect(self.mir, &mut bx, &[target]); helper.funclet_br(self, &mut bx, target); } else { // If we are trying to transmute to an uninhabited type, @@ -521,7 +521,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { Some(ty::InstanceDef::DropGlue(_, None)) => { // Empty drop glue; a no-op. let &(_, target) = destination.as_ref().unwrap(); - helper.maybe_sideeffect(&self.mir, &mut bx, &[target]); + helper.maybe_sideeffect(self.mir, &mut bx, &[target]); helper.funclet_br(self, &mut bx, target); return; } @@ -553,7 +553,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { let llfn = bx.get_fn_addr(instance); if let Some((_, target)) = destination.as_ref() { - helper.maybe_sideeffect(&self.mir, &mut bx, &[*target]); + helper.maybe_sideeffect(self.mir, &mut bx, &[*target]); } // Codegen the actual panic invoke/call. helper.do_call( @@ -568,7 +568,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { } else { // a NOP let target = destination.as_ref().unwrap().1; - helper.maybe_sideeffect(&self.mir, &mut bx, &[target]); + helper.maybe_sideeffect(self.mir, &mut bx, &[target]); helper.funclet_br(self, &mut bx, destination.as_ref().unwrap().1) } return; @@ -682,7 +682,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { } if let Some((_, target)) = *destination { - helper.maybe_sideeffect(&self.mir, &mut bx, &[target]); + helper.maybe_sideeffect(self.mir, &mut bx, &[target]); helper.funclet_br(self, &mut bx, target); } else { bx.unreachable(); @@ -776,7 +776,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { }; if let Some((_, target)) = destination.as_ref() { - helper.maybe_sideeffect(&self.mir, &mut bx, &[*target]); + helper.maybe_sideeffect(self.mir, &mut bx, &[*target]); } helper.do_call(self, &mut bx, fn_ty, fn_ptr, &llargs, destination.as_ref().map(|&(_, target)| (ret_dest, target)), @@ -784,13 +784,13 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { } } -impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { +impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_block( &mut self, bb: mir::BasicBlock, ) { let mut bx = self.build_block(bb); - let data = &self.mir[bb]; + let data = &self.mir.body()[bb]; debug!("codegen_block({:?}={:?})", bb, data); @@ -827,7 +827,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { } mir::TerminatorKind::Goto { target } => { - helper.maybe_sideeffect(&self.mir, &mut bx, &[target]); + helper.maybe_sideeffect(self.mir, &mut bx, &[target]); helper.funclet_br(self, &mut bx, target); } diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index 71d0abf2bff8..27891be6b82c 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -9,7 +9,7 @@ use crate::mir::operand::OperandRef; use super::FunctionCx; -impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { +impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn eval_mir_constant_to_operand( &mut self, bx: &mut Bx, diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs index a58b13ce102d..2a012cd2ed94 100644 --- a/src/librustc_codegen_ssa/mir/mod.rs +++ b/src/librustc_codegen_ssa/mir/mod.rs @@ -1,6 +1,6 @@ use rustc::ty::{self, Ty, TypeFoldable, Instance}; use rustc::ty::layout::{TyLayout, HasTyCtxt, FnAbiExt}; -use rustc::mir::{self, Body, BodyCache}; +use rustc::mir::{self, Body, ReadOnlyBodyCache}; use rustc_target::abi::call::{FnAbi, PassMode}; use crate::base; use crate::traits::*; @@ -18,10 +18,10 @@ use rustc::mir::traversal; use self::operand::{OperandRef, OperandValue}; /// Master context for codegenning from MIR. -pub struct FunctionCx<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { +pub struct FunctionCx<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { instance: Instance<'tcx>, - mir: &'b mir::ReadOnlyBodyCache<'a, 'tcx>, + mir: mir::ReadOnlyBodyCache<'a, 'tcx>, debug_context: Option>, @@ -79,7 +79,7 @@ pub struct FunctionCx<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> { per_local_var_debug_info: Option>>>, } -impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { +impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn monomorphize(&self, value: &T) -> T where T: TypeFoldable<'tcx> { @@ -122,7 +122,7 @@ impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> { pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( cx: &'a Bx::CodegenCx, llfn: Bx::Function, - mut mir: BodyCache<&'a Body<'tcx>>, + mir: ReadOnlyBodyCache<'a, 'tcx>, instance: Instance<'tcx>, sig: ty::FnSig<'tcx>, ) { @@ -157,10 +157,9 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( let (landing_pads, funclets) = create_funclets(&mir, &mut bx, &cleanup_kinds, &block_bxs); let mir_body = mir.body(); - let readonly_mir = mir.read_only(); let mut fx = FunctionCx { instance, - mir: &readonly_mir, + mir, llfn, fn_abi, cx, @@ -319,9 +318,9 @@ fn create_funclets<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( /// Produces, for each argument, a `Value` pointing at the /// argument's value. As arguments are places, these are always /// indirect. -fn arg_local_refs<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( +fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( bx: &mut Bx, - fx: &FunctionCx<'a, 'b, 'tcx, Bx>, + fx: &FunctionCx<'a, 'tcx, Bx>, memory_locals: &BitSet, ) -> Vec> { let mut idx = 0; diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index 947dc2df87d2..310b8aeb4db0 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -377,7 +377,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue { } } -impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { +impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn maybe_codegen_consume_direct( &mut self, bx: &mut Bx, diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index 34f2b56adee4..281539277cb7 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -435,7 +435,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { } } -impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { +impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_place( &mut self, bx: &mut Bx, diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs index 19554156b227..680c5b873b02 100644 --- a/src/librustc_codegen_ssa/mir/rvalue.rs +++ b/src/librustc_codegen_ssa/mir/rvalue.rs @@ -18,7 +18,7 @@ use syntax::source_map::{DUMMY_SP, Span}; use std::{u128, i128}; -impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { +impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_rvalue( &mut self, mut bx: Bx, @@ -695,7 +695,7 @@ impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { } } -impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { +impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn rvalue_creates_operand( &self, rvalue: &mir::Rvalue<'tcx>, diff --git a/src/librustc_codegen_ssa/mir/statement.rs b/src/librustc_codegen_ssa/mir/statement.rs index 5307108f8571..0b82edea1579 100644 --- a/src/librustc_codegen_ssa/mir/statement.rs +++ b/src/librustc_codegen_ssa/mir/statement.rs @@ -8,7 +8,7 @@ use crate::traits::*; use rustc_error_codes::*; -impl<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'b, 'tcx, Bx> { +impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn codegen_statement( &mut self, mut bx: Bx, diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 820783bab6d2..30dad03648c9 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -18,12 +18,11 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::svh::Svh; use rustc::dep_graph::{self, DepNodeIndex}; use rustc::middle::lang_items; -use rustc::mir::{self, interpret}; +use rustc::mir::{self, BodyCache, interpret, Promoted}; use rustc::mir::interpret::{AllocDecodingSession, AllocDecodingState}; use rustc::session::Session; use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::codec::TyDecoder; -use rustc::mir::{Body, Promoted}; use rustc::util::common::record_time; use rustc::util::captures::Captures; @@ -1080,7 +1079,7 @@ impl<'a, 'tcx> CrateMetadata { self.root.per_def.mir.get(self, id).is_some() } - fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> { + fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> BodyCache<'tcx> { self.root.per_def.mir.get(self, id) .filter(|_| !self.is_proc_macro(id)) .unwrap_or_else(|| { @@ -1093,7 +1092,7 @@ impl<'a, 'tcx> CrateMetadata { &self, tcx: TyCtxt<'tcx>, id: DefIndex, - ) -> IndexVec> { + ) -> IndexVec> { self.root.per_def.promoted_mir.get(self, id) .filter(|_| !self.is_proc_macro(id)) .unwrap_or_else(|| { diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 4ea562fced30..fdf43f06eb10 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -276,8 +276,8 @@ define_per_def_tables! { // Also, as an optimization, a missing entry indicates an empty `&[]`. inferred_outlives: Table, Span)])>, super_predicates: Table)>, - mir: Table)>, - promoted_mir: Table>)>, + mir: Table)>, + promoted_mir: Table>)>, } #[derive(Copy, Clone, RustcEncodable, RustcDecodable)] diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index 6191a93d2287..d1af7461f475 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -90,7 +90,7 @@ crate enum LocalsStateAtExit { impl LocalsStateAtExit { fn build( locals_are_invalidated_at_exit: bool, - body_cache: &ReadOnlyBodyCache<'_, 'tcx>, + body_cache: ReadOnlyBodyCache<'_, 'tcx>, move_data: &MoveData<'tcx> ) -> Self { struct HasStorageDead(BitSet); @@ -123,7 +123,7 @@ impl LocalsStateAtExit { impl<'tcx> BorrowSet<'tcx> { pub fn build( tcx: TyCtxt<'tcx>, - body_cache: &ReadOnlyBodyCache<'_, 'tcx>, + body_cache: ReadOnlyBodyCache<'_, 'tcx>, locals_are_invalidated_at_exit: bool, move_data: &MoveData<'tcx>, ) -> Self { @@ -139,7 +139,7 @@ impl<'tcx> BorrowSet<'tcx> { LocalsStateAtExit::build(locals_are_invalidated_at_exit, body_cache, move_data), }; - for (block, block_data) in traversal::preorder(body_cache) { + for (block, block_data) in traversal::preorder(&body_cache) { visitor.visit_basic_block_data(block, block_data); } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index f8ae07aa394b..0170cc8b42ab 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -102,7 +102,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def_id: DefId) -> BorrowCheckResult<'_> { fn do_mir_borrowck<'a, 'tcx>( infcx: &InferCtxt<'a, 'tcx>, input_body: &Body<'tcx>, - input_promoted: &IndexVec>, + input_promoted: &IndexVec>, def_id: DefId, ) -> BorrowCheckResult<'tcx> { debug!("do_mir_borrowck(def_id = {:?})", def_id); @@ -162,14 +162,13 @@ fn do_mir_borrowck<'a, 'tcx>( // requires first making our own copy of the MIR. This copy will // be modified (in place) to contain non-lexical lifetimes. It // will have a lifetime tied to the inference context. - let mut body: Body<'tcx> = input_body.clone(); + let body: Body<'tcx> = input_body.clone(); let mut promoted = input_promoted.clone(); - let mut promoted_cache: IndexVec>> = input_promoted.clone().iter_mut().map(|body| BodyCache::new(body)).collect(); - let mut body_cache = BodyCache::new(&mut body); + let mut body_cache = BodyCache::new(body); let free_regions = - nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body_cache, &mut promoted_cache); - let body_cache = BodyCache::new(&body).read_only(); // no further changes - let promoted: IndexVec> = promoted_cache.into_iter().map(|body_cache| body_cache.read_only()).collect(); + nll::replace_regions_in_mir(infcx, def_id, param_env, &mut body_cache, &mut promoted); + let body_cache = body_cache.read_only(); // no further changes + let promoted: IndexVec<_, _> = promoted.iter().map(|body_cache| body_cache.read_only()).collect(); let location_table = &LocationTable::new(&body_cache); @@ -198,14 +197,14 @@ fn do_mir_borrowck<'a, 'tcx>( let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(id).is_fn_or_closure(); let borrow_set = Rc::new(BorrowSet::build( - tcx, &body_cache, locals_are_invalidated_at_exit, &mdpe.move_data)); + tcx, body_cache, locals_are_invalidated_at_exit, &mdpe.move_data)); // If we are in non-lexical mode, compute the non-lexical lifetimes. let (regioncx, polonius_output, opt_closure_req) = nll::compute_regions( infcx, def_id, free_regions, - &body_cache, + body_cache, &promoted, &local_names, &upvars, @@ -1338,7 +1337,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { _ => bug!("temporary initialized in arguments"), }; - let bbd = &self.body_cache[loc.block]; + let bbd = &self.body_cache.body()[loc.block]; let stmt = &bbd.statements[loc.statement_index]; debug!("temporary assigned in: stmt={:?}", stmt); @@ -1860,7 +1859,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if def.is_union() { if this.move_data.path_map[mpi].iter().any(|moi| { this.move_data.moves[*moi].source.is_predecessor_of( - location, &this.body_cache, + location, this.body_cache, ) }) { return; diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index 44e139889c93..feaa5fd3a551 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -377,7 +377,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { }, ))) => Some(suggest_ampmut( self.infcx.tcx, - &self.body_cache, + self.body_cache, *local, local_decl, opt_ty_info, @@ -529,7 +529,7 @@ fn suggest_ampmut_self<'tcx>( // by trying (3.), then (2.) and finally falling back on (1.). fn suggest_ampmut<'tcx>( tcx: TyCtxt<'tcx>, - body_cache: &ReadOnlyBodyCache<'_, 'tcx>, + body_cache: ReadOnlyBodyCache<'_, 'tcx>, local: Local, local_decl: &mir::LocalDecl<'tcx>, opt_ty_info: Option, diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs index 7cb5b839ceeb..8d5466e545d5 100644 --- a/src/librustc_mir/borrow_check/nll/invalidation.rs +++ b/src/librustc_mir/borrow_check/nll/invalidation.rs @@ -22,7 +22,7 @@ pub(super) fn generate_invalidates<'tcx>( param_env: ty::ParamEnv<'tcx>, all_facts: &mut Option, location_table: &LocationTable, - body_cache: &ReadOnlyBodyCache<'_, 'tcx>, + body_cache: ReadOnlyBodyCache<'_, 'tcx>, borrow_set: &BorrowSet<'tcx>, ) { if all_facts.is_none() { @@ -41,7 +41,7 @@ pub(super) fn generate_invalidates<'tcx>( body: body_cache.body(), dominators, }; - ig.visit_body(&body_cache); + ig.visit_body(body_cache); } } diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index 5fa2c6605f6f..bf11d348409c 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -55,8 +55,8 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>( infcx: &InferCtxt<'cx, 'tcx>, def_id: DefId, param_env: ty::ParamEnv<'tcx>, - body_cache: &mut BodyCache<&mut Body<'tcx>>, - promoted: &mut IndexVec>>, + body_cache: &mut BodyCache<'tcx>, + promoted: &mut IndexVec>, ) -> UniversalRegions<'tcx> { debug!("replace_regions_in_mir(def_id={:?})", def_id); @@ -158,7 +158,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( infcx: &InferCtxt<'cx, 'tcx>, def_id: DefId, universal_regions: UniversalRegions<'tcx>, - body_cache: &ReadOnlyBodyCache<'_, 'tcx>, + body_cache: ReadOnlyBodyCache<'_, 'tcx>, promoted_cache: &IndexVec>, local_names: &IndexVec>, upvars: &[Upvar], @@ -181,7 +181,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( let universal_regions = Rc::new(universal_regions); - let elements = &Rc::new(RegionValueElements::new(body_cache)); + let elements = &Rc::new(RegionValueElements::new(body_cache.body())); // Run the MIR type-checker. let MirTypeckResults { @@ -206,7 +206,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( all_facts .universal_region .extend(universal_regions.universal_regions()); - populate_polonius_move_facts(all_facts, move_data, location_table, body_cache); + populate_polonius_move_facts(all_facts, move_data, location_table, body_cache.body()); } // Create the region inference context, taking ownership of the @@ -230,7 +230,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( &mut liveness_constraints, &mut all_facts, location_table, - body_cache, + body_cache.body(), borrow_set, ); @@ -239,7 +239,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( universal_regions, placeholder_indices, universal_region_relations, - body_cache, + body_cache.body(), outlives_constraints, member_constraints, closure_bounds_mapping, @@ -284,21 +284,21 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>( // Solve the region constraints. let closure_region_requirements = - regioncx.solve(infcx, body_cache, local_names, upvars, def_id, errors_buffer); + regioncx.solve(infcx, body_cache.body(), local_names, upvars, def_id, errors_buffer); // Dump MIR results into a file, if that is enabled. This let us // write unit-tests, as well as helping with debugging. dump_mir_results( infcx, MirSource::item(def_id), - body_cache, + body_cache.body(), ®ioncx, &closure_region_requirements, ); // We also have a `#[rustc_nll]` annotation that causes us to dump // information - dump_annotation(infcx, body_cache, def_id, ®ioncx, &closure_region_requirements, errors_buffer); + dump_annotation(infcx, body_cache.body(), def_id, ®ioncx, &closure_region_requirements, errors_buffer); (regioncx, polonius_output, closure_region_requirements) } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/values.rs b/src/librustc_mir/borrow_check/nll/region_infer/values.rs index 5d1891c0bf64..16d2eca8f20e 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/values.rs @@ -92,7 +92,7 @@ impl RegionValueElements { /// Pushes all predecessors of `index` onto `stack`. crate fn push_predecessors( &self, - body_cache: &ReadOnlyBodyCache<'_, '_>, + body_cache: ReadOnlyBodyCache<'_, '_>, index: PointIndex, stack: &mut Vec, ) { diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs index 57e977eacba1..882b825c5284 100644 --- a/src/librustc_mir/borrow_check/nll/renumber.rs +++ b/src/librustc_mir/borrow_check/nll/renumber.rs @@ -1,6 +1,6 @@ use rustc::ty::subst::SubstsRef; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; -use rustc::mir::{Body, BodyCache, Location, PlaceElem, Promoted}; +use rustc::mir::{BodyCache, Location, PlaceElem, Promoted}; use rustc::mir::visit::{MutVisitor, TyContext}; use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; use rustc_index::vec::IndexVec; @@ -9,8 +9,8 @@ use rustc_index::vec::IndexVec; /// inference variables, returning the number of variables created. pub fn renumber_mir<'tcx>( infcx: &InferCtxt<'_, 'tcx>, - body_cache: &mut BodyCache<&mut Body<'tcx>>, - promoted: &mut IndexVec>>, + body_cache: &mut BodyCache<'tcx>, + promoted: &mut IndexVec>, ) { debug!("renumber_mir()"); debug!("renumber_mir: body.arg_count={:?}", body_cache.arg_count); diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs index 181508a983a1..0cd5dd805949 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs @@ -60,7 +60,7 @@ impl LocalUseMap { crate fn build( live_locals: &Vec, elements: &RegionValueElements, - body_cache: &ReadOnlyBodyCache<'_, '_>, + body_cache: ReadOnlyBodyCache<'_, '_>, ) -> Self { let nones = IndexVec::from_elem_n(None, body_cache.local_decls.len()); let mut local_use_map = LocalUseMap { diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs index 833958814af4..2dea6797ec74 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs @@ -28,7 +28,7 @@ mod trace; /// performed before pub(super) fn generate<'tcx>( typeck: &mut TypeChecker<'_, 'tcx>, - body_cache: &ReadOnlyBodyCache<'_, 'tcx>, + body_cache: ReadOnlyBodyCache<'_, 'tcx>, elements: &Rc, flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>, move_data: &MoveData<'tcx>, @@ -48,7 +48,7 @@ pub(super) fn generate<'tcx>( let mut drop_used = Vec::new(); polonius::populate_access_facts( typeck, - &body_cache, + body_cache, location_table, move_data, &mut drop_used, diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs index 3320815688f2..c17fbf0cdc9f 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs @@ -97,7 +97,7 @@ fn add_var_uses_regions(typeck: &mut TypeChecker<'_, 'tcx>, local: Local, ty: Ty pub(super) fn populate_access_facts( typeck: &mut TypeChecker<'_, 'tcx>, - body_cache: &ReadOnlyBodyCache<'_, 'tcx>, + body_cache: ReadOnlyBodyCache<'_, 'tcx>, location_table: &LocationTable, move_data: &MoveData<'_>, drop_used: &mut Vec<(Local, Location)>, diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs index 5929516ec4e4..9a0392ab1d83 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs @@ -32,7 +32,7 @@ use std::rc::Rc; /// this respects `#[may_dangle]` annotations). pub(super) fn trace( typeck: &mut TypeChecker<'_, 'tcx>, - body_cache: &ReadOnlyBodyCache<'_, 'tcx>, + body_cache: ReadOnlyBodyCache<'_, 'tcx>, elements: &Rc, flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>, move_data: &MoveData<'tcx>, @@ -41,7 +41,7 @@ pub(super) fn trace( ) { debug!("trace()"); - let local_use_map = &LocalUseMap::build(&live_locals, elements, &body_cache); + let local_use_map = &LocalUseMap::build(&live_locals, elements, body_cache); let cx = LivenessContext { typeck, @@ -71,7 +71,7 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> { elements: &'me RegionValueElements, /// MIR we are analyzing. - body_cache: &'me ReadOnlyBodyCache<'me, 'tcx>, + body_cache: ReadOnlyBodyCache<'me, 'tcx>, /// Mapping to/from the various indices used for initialization tracking. move_data: &'me MoveData<'tcx>, @@ -211,7 +211,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> { } if self.use_live_at.insert(p) { - self.cx.elements.push_predecessors(&self.cx.body_cache, p, &mut self.stack) + self.cx.elements.push_predecessors(self.cx.body_cache, p, &mut self.stack) } } } 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 8e966033bb8f..92efd383c3c8 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -115,7 +115,7 @@ mod relate_tys; pub(crate) fn type_check<'tcx>( infcx: &InferCtxt<'_, 'tcx>, param_env: ty::ParamEnv<'tcx>, - body_cache: &ReadOnlyBodyCache<'_, 'tcx>, + body_cache: ReadOnlyBodyCache<'_, 'tcx>, promoted_cache: &IndexVec>, mir_def_id: DefId, universal_regions: &Rc>, @@ -168,7 +168,7 @@ pub(crate) fn type_check<'tcx>( &mut borrowck_context, &universal_region_relations, |mut cx| { - cx.equate_inputs_and_outputs(body_cache, universal_regions, &normalized_inputs_and_output); + cx.equate_inputs_and_outputs(body_cache.body(), universal_regions, &normalized_inputs_and_output); liveness::generate(&mut cx, body_cache, elements, flow_inits, move_data, location_table); translate_outlives_facts(cx.borrowck_context); @@ -185,7 +185,7 @@ fn type_check_internal<'a, 'tcx, R>( infcx: &'a InferCtxt<'a, 'tcx>, mir_def_id: DefId, param_env: ty::ParamEnv<'tcx>, - body_cache: &ReadOnlyBodyCache<'a, 'tcx>, + body_cache: ReadOnlyBodyCache<'a, 'tcx>, promoted_cache: &'a IndexVec>, region_bound_pairs: &'a RegionBoundPairs<'tcx>, implicit_region_bound: ty::Region<'tcx>, @@ -195,7 +195,7 @@ fn type_check_internal<'a, 'tcx, R>( ) -> R where { let mut checker = TypeChecker::new( infcx, - body_cache, + body_cache.body(), mir_def_id, param_env, region_bound_pairs, @@ -204,14 +204,14 @@ fn type_check_internal<'a, 'tcx, R>( universal_region_relations, ); let errors_reported = { - let mut verifier = TypeVerifier::new(&mut checker, body_cache, promoted_cache); + let mut verifier = TypeVerifier::new(&mut checker, body_cache.body(), promoted_cache); verifier.visit_body(body_cache); verifier.errors_reported }; if !errors_reported { // if verifier failed, don't do further checks to avoid ICEs - checker.typeck_mir(body_cache); + checker.typeck_mir(body_cache.body()); } extra(&mut checker) @@ -385,7 +385,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { } } - fn visit_body(&mut self, body_cache: &ReadOnlyBodyCache<'_, 'tcx>) { + fn visit_body(&mut self, body_cache: ReadOnlyBodyCache<'_, 'tcx>) { self.sanitize_type(&"return type", body_cache.return_ty()); for local_decl in &body_cache.local_decls { self.sanitize_type(local_decl, local_decl.ty); @@ -464,7 +464,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { match kind { StaticKind::Promoted(promoted, _) => { if !self.errors_reported { - let promoted_body_cache = &self.promoted_cache[*promoted]; + let promoted_body_cache = self.promoted_cache[*promoted]; self.sanitize_promoted(promoted_body_cache, location); let promoted_ty = promoted_body_cache.return_ty(); @@ -535,7 +535,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { place_ty } - fn sanitize_promoted(&mut self, promoted_body_cache: &ReadOnlyBodyCache<'b, 'tcx>, location: Location) { + fn sanitize_promoted(&mut self, promoted_body_cache: ReadOnlyBodyCache<'b, 'tcx>, location: Location) { // Determine the constraints from the promoted MIR by running the type // checker on the promoted MIR, then transfer the constraints back to // the main MIR, changing the locations to the provided location. diff --git a/src/librustc_mir/borrow_check/used_muts.rs b/src/librustc_mir/borrow_check/used_muts.rs index 430452efe422..27e6d803bd0a 100644 --- a/src/librustc_mir/borrow_check/used_muts.rs +++ b/src/librustc_mir/borrow_check/used_muts.rs @@ -32,7 +32,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { never_initialized_mut_locals: &mut never_initialized_mut_locals, mbcx: self, }; - visitor.visit_body(&visitor.mbcx.body_cache); + visitor.visit_body(visitor.mbcx.body_cache); } // Take the union of the existed `used_mut` set with those variables we've found were diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index eb9b401f2720..28b4c9fd09b3 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -24,7 +24,7 @@ use syntax_pos::Span; use super::lints; /// Construct the MIR for a given `DefId`. -pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> { +pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyCache<'_> { let id = tcx.hir().as_local_hir_id(def_id).unwrap(); // Figure out what primary body this item has. @@ -196,7 +196,7 @@ pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> { lints::check(tcx, &body, def_id); - body + BodyCache::new(body) }) } diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 0967b2578855..0a205be0c58d 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -354,7 +354,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, } // This is a const fn. Call it. Ok(Some(match ecx.load_mir(instance.def, None) { - Ok(body) => body, + Ok(body_cache) => body_cache.body(), Err(err) => { if let err_unsup!(NoMirFor(ref path)) = err.kind { return Err( @@ -697,7 +697,7 @@ pub fn const_eval_raw_provider<'tcx>( let res = ecx.load_mir(cid.instance.def, cid.promoted); res.and_then( - |body| eval_body_using_ecx(&mut ecx, cid, body) + |body_cache| eval_body_using_ecx(&mut ecx, cid, body_cache.body()) ).and_then(|place| { Ok(RawConst { alloc_id: place.ptr.assert_ptr().alloc_id, diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs index 2e164765043d..fc344f9b2525 100644 --- a/src/librustc_mir/dataflow/impls/storage_liveness.rs +++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs @@ -75,19 +75,19 @@ impl<'a, 'tcx> BottomValue for MaybeStorageLive<'a, 'tcx> { /// Dataflow analysis that determines whether each local requires storage at a /// given location; i.e. whether its storage can go away without being observed. pub struct RequiresStorage<'mir, 'tcx> { - body_cache: &'mir ReadOnlyBodyCache<'mir, 'tcx>, + body_cache: ReadOnlyBodyCache<'mir, 'tcx>, borrowed_locals: RefCell>>, } impl<'mir, 'tcx: 'mir> RequiresStorage<'mir, 'tcx> { pub fn new( - body_cache: &'mir ReadOnlyBodyCache<'mir, 'tcx>, + body_cache: ReadOnlyBodyCache<'mir, 'tcx>, borrowed_locals: &'mir DataflowResults<'tcx, HaveBeenBorrowedLocals<'mir, 'tcx>>, ) -> Self { RequiresStorage { body_cache, - borrowed_locals: RefCell::new(DataflowResultsCursor::new(borrowed_locals, body_cache)), + borrowed_locals: RefCell::new(DataflowResultsCursor::new(borrowed_locals, body_cache.body())), } } @@ -187,7 +187,7 @@ impl<'mir, 'tcx> RequiresStorage<'mir, 'tcx> { sets, borrowed_locals: &self.borrowed_locals, }; - visitor.visit_location(&self.body_cache, loc); + visitor.visit_location(self.body_cache, loc); } /// Gen locals that are newly borrowed. This includes borrowing any part of diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 6c16c4f22192..043ba09f52a9 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -292,7 +292,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { &self, instance: ty::InstanceDef<'tcx>, promoted: Option, - ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> { + ) -> InterpResult<'tcx, mir::ReadOnlyBodyCache<'tcx, 'tcx>> { // do not continue if typeck errors occurred (can only occur in local crate) let did = instance.def_id(); if did.is_local() @@ -303,11 +303,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } trace!("load mir(instance={:?}, promoted={:?})", instance, promoted); if let Some(promoted) = promoted { - return Ok(&self.tcx.promoted_mir(did)[promoted]); + return Ok(self.tcx.promoted_mir(did)[promoted].read_only()); } match instance { ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) { - Ok(self.tcx.optimized_mir(did)) + Ok(self.tcx.optimized_mir(did).read_only()) } else { throw_unsup!(NoMirFor(self.tcx.def_path_str(def_id))) }, diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 285bdf50d4a2..ecfbe529b956 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -186,7 +186,7 @@ use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind, Instance}; use rustc::ty::print::obsolete::DefPathBasedNames; use rustc::ty::adjustment::{CustomCoerceUnsized, PointerCast}; use rustc::session::config::EntryFnType; -use rustc::mir::{self, BodyCache, Location, PlaceBase, Static, StaticKind}; +use rustc::mir::{self, Location, PlaceBase, Static, StaticKind}; use rustc::mir::visit::Visitor as MirVisitor; use rustc::mir::mono::{MonoItem, InstantiationMode}; use rustc::mir::interpret::{Scalar, GlobalId, GlobalAlloc, ErrorHandled}; @@ -1248,15 +1248,15 @@ fn collect_neighbours<'tcx>( output: &mut Vec>, ) { debug!("collect_neighbours: {:?}", instance.def_id()); - let body = tcx.instance_mir(instance.def); - let body_cache = BodyCache::new(body).read_only(); + let body_cache = tcx.instance_mir(instance.def); + let body = body_cache.body(); MirNeighborCollector { tcx, body: &body, output, param_substs: instance.substs, - }.visit_body(&body_cache); + }.visit_body(body_cache); } fn def_id_to_string(tcx: TyCtxt<'_>, def_id: DefId) -> String { diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index c80b6e38ac50..8f97a4e7f5c8 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -26,7 +26,7 @@ pub fn provide(providers: &mut Providers<'_>) { providers.mir_shims = make_shim; } -fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> { +fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx BodyCache<'tcx> { debug!("make_shim({:?})", instance); let mut result = match instance { @@ -113,7 +113,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx bug!("creating shims from intrinsics ({:?}) is unsupported", instance) } }; - debug!("make_shim({:?}) = untransformed {:?}", instance, result); + debug!("make_shim({:?}) = untransformed {:?}", instance, result.body()); run_passes(tcx, &mut result, instance, None, MirPhase::Const, &[ &add_moves_for_packed_drops::AddMovesForPackedDrops, @@ -123,7 +123,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx &add_call_guards::CriticalCallEdges, ]); - debug!("make_shim({:?}) = {:?}", instance, result); + debug!("make_shim({:?}) = {:?}", instance, result.body()); tcx.arena.alloc(result) } @@ -164,7 +164,7 @@ fn local_decls_for_sig<'tcx>(sig: &ty::FnSig<'tcx>, span: Span) .collect() } -fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) -> Body<'tcx> { +fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) -> BodyCache<'tcx> { debug!("build_drop_shim(def_id={:?}, ty={:?})", def_id, ty); // Check if this is a generator, if so, return the drop glue for it @@ -202,7 +202,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) sig.inputs().len(), span); - let mut body_cache = BodyCache::new(&mut body); + let mut body_cache = BodyCache::new(body); if let Some(..) = ty { // The first argument (index 0), but add 1 for the return value. @@ -238,8 +238,7 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option>) patch.apply(&mut body_cache); } - // TODO(pfaia) return owning body cache... - body + body_cache } fn new_body<'tcx>( @@ -317,7 +316,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { } /// Builds a `Clone::clone` shim for `self_ty`. Here, `def_id` is `Clone::clone`. -fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> { +fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> BodyCache<'tcx> { debug!("build_clone_shim(def_id={:?})", def_id); let param_env = tcx.param_env(def_id); @@ -346,7 +345,7 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) - } }; - builder.into_mir() + BodyCache::new(builder.into_mir()) } struct CloneShimBuilder<'tcx> { @@ -707,7 +706,7 @@ fn build_call_shim<'tcx>( rcvr_adjustment: Adjustment, call_kind: CallKind, untuple_args: Option<&[Ty<'tcx>]>, -) -> Body<'tcx> { +) -> BodyCache<'tcx> { debug!("build_call_shim(def_id={:?}, rcvr_adjustment={:?}, \ call_kind={:?}, untuple_args={:?})", def_id, rcvr_adjustment, call_kind, untuple_args); @@ -842,10 +841,10 @@ fn build_call_shim<'tcx>( if let Abi::RustCall = sig.abi { body.spread_arg = Some(Local::new(sig.inputs().len())); } - body + BodyCache::new(body) } -pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> { +pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &BodyCache<'_> { debug_assert!(tcx.is_constructor(ctor_id)); let span = tcx.hir().span_if_local(ctor_id) @@ -929,5 +928,5 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> { |_, _| Ok(()), ); - tcx.arena.alloc(body) + tcx.arena.alloc(BodyCache::new(body)) } diff --git a/src/librustc_mir/transform/add_call_guards.rs b/src/librustc_mir/transform/add_call_guards.rs index bf3df1ae2fd8..071ad002c169 100644 --- a/src/librustc_mir/transform/add_call_guards.rs +++ b/src/librustc_mir/transform/add_call_guards.rs @@ -31,22 +31,22 @@ pub use self::AddCallGuards::*; */ impl<'tcx> MirPass<'tcx> for AddCallGuards { - fn run_pass(&self, _tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) { - self.add_call_guards(body); + fn run_pass(&self, _tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { + self.add_call_guards(body_cache); } } impl AddCallGuards { - pub fn add_call_guards(&self, body: &mut Body<'_>) { + pub fn add_call_guards(&self, body_cache: &mut BodyCache<'_>) { let pred_count: IndexVec<_, _> = - body.predecessors().iter().map(|ps| ps.len()).collect(); + body_cache.predecessors().iter().map(|ps| ps.len()).collect(); // We need a place to store the new blocks generated let mut new_blocks = Vec::new(); - let cur_len = body.basic_blocks().len(); + let cur_len = body_cache.basic_blocks().len(); - for block in body.basic_blocks_mut() { + for block in body_cache.basic_blocks_mut() { match block.terminator { Some(Terminator { kind: TerminatorKind::Call { @@ -78,6 +78,6 @@ impl AddCallGuards { debug!("Broke {} N edges", new_blocks.len()); - body.basic_blocks_mut().extend(new_blocks); + body_cache.basic_blocks_mut().extend(new_blocks); } } diff --git a/src/librustc_mir/transform/add_moves_for_packed_drops.rs b/src/librustc_mir/transform/add_moves_for_packed_drops.rs index 052631ddff37..aebd632978ad 100644 --- a/src/librustc_mir/transform/add_moves_for_packed_drops.rs +++ b/src/librustc_mir/transform/add_moves_for_packed_drops.rs @@ -40,15 +40,15 @@ use crate::util; pub struct AddMovesForPackedDrops; impl<'tcx> MirPass<'tcx> for AddMovesForPackedDrops { - fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) { - debug!("add_moves_for_packed_drops({:?} @ {:?})", src, body.span); - add_moves_for_packed_drops(tcx, body, src.def_id()); + fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { + debug!("add_moves_for_packed_drops({:?} @ {:?})", src, body_cache.span); + add_moves_for_packed_drops(tcx, body_cache, src.def_id()); } } -pub fn add_moves_for_packed_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, def_id: DefId) { - let patch = add_moves_for_packed_drops_patch(tcx, body, def_id); - patch.apply(body); +pub fn add_moves_for_packed_drops<'tcx>(tcx: TyCtxt<'tcx>, body_cache: &mut BodyCache<'tcx>, def_id: DefId) { + let patch = add_moves_for_packed_drops_patch(tcx, body_cache, def_id); + patch.apply(body_cache); } fn add_moves_for_packed_drops_patch<'tcx>( diff --git a/src/librustc_mir/transform/add_retag.rs b/src/librustc_mir/transform/add_retag.rs index b56a1b263fd6..25594ab20a91 100644 --- a/src/librustc_mir/transform/add_retag.rs +++ b/src/librustc_mir/transform/add_retag.rs @@ -59,12 +59,12 @@ fn may_be_reference<'tcx>(ty: Ty<'tcx>) -> bool { } impl<'tcx> MirPass<'tcx> for AddRetag { - fn run_pass(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { if !tcx.sess.opts.debugging_opts.mir_emit_retag { return; } - let (span, arg_count) = (body.span, body.arg_count); - let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut(); + let (span, arg_count) = (body_cache.span, body_cache.arg_count); + let (basic_blocks, local_decls) = body_cache.basic_blocks_and_local_decls_mut(); let needs_retag = |place: &Place<'tcx>| { // FIXME: Instead of giving up for unstable places, we should introduce // a temporary and retag on that. diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index d12d21aee6ab..78628474bce9 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -528,7 +528,7 @@ fn unsafety_check_result(tcx: TyCtxt<'_>, def_id: DefId) -> UnsafetyCheckResult hir::BodyOwnerKind::Static(_) => (true, false), }; let mut checker = UnsafetyChecker::new(const_context, min_const_fn, body, tcx, param_env); - checker.visit_body(body); + checker.visit_body(body.read_only()); check_unused_unsafe(tcx, def_id, &checker.used_unsafe, &mut checker.inherited_blocks); UnsafetyCheckResult { diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs index 4fd4fe45cd4f..3ea41816ebef 100644 --- a/src/librustc_mir/transform/cleanup_post_borrowck.rs +++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs @@ -16,7 +16,7 @@ //! [`FakeRead`]: rustc::mir::StatementKind::FakeRead //! [`Nop`]: rustc::mir::StatementKind::Nop -use rustc::mir::{BorrowKind, Rvalue, Location, Body}; +use rustc::mir::{BodyCache, BorrowKind, Rvalue, Location}; use rustc::mir::{Statement, StatementKind}; use rustc::mir::visit::MutVisitor; use rustc::ty::TyCtxt; @@ -29,9 +29,9 @@ pub struct DeleteNonCodegenStatements<'tcx> { } impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements { - fn run_pass(&self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut Body<'tcx>) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { let mut delete = DeleteNonCodegenStatements { tcx }; - delete.visit_body(body); + delete.visit_body(body_cache); } } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 67958af3460f..f79f375a7e84 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -7,9 +7,10 @@ use std::cell::Cell; use rustc::hir::def::DefKind; use rustc::hir::def_id::DefId; use rustc::mir::{ - AggregateKind, Constant, Location, Place, PlaceBase, Body, Operand, Rvalue, Local, UnOp, - StatementKind, Statement, LocalKind, TerminatorKind, Terminator, ClearCrossCrate, SourceInfo, - BinOp, SourceScope, SourceScopeData, LocalDecl, BasicBlock, RETURN_PLACE, + AggregateKind, Constant, Location, Place, PlaceBase, Body, BodyCache, Operand, Local, UnOp, + Rvalue. StatementKind, Statement, LocalKind, TerminatorKind, Terminator, ClearCrossCrate, + SourceInfo, BinOp, SourceScope, SourceScopeData, LocalDecl, BasicBlock, ReadOnlyBodyCache, + RETURN_PLACE }; use rustc::mir::visit::{ Visitor, PlaceContext, MutatingUseContext, MutVisitor, NonMutatingUseContext, @@ -41,7 +42,7 @@ const MAX_ALLOC_LIMIT: u64 = 1024; pub struct ConstProp; impl<'tcx> MirPass<'tcx> for ConstProp { - fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { // will be evaluated by miri and produce its errors there if source.promoted.is_some() { return; @@ -76,15 +77,15 @@ impl<'tcx> MirPass<'tcx> for ConstProp { let dummy_body = &Body::new( - body.basic_blocks().clone(), - body.source_scopes.clone(), - body.local_decls.clone(), + body_cache.basic_blocks().clone(), + body_cache.source_scopes.clone(), + body_cache.local_decls.clone(), Default::default(), - body.arg_count, + body_cache.arg_count, Default::default(), tcx.def_span(source.def_id()), Default::default(), - body.generator_kind, + body_cache.generator_kind, ); // FIXME(oli-obk, eddyb) Optimize locals (or even local paths) to hold @@ -92,12 +93,12 @@ impl<'tcx> MirPass<'tcx> for ConstProp { // That would require an uniform one-def no-mutation analysis // and RPO (or recursing when needing the value of a local). let mut optimization_finder = ConstPropagator::new( - body, + body_cache.read_only(), dummy_body, tcx, source ); - optimization_finder.visit_body(body); + optimization_finder.visit_body(body_cache); trace!("ConstProp done for {:?}", source.def_id()); } @@ -284,7 +285,7 @@ impl<'mir, 'tcx> HasTyCtxt<'tcx> for ConstPropagator<'mir, 'tcx> { impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { fn new( - body: &Body<'tcx>, + body_cache: ReadOnlyBodyCache<'mir, 'tcx>, dummy_body: &'mir Body<'tcx>, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, @@ -293,7 +294,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let param_env = tcx.param_env(def_id); let span = tcx.def_span(def_id); let mut ecx = InterpCx::new(tcx.at(span), param_env, ConstPropMachine, ()); - let can_const_prop = CanConstProp::check(body); + let can_const_prop = CanConstProp::check(body_cache); let substs = &InternalSubsts::identity_for_item(tcx, def_id); @@ -325,9 +326,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { can_const_prop, // FIXME(eddyb) avoid cloning these two fields more than once, // by accessing them through `ecx` instead. - source_scopes: body.source_scopes.clone(), + source_scopes: body_cache.source_scopes.clone(), //FIXME(wesleywiser) we can't steal this because `Visitor::super_visit_body()` needs it - local_decls: body.local_decls.clone(), + local_decls: body_cache.local_decls.clone(), ret: ret.map(Into::into), } } @@ -678,10 +679,10 @@ struct CanConstProp { impl CanConstProp { /// returns true if `local` can be propagated - fn check(body: &Body<'_>) -> IndexVec { + fn check(body_cache: ReadOnlyBodyCache<'_, '_>) -> IndexVec { let mut cpv = CanConstProp { - can_const_prop: IndexVec::from_elem(true, &body.local_decls), - found_assignment: IndexVec::from_elem(false, &body.local_decls), + can_const_prop: IndexVec::from_elem(true, &body_cache.local_decls), + found_assignment: IndexVec::from_elem(false, &body_cache.local_decls), }; for (local, val) in cpv.can_const_prop.iter_enumerated_mut() { // cannot use args at all @@ -689,14 +690,14 @@ impl CanConstProp { // lint for x != y // FIXME(oli-obk): lint variables until they are used in a condition // FIXME(oli-obk): lint if return value is constant - let local_kind = body.local_kind(local); + let local_kind = body_cache.local_kind(local); *val = local_kind == LocalKind::Temp || local_kind == LocalKind::ReturnPointer; if !*val { trace!("local {:?} can't be propagated because it's not a temporary", local); } } - cpv.visit_body(body); + cpv.visit_body(body_cache); cpv.can_const_prop } } diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs index 4c26feac4af7..637f4792029a 100644 --- a/src/librustc_mir/transform/copy_prop.rs +++ b/src/librustc_mir/transform/copy_prop.rs @@ -19,7 +19,10 @@ //! (non-mutating) use of `SRC`. These restrictions are conservative and may be relaxed in the //! future. -use rustc::mir::{Constant, Local, LocalKind, Location, Place, Body, Operand, Rvalue, StatementKind}; +use rustc::mir::{ + Constant, Local, LocalKind, Location, Place, Body, BodyCache, Operand, Rvalue, + StatementKind +}; use rustc::mir::visit::MutVisitor; use rustc::ty::TyCtxt; use crate::transform::{MirPass, MirSource}; @@ -28,23 +31,23 @@ use crate::util::def_use::DefUseAnalysis; pub struct CopyPropagation; impl<'tcx> MirPass<'tcx> for CopyPropagation { - fn run_pass(&self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut Body<'tcx>) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { // We only run when the MIR optimization level is > 1. // This avoids a slow pass, and messing up debug info. if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 { return; } - let mut def_use_analysis = DefUseAnalysis::new(body); + let mut def_use_analysis = DefUseAnalysis::new(body_cache); loop { - def_use_analysis.analyze(body); + def_use_analysis.analyze(body_cache.read_only()); - if eliminate_self_assignments(body, &def_use_analysis) { - def_use_analysis.analyze(body); + if eliminate_self_assignments(body_cache, &def_use_analysis) { + def_use_analysis.analyze(body_cache.read_only()); } let mut changed = false; - for dest_local in body.local_decls.indices() { + for dest_local in body_cache.local_decls.indices() { debug!("considering destination local: {:?}", dest_local); let action; @@ -71,7 +74,7 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation { } // Conservatively gives up if the dest is an argument, // because there may be uses of the original argument value. - if body.local_kind(dest_local) == LocalKind::Arg { + if body_cache.local_kind(dest_local) == LocalKind::Arg { debug!(" Can't copy-propagate local: dest {:?} (argument)", dest_local); continue; @@ -79,7 +82,7 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation { let dest_place_def = dest_use_info.defs_not_including_drop().next().unwrap(); location = dest_place_def.location; - let basic_block = &body[location.block]; + let basic_block = &body_cache[location.block]; let statement_index = location.statement_index; let statement = match basic_block.statements.get(statement_index) { Some(statement) => statement, @@ -97,7 +100,7 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation { let maybe_action = match operand { Operand::Copy(ref src_place) | Operand::Move(ref src_place) => { - Action::local_copy(&body, &def_use_analysis, src_place) + Action::local_copy(&body_cache, &def_use_analysis, src_place) } Operand::Constant(ref src_constant) => { Action::constant(src_constant) @@ -127,7 +130,7 @@ impl<'tcx> MirPass<'tcx> for CopyPropagation { } changed = - action.perform(body, &def_use_analysis, dest_local, location, tcx) || changed; + action.perform(body_cache, &def_use_analysis, dest_local, location, tcx) || changed; // FIXME(pcwalton): Update the use-def chains to delete the instructions instead of // regenerating the chains. break @@ -242,7 +245,7 @@ impl<'tcx> Action<'tcx> { } fn perform(self, - body: &mut Body<'tcx>, + body_cache: &mut BodyCache<'tcx>, def_use_analysis: &DefUseAnalysis, dest_local: Local, location: Location, @@ -260,21 +263,21 @@ impl<'tcx> Action<'tcx> { src_local); for place_use in &def_use_analysis.local_info(dest_local).defs_and_uses { if place_use.context.is_storage_marker() { - body.make_statement_nop(place_use.location) + body_cache.make_statement_nop(place_use.location) } } for place_use in &def_use_analysis.local_info(src_local).defs_and_uses { if place_use.context.is_storage_marker() { - body.make_statement_nop(place_use.location) + body_cache.make_statement_nop(place_use.location) } } // Replace all uses of the destination local with the source local. - def_use_analysis.replace_all_defs_and_uses_with(dest_local, body, src_local, tcx); + def_use_analysis.replace_all_defs_and_uses_with(dest_local, body_cache, src_local, tcx); // Finally, zap the now-useless assignment instruction. debug!(" Deleting assignment"); - body.make_statement_nop(location); + body_cache.make_statement_nop(location); true } @@ -288,7 +291,7 @@ impl<'tcx> Action<'tcx> { let dest_local_info = def_use_analysis.local_info(dest_local); for place_use in &dest_local_info.defs_and_uses { if place_use.context.is_storage_marker() { - body.make_statement_nop(place_use.location) + body_cache.make_statement_nop(place_use.location) } } @@ -297,7 +300,7 @@ impl<'tcx> Action<'tcx> { src_constant, tcx); for dest_place_use in &dest_local_info.defs_and_uses { - visitor.visit_location(body, dest_place_use.location) + visitor.visit_location(body_cache, dest_place_use.location) } // Zap the assignment instruction if we eliminated all the uses. We won't have been @@ -308,7 +311,7 @@ impl<'tcx> Action<'tcx> { debug!(" {} of {} use(s) replaced; deleting assignment", visitor.uses_replaced, use_count); - body.make_statement_nop(location); + body_cache.make_statement_nop(location); true } else if visitor.uses_replaced == 0 { debug!(" No uses replaced; not deleting assignment"); diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs index cdde9e12edcb..3d0bf6192dc4 100644 --- a/src/librustc_mir/transform/deaggregator.rs +++ b/src/librustc_mir/transform/deaggregator.rs @@ -6,8 +6,8 @@ use crate::util::expand_aggregate; pub struct Deaggregator; impl<'tcx> MirPass<'tcx> for Deaggregator { - fn run_pass(&self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body: &mut Body<'tcx>) { - let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut(); + fn run_pass(&self, tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { + let (basic_blocks, local_decls) = body_cache.basic_blocks_and_local_decls_mut(); let local_decls = &*local_decls; for bb in basic_blocks { bb.expand_statements(|stmt| { diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs index ed0eff943a16..987f0fde2e37 100644 --- a/src/librustc_mir/transform/dump_mir.rs +++ b/src/librustc_mir/transform/dump_mir.rs @@ -5,7 +5,7 @@ use std::fmt; use std::fs::File; use std::io; -use rustc::mir::Body; +use rustc::mir::{Body, BodyCache}; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::ty::TyCtxt; use crate::transform::{MirPass, MirSource}; @@ -18,7 +18,7 @@ impl<'tcx> MirPass<'tcx> for Marker { Cow::Borrowed(self.0) } - fn run_pass(&self, _tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, _body: &mut Body<'tcx>) { + fn run_pass(&self, _tcx: TyCtxt<'tcx>, _source: MirSource<'tcx>, _body_cache: &mut BodyCache<'tcx>) { } } diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index f91a08bcd9aa..378d991025a8 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -21,17 +21,17 @@ use syntax_pos::Span; pub struct ElaborateDrops; impl<'tcx> MirPass<'tcx> for ElaborateDrops { - fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) { - debug!("elaborate_drops({:?} @ {:?})", src, body.span); + fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { + debug!("elaborate_drops({:?} @ {:?})", src, body_cache.span); let def_id = src.def_id(); let param_env = tcx.param_env(src.def_id()).with_reveal_all(); - let move_data = match MoveData::gather_moves(body, tcx) { + let move_data = match MoveData::gather_moves(body_cache, tcx) { Ok(move_data) => move_data, Err(_) => bug!("No `move_errors` should be allowed in MIR borrowck"), }; let elaborate_patch = { - let body = &*body; + let body = &*body_cache; let env = MoveDataParamEnv { move_data, param_env, @@ -56,7 +56,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { patch: MirPatch::new(body), }.elaborate() }; - elaborate_patch.apply(body); + elaborate_patch.apply(body_cache); } } diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs index b30e2de4ca0b..ff07f65d22c4 100644 --- a/src/librustc_mir/transform/erase_regions.rs +++ b/src/librustc_mir/transform/erase_regions.rs @@ -62,7 +62,7 @@ impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> { pub struct EraseRegions; impl<'tcx> MirPass<'tcx> for EraseRegions { - fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) { - EraseRegionsVisitor::new(tcx).visit_body(body); + fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { + EraseRegionsVisitor::new(tcx).visit_body(body_cache); } } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 37205e65a0a4..503d24e56ae7 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -378,9 +378,9 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> { fn make_generator_state_argument_indirect<'tcx>( tcx: TyCtxt<'tcx>, def_id: DefId, - body: &mut Body<'tcx>, + body_cache: &mut BodyCache<'tcx>, ) { - let gen_ty = body.local_decls.raw[1].ty; + let gen_ty = body_cache.local_decls.raw[1].ty; let region = ty::ReFree(ty::FreeRegion { scope: def_id, @@ -395,14 +395,14 @@ fn make_generator_state_argument_indirect<'tcx>( }); // Replace the by value generator argument - body.local_decls.raw[1].ty = ref_gen_ty; + body_cache.local_decls.raw[1].ty = ref_gen_ty; // Add a deref to accesses of the generator state - DerefArgVisitor { tcx }.visit_body(body); + DerefArgVisitor { tcx }.visit_body(body_cache); } -fn make_generator_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let ref_gen_ty = body.local_decls.raw[1].ty; +fn make_generator_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body_cache: &mut BodyCache<'tcx>) { + let ref_gen_ty = body_cache.local_decls.raw[1].ty; let pin_did = tcx.lang_items().pin_type().unwrap(); let pin_adt_ref = tcx.adt_def(pin_did); @@ -410,18 +410,18 @@ fn make_generator_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body let pin_ref_gen_ty = tcx.mk_adt(pin_adt_ref, substs); // Replace the by ref generator argument - body.local_decls.raw[1].ty = pin_ref_gen_ty; + body_cache.local_decls.raw[1].ty = pin_ref_gen_ty; // Add the Pin field access to accesses of the generator state - PinArgVisitor { ref_gen_ty, tcx }.visit_body(body); + PinArgVisitor { ref_gen_ty, tcx }.visit_body(body_cache); } fn replace_result_variable<'tcx>( ret_ty: Ty<'tcx>, - body: &mut Body<'tcx>, + body_cache: &mut BodyCache<'tcx>, tcx: TyCtxt<'tcx>, ) -> Local { - let source_info = source_info(body); + let source_info = source_info(body_cache); let new_ret = LocalDecl { mutability: Mutability::Mut, ty: ret_ty, @@ -431,15 +431,15 @@ fn replace_result_variable<'tcx>( is_block_tail: None, local_info: LocalInfo::Other }; - let new_ret_local = Local::new(body.local_decls.len()); - body.local_decls.push(new_ret); - body.local_decls.swap(RETURN_PLACE, new_ret_local); + let new_ret_local = Local::new(body_cache.local_decls.len()); + body_cache.local_decls.push(new_ret); + body_cache.local_decls.swap(RETURN_PLACE, new_ret_local); RenameLocalVisitor { from: RETURN_PLACE, to: new_ret_local, tcx, - }.visit_body(body); + }.visit_body(body_cache); new_ret_local } @@ -481,12 +481,13 @@ struct LivenessInfo { fn locals_live_across_suspend_points( tcx: TyCtxt<'tcx>, - body: &Body<'tcx>, + body_cache: ReadOnlyBodyCache<'_, 'tcx>, source: MirSource<'tcx>, movable: bool, ) -> LivenessInfo { - let dead_unwinds = BitSet::new_empty(body.basic_blocks().len()); + let dead_unwinds = BitSet::new_empty(body_cache.basic_blocks().len()); let def_id = source.def_id(); + let body = body_cache.body(); // Calculate when MIR locals have live storage. This gives us an upper bound of their // lifetimes. @@ -498,8 +499,8 @@ fn locals_live_across_suspend_points( // Find the MIR locals which do not use StorageLive/StorageDead statements. // The storage of these locals are always live. - let mut ignored = StorageIgnored(BitSet::new_filled(body.local_decls.len())); - ignored.visit_body(body); + let mut ignored = StorageIgnored(BitSet::new_filled(body_cache.local_decls.len())); + ignored.visit_body(body_cache); // Calculate the MIR locals which have been previously // borrowed (even if they are still active). @@ -511,16 +512,16 @@ fn locals_live_across_suspend_points( // Calculate the MIR locals that we actually need to keep storage around // for. - let requires_storage_analysis = RequiresStorage::new(body, &borrowed_locals_results); + let requires_storage_analysis = RequiresStorage::new(body_cache, &borrowed_locals_results); let requires_storage_results = do_dataflow(tcx, body, def_id, &[], &dead_unwinds, requires_storage_analysis, |bd, p| DebugFormatted::new(&bd.body().local_decls[p])); let mut requires_storage_cursor = DataflowResultsCursor::new(&requires_storage_results, body); // Calculate the liveness of MIR locals ignoring borrows. - let mut live_locals = liveness::LiveVarSet::new_empty(body.local_decls.len()); + let mut live_locals = liveness::LiveVarSet::new_empty(body_cache.local_decls.len()); let mut liveness = liveness::liveness_of_locals( - body, + body_cache, ); liveness::dump_mir( tcx, @@ -533,7 +534,7 @@ fn locals_live_across_suspend_points( let mut storage_liveness_map = FxHashMap::default(); let mut live_locals_at_suspension_points = Vec::new(); - for (block, data) in body.basic_blocks().iter_enumerated() { + for (block, data) in body_cache.basic_blocks().iter_enumerated() { if let TerminatorKind::Yield { .. } = data.terminator().kind { let loc = Location { block: block, @@ -749,7 +750,7 @@ fn compute_layout<'tcx>( upvars: &Vec>, interior: Ty<'tcx>, movable: bool, - body: &mut Body<'tcx>, + body_cache: &mut BodyCache<'tcx>, ) -> ( FxHashMap, VariantIdx, usize)>, GeneratorLayout<'tcx>, @@ -758,7 +759,7 @@ fn compute_layout<'tcx>( // Use a liveness analysis to compute locals which are live across a suspension point let LivenessInfo { live_locals, live_locals_at_suspension_points, storage_conflicts, storage_liveness - } = locals_live_across_suspend_points(tcx, body, source, movable); + } = locals_live_across_suspend_points(tcx, body_cache.read_only(), source, movable); // Erase regions from the types passed in from typeck so we can compare them with // MIR types @@ -768,7 +769,7 @@ fn compute_layout<'tcx>( _ => bug!(), }; - for (local, decl) in body.local_decls.iter_enumerated() { + for (local, decl) in body_cache.local_decls.iter_enumerated() { // Ignore locals which are internal or not live if !live_locals.contains(local) || decl.internal { continue; @@ -777,7 +778,7 @@ fn compute_layout<'tcx>( // Sanity check that typeck knows about the type of locals which are // live across a suspension point if !allowed.contains(&decl.ty) && !allowed_upvars.contains(&decl.ty) { - span_bug!(body.span, + span_bug!(body_cache.span, "Broken MIR: generator contains type {} in MIR, \ but typeck only knows about {}", decl.ty, @@ -790,7 +791,7 @@ fn compute_layout<'tcx>( let mut tys = IndexVec::::new(); for (idx, local) in live_locals.iter().enumerate() { locals.push(local); - tys.push(body.local_decls[local].ty); + tys.push(body_cache.local_decls[local].ty); debug!("generator saved local {:?} => {:?}", GeneratorSavedLocal::from(idx), local); } @@ -828,13 +829,13 @@ fn compute_layout<'tcx>( } fn insert_switch<'tcx>( - body: &mut Body<'tcx>, + body_cache: &mut BodyCache<'tcx>, cases: Vec<(usize, BasicBlock)>, transform: &TransformVisitor<'tcx>, default: TerminatorKind<'tcx>, ) { - let default_block = insert_term_block(body, default); - let (assign, discr) = transform.get_discr(body); + let default_block = insert_term_block(body_cache, default); + let (assign, discr) = transform.get_discr(body_cache); let switch = TerminatorKind::SwitchInt { discr: Operand::Move(discr), switch_ty: transform.discr_ty, @@ -842,8 +843,8 @@ fn insert_switch<'tcx>( targets: cases.iter().map(|&(_, d)| d).chain(iter::once(default_block)).collect(), }; - let source_info = source_info(body); - body.basic_blocks_mut().raw.insert(0, BasicBlockData { + let source_info = source_info(body_cache); + body_cache.basic_blocks_mut().raw.insert(0, BasicBlockData { statements: vec![assign], terminator: Some(Terminator { source_info, @@ -852,14 +853,14 @@ fn insert_switch<'tcx>( is_cleanup: false, }); - let blocks = body.basic_blocks_mut().iter_mut(); + let blocks = body_cache.basic_blocks_mut().iter_mut(); for target in blocks.flat_map(|b| b.terminator_mut().successors_mut()) { *target = BasicBlock::new(target.index() + 1); } } -fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, body: &mut Body<'tcx>) { +fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, body_cache: &mut BodyCache<'tcx>) { use crate::util::elaborate_drops::{elaborate_drop, Unwind}; use crate::util::patch::MirPatch; use crate::shim::DropShimElaborator; @@ -872,13 +873,13 @@ fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, body: &mut let gen = self_arg(); let mut elaborator = DropShimElaborator { - body: body, - patch: MirPatch::new(body), + body: body_cache, + patch: MirPatch::new(body_cache), tcx, param_env }; - for (block, block_data) in body.basic_blocks().iter_enumerated() { + for (block, block_data) in body_cache.basic_blocks().iter_enumerated() { let (target, unwind, source_info) = match block_data.terminator() { Terminator { source_info, @@ -915,7 +916,7 @@ fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, body: &mut block, ); } - elaborator.patch.apply(body); + elaborator.patch.apply(body_cache); } fn create_generator_drop_shim<'tcx>( @@ -924,23 +925,23 @@ fn create_generator_drop_shim<'tcx>( def_id: DefId, source: MirSource<'tcx>, gen_ty: Ty<'tcx>, - body: &Body<'tcx>, + body_cache: &mut BodyCache<'tcx>, drop_clean: BasicBlock, -) -> Body<'tcx> { - let mut body = body.clone(); +) -> BodyCache<'tcx> { + let mut body_cache = body_cache.clone(); - let source_info = source_info(&body); + let source_info = source_info(body_cache.body()); - let mut cases = create_cases(&mut body, transform, |point| point.drop); + let mut cases = create_cases(&mut body_cache, transform, |point| point.drop); cases.insert(0, (UNRESUMED, drop_clean)); // The returned state and the poisoned state fall through to the default // case which is just to return - insert_switch(&mut body, cases, &transform, TerminatorKind::Return); + insert_switch(&mut body_cache, cases, &transform, TerminatorKind::Return); - for block in body.basic_blocks_mut() { + for block in body_cache.basic_blocks_mut() { let kind = &mut block.terminator_mut().kind; if let TerminatorKind::GeneratorDrop = *kind { *kind = TerminatorKind::Return; @@ -948,7 +949,7 @@ fn create_generator_drop_shim<'tcx>( } // Replace the return variable - body.local_decls[RETURN_PLACE] = LocalDecl { + body_cache.local_decls[RETURN_PLACE] = LocalDecl { mutability: Mutability::Mut, ty: tcx.mk_unit(), user_ty: UserTypeProjections::none(), @@ -958,10 +959,10 @@ fn create_generator_drop_shim<'tcx>( local_info: LocalInfo::Other }; - make_generator_state_argument_indirect(tcx, def_id, &mut body); + make_generator_state_argument_indirect(tcx, def_id, &mut body_cache); // Change the generator argument from &mut to *mut - body.local_decls[self_arg()] = LocalDecl { + body_cache.local_decls[self_arg()] = LocalDecl { mutability: Mutability::Mut, ty: tcx.mk_ptr(ty::TypeAndMut { ty: gen_ty, @@ -975,27 +976,27 @@ fn create_generator_drop_shim<'tcx>( }; if tcx.sess.opts.debugging_opts.mir_emit_retag { // Alias tracking must know we changed the type - body.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement { + body_cache.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement { source_info, kind: StatementKind::Retag(RetagKind::Raw, box Place::from(self_arg())), }) } - no_landing_pads(tcx, &mut body); + no_landing_pads(tcx, &mut body_cache); // Make sure we remove dead blocks to remove // unrelated code from the resume part of the function - simplify::remove_dead_blocks(&mut body); + simplify::remove_dead_blocks(&mut body_cache); - dump_mir(tcx, None, "generator_drop", &0, source, &mut body, |_, _| Ok(()) ); + dump_mir(tcx, None, "generator_drop", &0, source, &mut body_cache, |_, _| Ok(()) ); - body + body_cache } -fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) -> BasicBlock { - let term_block = BasicBlock::new(body.basic_blocks().len()); - let source_info = source_info(body); - body.basic_blocks_mut().push(BasicBlockData { +fn insert_term_block<'tcx>(body_cache: &mut BodyCache<'tcx>, kind: TerminatorKind<'tcx>) -> BasicBlock { + let term_block = BasicBlock::new(body_cache.basic_blocks().len()); + let source_info = source_info(body_cache); + body_cache.basic_blocks_mut().push(BasicBlockData { statements: Vec::new(), terminator: Some(Terminator { source_info, @@ -1008,13 +1009,13 @@ fn insert_term_block<'tcx>(body: &mut Body<'tcx>, kind: TerminatorKind<'tcx>) -> fn insert_panic_block<'tcx>( tcx: TyCtxt<'tcx>, - body: &mut Body<'tcx>, + body_cache: &mut BodyCache<'tcx>, message: AssertMessage<'tcx>, ) -> BasicBlock { - let assert_block = BasicBlock::new(body.basic_blocks().len()); + let assert_block = BasicBlock::new(body_cache.basic_blocks().len()); let term = TerminatorKind::Assert { cond: Operand::Constant(box Constant { - span: body.span, + span: body_cache.span, user_ty: None, literal: ty::Const::from_bool(tcx, false), }), @@ -1024,8 +1025,8 @@ fn insert_panic_block<'tcx>( cleanup: None, }; - let source_info = source_info(body); - body.basic_blocks_mut().push(BasicBlockData { + let source_info = source_info(body_cache); + body_cache.basic_blocks_mut().push(BasicBlockData { statements: Vec::new(), terminator: Some(Terminator { source_info, @@ -1042,10 +1043,10 @@ fn create_generator_resume_function<'tcx>( transform: TransformVisitor<'tcx>, def_id: DefId, source: MirSource<'tcx>, - body: &mut Body<'tcx>, + body_cache: &mut BodyCache<'tcx>, ) { // Poison the generator when it unwinds - for block in body.basic_blocks_mut() { + for block in body_cache.basic_blocks_mut() { let source_info = block.terminator().source_info; if let &TerminatorKind::Resume = &block.terminator().kind { block.statements.push( @@ -1053,7 +1054,7 @@ fn create_generator_resume_function<'tcx>( } } - let mut cases = create_cases(body, &transform, |point| Some(point.resume)); + let mut cases = create_cases(body_cache, &transform, |point| Some(point.resume)); use rustc::mir::interpret::PanicInfo::{ ResumedAfterPanic, @@ -1067,25 +1068,25 @@ fn create_generator_resume_function<'tcx>( let generator_kind = body.generator_kind.unwrap(); cases.insert(1, (RETURNED, insert_panic_block( tcx, - body, + body_cache, ResumedAfterReturn(generator_kind)))); cases.insert(2, (POISONED, insert_panic_block( tcx, - body, + body_cache, ResumedAfterPanic(generator_kind)))); - insert_switch(body, cases, &transform, TerminatorKind::Unreachable); + insert_switch(body_cache, cases, &transform, TerminatorKind::Unreachable); - make_generator_state_argument_indirect(tcx, def_id, body); - make_generator_state_argument_pinned(tcx, body); + make_generator_state_argument_indirect(tcx, def_id, body_cache); + make_generator_state_argument_pinned(tcx, body_cache); - no_landing_pads(tcx, body); + no_landing_pads(tcx, body_cache); // Make sure we remove dead blocks to remove // unrelated code from the drop part of the function - simplify::remove_dead_blocks(body); + simplify::remove_dead_blocks(body_cache); - dump_mir(tcx, None, "generator_resume", &0, source, body, |_, _| Ok(()) ); + dump_mir(tcx, None, "generator_resume", &0, source, body_cache, |_, _| Ok(()) ); } fn source_info(body: &Body<'_>) -> SourceInfo { @@ -1095,18 +1096,18 @@ fn source_info(body: &Body<'_>) -> SourceInfo { } } -fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock { - let return_block = insert_term_block(body, TerminatorKind::Return); +fn insert_clean_drop(body_cache: &mut BodyCache<'_>) -> BasicBlock { + let return_block = insert_term_block(body_cache, TerminatorKind::Return); // Create a block to destroy an unresumed generators. This can only destroy upvars. - let drop_clean = BasicBlock::new(body.basic_blocks().len()); + let drop_clean = BasicBlock::new(body_cache.basic_blocks().len()); let term = TerminatorKind::Drop { location: Place::from(self_arg()), target: return_block, unwind: None, }; - let source_info = source_info(body); - body.basic_blocks_mut().push(BasicBlockData { + let source_info = source_info(body_cache); + body_cache.basic_blocks_mut().push(BasicBlockData { statements: Vec::new(), terminator: Some(Terminator { source_info, @@ -1119,23 +1120,23 @@ fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock { } fn create_cases<'tcx, F>( - body: &mut Body<'tcx>, + body_cache: &mut BodyCache<'tcx>, transform: &TransformVisitor<'tcx>, target: F, ) -> Vec<(usize, BasicBlock)> where F: Fn(&SuspensionPoint) -> Option, { - let source_info = source_info(body); + let source_info = source_info(body_cache); transform.suspension_points.iter().filter_map(|point| { // Find the target for this suspension point, if applicable target(point).map(|target| { - let block = BasicBlock::new(body.basic_blocks().len()); + let block = BasicBlock::new(body_cache.basic_blocks().len()); let mut statements = Vec::new(); // Create StorageLive instructions for locals with live storage - for i in 0..(body.local_decls.len()) { + for i in 0..(body_cache.local_decls.len()) { let l = Local::new(i); if point.storage_liveness.contains(l) && !transform.remap.contains_key(&l) { statements.push(Statement { @@ -1146,7 +1147,7 @@ where } // Then jump to the real target - body.basic_blocks_mut().push(BasicBlockData { + body_cache.basic_blocks_mut().push(BasicBlockData { statements, terminator: Some(Terminator { source_info, @@ -1163,20 +1164,20 @@ where } impl<'tcx> MirPass<'tcx> for StateTransform { - fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) { - let yield_ty = if let Some(yield_ty) = body.yield_ty { + fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { + let yield_ty = if let Some(yield_ty) = body_cache.yield_ty { yield_ty } else { // This only applies to generators return }; - assert!(body.generator_drop.is_none()); + assert!(body_cache.generator_drop.is_none()); let def_id = source.def_id(); // The first argument is the generator type passed by value - let gen_ty = body.local_decls.raw[1].ty; + let gen_ty = body_cache.local_decls.raw[1].ty; // Get the interior types and substs which typeck computed let (upvars, interior, discr_ty, movable) = match gen_ty.kind { @@ -1195,13 +1196,13 @@ impl<'tcx> MirPass<'tcx> for StateTransform { let state_adt_ref = tcx.adt_def(state_did); let state_substs = tcx.intern_substs(&[ yield_ty.into(), - body.return_ty().into(), + body_cache.return_ty().into(), ]); let ret_ty = tcx.mk_adt(state_adt_ref, state_substs); // We rename RETURN_PLACE which has type mir.return_ty to new_ret_local // RETURN_PLACE then is a fresh unused local with type ret_ty. - let new_ret_local = replace_result_variable(ret_ty, body, tcx); + let new_ret_local = replace_result_variable(ret_ty, body_cache, tcx); // Extract locals which are live across suspension point into `layout` // `remap` gives a mapping from local indices onto generator struct indices @@ -1212,7 +1213,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform { &upvars, interior, movable, - body); + body_cache); // Run the transformation which converts Places from Local to generator struct // accesses for locals in `remap`. @@ -1228,40 +1229,40 @@ impl<'tcx> MirPass<'tcx> for StateTransform { new_ret_local, discr_ty, }; - transform.visit_body(body); + transform.visit_body(body_cache); // Update our MIR struct to reflect the changed we've made - body.yield_ty = None; - body.arg_count = 1; - body.spread_arg = None; - body.generator_layout = Some(layout); + body_cache.yield_ty = None; + body_cache.arg_count = 1; + body_cache.spread_arg = None; + body_cache.generator_layout = Some(layout); // Insert `drop(generator_struct)` which is used to drop upvars for generators in // the unresumed state. // This is expanded to a drop ladder in `elaborate_generator_drops`. - let drop_clean = insert_clean_drop(body); + let drop_clean = insert_clean_drop(body_cache); - dump_mir(tcx, None, "generator_pre-elab", &0, source, body, |_, _| Ok(()) ); + dump_mir(tcx, None, "generator_pre-elab", &0, source, body_cache, |_, _| Ok(()) ); // Expand `drop(generator_struct)` to a drop ladder which destroys upvars. // If any upvars are moved out of, drop elaboration will handle upvar destruction. // However we need to also elaborate the code generated by `insert_clean_drop`. - elaborate_generator_drops(tcx, def_id, body); + elaborate_generator_drops(tcx, def_id, body_cache); - dump_mir(tcx, None, "generator_post-transform", &0, source, body, |_, _| Ok(()) ); + dump_mir(tcx, None, "generator_post-transform", &0, source, body_cache, |_, _| Ok(()) ); // Create a copy of our MIR and use it to create the drop shim for the generator let drop_shim = create_generator_drop_shim(tcx, - &transform, - def_id, - source, - gen_ty, - &body, - drop_clean); + &transform, + def_id, + source, + gen_ty, + body_cache, + drop_clean); - body.generator_drop = Some(box drop_shim); + body_cache.generator_drop = Some(box drop_shim); // Create the Generator::resume function - create_generator_resume_function(tcx, transform, def_id, source, body); + create_generator_resume_function(tcx, transform, def_id, source, body_cache); } } diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index ebfadd0cfd3e..c1c3d39bdc08 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -38,9 +38,9 @@ struct CallSite<'tcx> { } impl<'tcx> MirPass<'tcx> for Inline { - fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { if tcx.sess.opts.debugging_opts.mir_opt_level >= 2 { - Inliner { tcx, source }.run_pass(body); + Inliner { tcx, source }.run_pass(body_cache); } } } @@ -51,7 +51,7 @@ struct Inliner<'tcx> { } impl Inliner<'tcx> { - fn run_pass(&self, caller_body: &mut Body<'tcx>) { + fn run_pass(&self, caller_body_cache: &mut BodyCache<'tcx>) { // Keep a queue of callsites to try inlining on. We take // advantage of the fact that queries detect cycles here to // allow us to try and fetch the fully optimized MIR of a @@ -73,11 +73,11 @@ impl Inliner<'tcx> { if self.tcx.hir().body_owner_kind(id).is_fn_or_closure() && self.source.promoted.is_none() { - for (bb, bb_data) in caller_body.basic_blocks().iter_enumerated() { + for (bb, bb_data) in caller_body_cache.basic_blocks().iter_enumerated() { if let Some(callsite) = self.get_valid_function_call(bb, - bb_data, - caller_body, - param_env) { + bb_data, + caller_body_cache, + param_env) { callsites.push_back(callsite); } } @@ -127,19 +127,19 @@ impl Inliner<'tcx> { continue; }; - let start = caller_body.basic_blocks().len(); + let start = caller_body_cache.basic_blocks().len(); debug!("attempting to inline callsite {:?} - body={:?}", callsite, callee_body); - if !self.inline_call(callsite, caller_body, callee_body) { + if !self.inline_call(callsite, caller_body_cache, callee_body) { debug!("attempting to inline callsite {:?} - failure", callsite); continue; } debug!("attempting to inline callsite {:?} - success", callsite); // Add callsites from inlined function - for (bb, bb_data) in caller_body.basic_blocks().iter_enumerated().skip(start) { + for (bb, bb_data) in caller_body_cache.basic_blocks().iter_enumerated().skip(start) { if let Some(new_callsite) = self.get_valid_function_call(bb, bb_data, - caller_body, + caller_body_cache, param_env) { // Don't inline the same function multiple times. if callsite.callee != new_callsite.callee { @@ -160,8 +160,8 @@ impl Inliner<'tcx> { // Simplify if we inlined anything. if changed { debug!("running simplify cfg on {:?}", self.source); - CfgSimplifier::new(caller_body).simplify(); - remove_dead_blocks(caller_body); + CfgSimplifier::new(caller_body_cache).simplify(); + remove_dead_blocks(caller_body_cache); } } @@ -377,23 +377,23 @@ impl Inliner<'tcx> { fn inline_call(&self, callsite: CallSite<'tcx>, - caller_body: &mut Body<'tcx>, - mut callee_body: Body<'tcx>) -> bool { + caller_body: &mut BodyCache<'tcx>, + mut callee_body_cache: BodyCache<'tcx>) -> bool { let terminator = caller_body[callsite.bb].terminator.take().unwrap(); match terminator.kind { // FIXME: Handle inlining of diverging calls TerminatorKind::Call { args, destination: Some(destination), cleanup, .. } => { debug!("inlined {:?} into {:?}", callsite.callee, self.source); - let mut local_map = IndexVec::with_capacity(callee_body.local_decls.len()); - let mut scope_map = IndexVec::with_capacity(callee_body.source_scopes.len()); + let mut local_map = IndexVec::with_capacity(callee_body_cache.local_decls.len()); + let mut scope_map = IndexVec::with_capacity(callee_body_cache.source_scopes.len()); - for mut scope in callee_body.source_scopes.iter().cloned() { + for mut scope in callee_body_cache.source_scopes.iter().cloned() { if scope.parent_scope.is_none() { scope.parent_scope = Some(callsite.location.scope); // FIXME(eddyb) is this really needed? // (also note that it's always overwritten below) - scope.span = callee_body.span; + scope.span = callee_body_cache.span; } // FIXME(eddyb) this doesn't seem right at all. @@ -405,8 +405,8 @@ impl Inliner<'tcx> { scope_map.push(idx); } - for loc in callee_body.vars_and_temps_iter() { - let mut local = callee_body.local_decls[loc].clone(); + for loc in callee_body_cache.vars_and_temps_iter() { + let mut local = callee_body_cache.local_decls[loc].clone(); local.source_info.scope = scope_map[local.source_info.scope]; @@ -445,7 +445,7 @@ impl Inliner<'tcx> { BorrowKind::Mut { allow_two_phase_borrow: false }, destination.0); - let ty = dest.ty(caller_body, self.tcx); + let ty = dest.ty(caller_body.body(), self.tcx); let temp = LocalDecl::new_temp(ty, callsite.location.span); @@ -486,7 +486,7 @@ impl Inliner<'tcx> { caller_body.var_debug_info.push(var_debug_info); } - for (bb, mut block) in callee_body.basic_blocks_mut().drain_enumerated(..) { + for (bb, mut block) in callee_body_cache.basic_blocks_mut().drain_enumerated(..) { integrator.visit_basic_block_data(bb, &mut block); caller_body.basic_blocks_mut().push(block); } diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs index a567ed668bfa..e466b0cb77b7 100644 --- a/src/librustc_mir/transform/instcombine.rs +++ b/src/librustc_mir/transform/instcombine.rs @@ -1,7 +1,8 @@ //! Performs various peephole optimizations. use rustc::mir::{ - Constant, Location, Place, PlaceBase, PlaceRef, Body, Operand, ProjectionElem, Rvalue, Local + Constant, Location, Place, PlaceBase, PlaceRef, Body, BodyCache, Operand, ProjectionElem, + Rvalue, Local }; use rustc::mir::visit::{MutVisitor, Visitor}; use rustc::ty::{self, TyCtxt}; @@ -13,7 +14,7 @@ use crate::transform::{MirPass, MirSource}; pub struct InstCombine; impl<'tcx> MirPass<'tcx> for InstCombine { - fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { // We only run when optimizing MIR (at any level). if tcx.sess.opts.debugging_opts.mir_opt_level == 0 { return @@ -23,13 +24,13 @@ impl<'tcx> MirPass<'tcx> for InstCombine { // read-only so that we can do global analyses on the MIR in the process (e.g. // `Place::ty()`). let optimizations = { - let mut optimization_finder = OptimizationFinder::new(body, tcx); - optimization_finder.visit_body(body); + let mut optimization_finder = OptimizationFinder::new(body_cache, tcx); + optimization_finder.visit_body(body_cache.read_only()); optimization_finder.optimizations }; // Then carry out those optimizations. - MutVisitor::visit_body(&mut InstCombineVisitor { optimizations, tcx }, body); + MutVisitor::visit_body(&mut InstCombineVisitor { optimizations, tcx }, body_cache); } } diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 1eac40fc591a..97c4efc08a37 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -1,7 +1,7 @@ use crate::{build, shim}; use rustc_index::vec::IndexVec; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; -use rustc::mir::{Body, MirPhase, Promoted, ConstQualifs}; +use rustc::mir::{BodyCache, MirPhase, Promoted, ConstQualifs}; use rustc::ty::{TyCtxt, InstanceDef, TypeFoldable}; use rustc::ty::query::Providers; use rustc::ty::steal::Steal; @@ -97,7 +97,7 @@ fn mir_keys(tcx: TyCtxt<'_>, krate: CrateNum) -> &DefIdSet { tcx.arena.alloc(set) } -fn mir_built(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal> { +fn mir_built(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal> { let mir = build::mir_build(tcx, def_id); tcx.alloc_steal_mir(mir) } @@ -144,12 +144,12 @@ pub trait MirPass<'tcx> { default_name::() } - fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>); + fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut BodyCache<'tcx>); } pub fn run_passes( tcx: TyCtxt<'tcx>, - body: &mut Body<'tcx>, + body: &mut BodyCache<'tcx>, instance: InstanceDef<'tcx>, promoted: Option, mir_phase: MirPhase, @@ -220,47 +220,47 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def_id: DefId) -> ConstQualifs { validator.qualifs_in_return_place().into() } -fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal> { +fn mir_const(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal> { // Unsafety check uses the raw mir, so make sure it is run let _ = tcx.unsafety_check_result(def_id); - let mut body = tcx.mir_built(def_id).steal(); - run_passes(tcx, &mut body, InstanceDef::Item(def_id), None, MirPhase::Const, &[ + let mut body_cache = tcx.mir_built(def_id).steal(); + run_passes(tcx, &mut body_cache, InstanceDef::Item(def_id), None, MirPhase::Const, &[ // What we need to do constant evaluation. &simplify::SimplifyCfg::new("initial"), &rustc_peek::SanityCheck, &uniform_array_move_out::UniformArrayMoveOut, ]); - tcx.alloc_steal_mir(body) + tcx.alloc_steal_mir(body_cache) } fn mir_validated( tcx: TyCtxt<'tcx>, def_id: DefId, -) -> (&'tcx Steal>, &'tcx Steal>>) { +) -> (&'tcx Steal>, &'tcx Steal>>) { // Ensure that we compute the `mir_const_qualif` for constants at // this point, before we steal the mir-const result. let _ = tcx.mir_const_qualif(def_id); - let mut body = tcx.mir_const(def_id).steal(); + let mut body_cache = tcx.mir_const(def_id).steal(); let promote_pass = promote_consts::PromoteTemps::default(); - run_passes(tcx, &mut body, InstanceDef::Item(def_id), None, MirPhase::Validated, &[ + run_passes(tcx, &mut body_cache, InstanceDef::Item(def_id), None, MirPhase::Validated, &[ // What we need to run borrowck etc. &promote_pass, &simplify::SimplifyCfg::new("qualify-consts"), ]); let promoted = promote_pass.promoted_fragments.into_inner(); - (tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted)) + (tcx.alloc_steal_mir(body_cache), tcx.alloc_steal_promoted(promoted)) } fn run_optimization_passes<'tcx>( tcx: TyCtxt<'tcx>, - body: &mut Body<'tcx>, + body_cache: &mut BodyCache<'tcx>, def_id: DefId, promoted: Option, ) { - run_passes(tcx, body, InstanceDef::Item(def_id), promoted, MirPhase::Optimized, &[ + run_passes(tcx, body_cache, InstanceDef::Item(def_id), promoted, MirPhase::Optimized, &[ // Remove all things only needed by analysis &no_landing_pads::NoLandingPads::new(tcx), &simplify_branches::SimplifyBranches::new("initial"), @@ -318,7 +318,7 @@ fn run_optimization_passes<'tcx>( ]); } -fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> { +fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &BodyCache<'_> { if tcx.is_constructor(def_id) { // There's no reason to run all of the MIR passes on constructors when // we can just output the MIR we want directly. This also saves const @@ -332,12 +332,12 @@ fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> &Body<'_> { tcx.ensure().mir_borrowck(def_id); let (body, _) = tcx.mir_validated(def_id); - let mut body = body.steal(); - run_optimization_passes(tcx, &mut body, def_id, None); - tcx.arena.alloc(body) + let mut body_cache = body.steal(); + run_optimization_passes(tcx, &mut body_cache, def_id, None); + tcx.arena.alloc(body_cache) } -fn promoted_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx IndexVec> { +fn promoted_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx IndexVec> { if tcx.is_constructor(def_id) { return tcx.intern_promoted(IndexVec::new()); } @@ -346,8 +346,8 @@ fn promoted_mir<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> &'tcx IndexVec NoLandingPads<'tcx> { } impl<'tcx> MirPass<'tcx> for NoLandingPads<'tcx> { - fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { no_landing_pads(tcx, body) } } -pub fn no_landing_pads<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { +pub fn no_landing_pads<'tcx>(tcx: TyCtxt<'tcx>, body_cache: &mut BodyCache<'tcx>) { if tcx.sess.no_landing_pads() { - NoLandingPads::new(tcx).visit_body(body); + NoLandingPads::new(tcx).visit_body(body_cache); } } diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs index 591f3ca44009..e409bb084290 100644 --- a/src/librustc_mir/transform/promote_consts.rs +++ b/src/librustc_mir/transform/promote_consts.rs @@ -770,8 +770,8 @@ pub fn validate_candidates( struct Promoter<'a, 'tcx> { tcx: TyCtxt<'tcx>, - source: &'a mut Body<'tcx>, - promoted: Body<'tcx>, + source_cache: &'a mut BodyCache<'tcx>, + promoted_cache: BodyCache<'tcx>, temps: &'a mut IndexVec, /// If true, all nested temps are also kept in the @@ -781,8 +781,8 @@ struct Promoter<'a, 'tcx> { impl<'a, 'tcx> Promoter<'a, 'tcx> { fn new_block(&mut self) -> BasicBlock { - let span = self.promoted.span; - self.promoted.basic_blocks_mut().push(BasicBlockData { + let span = self.promoted_cache.span; + self.promoted_cache.basic_blocks_mut().push(BasicBlockData { statements: vec![], terminator: Some(Terminator { source_info: SourceInfo { @@ -796,8 +796,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { } fn assign(&mut self, dest: Local, rvalue: Rvalue<'tcx>, span: Span) { - let last = self.promoted.basic_blocks().last().unwrap(); - let data = &mut self.promoted[last]; + let last = self.promoted_cache.basic_blocks().last().unwrap(); + let data = &mut self.promoted_cache[last]; data.statements.push(Statement { source_info: SourceInfo { span, @@ -808,7 +808,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { } fn is_temp_kind(&self, local: Local) -> bool { - self.source.local_kind(local) == LocalKind::Temp + self.source_cache.local_kind(local) == LocalKind::Temp } /// Copies the initialization of this temp to the @@ -823,7 +823,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { location } state => { - span_bug!(self.promoted.span, "{:?} not promotable: {:?}", + span_bug!(self.promoted_cache.span, "{:?} not promotable: {:?}", temp, state); } }; @@ -831,10 +831,10 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { self.temps[temp] = TempState::PromotedOut; } - let num_stmts = self.source[loc.block].statements.len(); - let new_temp = self.promoted.local_decls.push( - LocalDecl::new_temp(self.source.local_decls[temp].ty, - self.source.local_decls[temp].source_info.span)); + let num_stmts = self.source_cacje[loc.block].statements.len(); + let new_temp = self.promoted_cache.local_decls.push( + LocalDecl::new_temp(self.source_cache.local_decls[temp].ty, + self.source_cache.local_decls[temp].source_info.span)); debug!("promote({:?} @ {:?}/{:?}, {:?})", temp, loc, num_stmts, self.keep_original); @@ -843,7 +843,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { // or duplicate it, depending on keep_original. if loc.statement_index < num_stmts { let (mut rvalue, source_info) = { - let statement = &mut self.source[loc.block].statements[loc.statement_index]; + let statement = &mut self.source_cache[loc.block].statements[loc.statement_index]; let rhs = match statement.kind { StatementKind::Assign(box(_, ref mut rhs)) => rhs, _ => { @@ -864,9 +864,9 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { self.assign(new_temp, rvalue, source_info.span); } else { let terminator = if self.keep_original { - self.source[loc.block].terminator().clone() + self.source_cache[loc.block].terminator().clone() } else { - let terminator = self.source[loc.block].terminator_mut(); + let terminator = self.source_cache[loc.block].terminator_mut(); let target = match terminator.kind { TerminatorKind::Call { destination: Some((_, target)), .. } => target, ref kind => { @@ -888,10 +888,10 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { self.visit_operand(arg, loc); } - let last = self.promoted.basic_blocks().last().unwrap(); + let last = self.promoted_cache.basic_blocks().last().unwrap(); let new_target = self.new_block(); - *self.promoted[last].terminator_mut() = Terminator { + *self.promoted_cache[last].terminator_mut() = Terminator { kind: TerminatorKind::Call { func, args, @@ -919,9 +919,9 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { def_id: DefId, candidate: Candidate, next_promoted_id: usize, - ) -> Option> { + ) -> Option> { let mut operand = { - let promoted = &mut self.promoted; + let promoted = &mut self.promoted_cache; let promoted_id = Promoted::new(next_promoted_id); let tcx = self.tcx; let mut promoted_place = |ty, span| { @@ -940,7 +940,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { projection: List::empty(), } }; - let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut(); + let (blocks, local_decls) = self.source_cache.basic_blocks_and_local_decls_mut(); match candidate { Candidate::Ref(loc) => { let ref mut statement = blocks[loc.block].statements[loc.statement_index]; @@ -1004,9 +1004,9 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { statement_index: usize::MAX }); - let span = self.promoted.span; + let span = self.promoted_cache.span; self.assign(RETURN_PLACE, Rvalue::Use(operand), span); - Some(self.promoted) + Some(self.promoted_cache) } } @@ -1040,11 +1040,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for Promoter<'a, 'tcx> { pub fn promote_candidates<'tcx>( def_id: DefId, - body: &mut Body<'tcx>, + body_cache: &mut BodyCache<'tcx>, tcx: TyCtxt<'tcx>, mut temps: IndexVec, candidates: Vec, -) -> IndexVec> { +) -> IndexVec> { // Visit candidates in reverse, in case they're nested. debug!("promote_candidates({:?})", candidates); @@ -1054,7 +1054,7 @@ pub fn promote_candidates<'tcx>( match candidate { Candidate::Repeat(Location { block, statement_index }) | Candidate::Ref(Location { block, statement_index }) => { - match &body[block].statements[statement_index].kind { + match &body_cache[block].statements[statement_index].kind { StatementKind::Assign(box(place, _)) => { if let Some(local) = place.as_local() { if temps[local] == TempState::PromotedOut { @@ -1072,25 +1072,26 @@ pub fn promote_candidates<'tcx>( // Declare return place local so that `mir::Body::new` doesn't complain. let initial_locals = iter::once( - LocalDecl::new_return_place(tcx.types.never, body.span) + LocalDecl::new_return_place(tcx.types.never, body_cache.span) ).collect(); let promoter = Promoter { - promoted: Body::new( + promoted_cache: BodyCache::new(Body::new( IndexVec::new(), // FIXME: maybe try to filter this to avoid blowing up // memory usage? - body.source_scopes.clone(), + body_cache.source_scopes.clone(), + body_cache.source_scope_local_data.clone(), initial_locals, IndexVec::new(), 0, vec![], - body.span, + body_cache.span, vec![], - body.generator_kind, - ), + body_cache.generator_kind, + )), tcx, - source: body, + source_cache: body_cache, temps: &mut temps, keep_original: false }; @@ -1103,7 +1104,7 @@ pub fn promote_candidates<'tcx>( // Eliminate assignments to, and drops of promoted temps. let promoted = |index: Local| temps[index] == TempState::PromotedOut; - for block in body.basic_blocks_mut() { + for block in body_cache.basic_blocks_mut() { block.statements.retain(|statement| { match &statement.kind { StatementKind::Assign(box(place, _)) => { diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs index 130393e2c4c8..3a7d7d17f069 100644 --- a/src/librustc_mir/transform/remove_noop_landing_pads.rs +++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs @@ -9,18 +9,18 @@ use crate::util::patch::MirPatch; /// code for these. pub struct RemoveNoopLandingPads; -pub fn remove_noop_landing_pads<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { +pub fn remove_noop_landing_pads<'tcx>(tcx: TyCtxt<'tcx>, body_cache: &mut BodyCache<'tcx>) { if tcx.sess.no_landing_pads() { return } - debug!("remove_noop_landing_pads({:?})", body); + debug!("remove_noop_landing_pads({:?})", body_cache.body()); - RemoveNoopLandingPads.remove_nop_landing_pads(body) + RemoveNoopLandingPads.remove_nop_landing_pads(body_cache) } impl<'tcx> MirPass<'tcx> for RemoveNoopLandingPads { - fn run_pass(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) { - remove_noop_landing_pads(tcx, body); + fn run_pass(&self, tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { + remove_noop_landing_pads(tcx, body_cache); } } @@ -84,26 +84,26 @@ impl RemoveNoopLandingPads { } } - fn remove_nop_landing_pads(&self, body: &mut Body<'_>) { + fn remove_nop_landing_pads(&self, body_cache: &mut BodyCache<'_>) { // make sure there's a single resume block let resume_block = { - let patch = MirPatch::new(body); + let patch = MirPatch::new(body_cache); let resume_block = patch.resume_block(); - patch.apply(body); + patch.apply(body_cache); resume_block }; debug!("remove_noop_landing_pads: resume block is {:?}", resume_block); let mut jumps_folded = 0; let mut landing_pads_removed = 0; - let mut nop_landing_pads = BitSet::new_empty(body.basic_blocks().len()); + let mut nop_landing_pads = BitSet::new_empty(body_cache.basic_blocks().len()); // This is a post-order traversal, so that if A post-dominates B // then A will be visited before B. - let postorder: Vec<_> = traversal::postorder(body).map(|(bb, _)| bb).collect(); + let postorder: Vec<_> = traversal::postorder(body_cache).map(|(bb, _)| bb).collect(); for bb in postorder { debug!(" processing {:?}", bb); - for target in body[bb].terminator_mut().successors_mut() { + for target in body_cache[bb].terminator_mut().successors_mut() { if *target != resume_block && nop_landing_pads.contains(*target) { debug!(" folding noop jump to {:?} to resume block", target); *target = resume_block; @@ -111,7 +111,7 @@ impl RemoveNoopLandingPads { } } - match body[bb].terminator_mut().unwind_mut() { + match body_cache[bb].terminator_mut().unwind_mut() { Some(unwind) => { if *unwind == Some(resume_block) { debug!(" removing noop landing pad"); @@ -123,7 +123,7 @@ impl RemoveNoopLandingPads { _ => {} } - let is_nop_landing_pad = self.is_nop_landing_pad(bb, body, &nop_landing_pads); + let is_nop_landing_pad = self.is_nop_landing_pad(bb, body_cache, &nop_landing_pads); if is_nop_landing_pad { nop_landing_pads.insert(bb); } diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index aada7641df67..87fcef69238d 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -5,7 +5,7 @@ use syntax_pos::Span; use rustc::ty::{self, TyCtxt, Ty}; use rustc::hir::def_id::DefId; -use rustc::mir::{self, Body, Location, Local}; +use rustc::mir::{self, Body, BodyCache, Location, Local}; use rustc_index::bit_set::BitSet; use crate::transform::{MirPass, MirSource}; @@ -26,7 +26,7 @@ use crate::dataflow::has_rustc_mir_with; pub struct SanityCheck; impl<'tcx> MirPass<'tcx> for SanityCheck { - fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { let def_id = src.def_id(); if !tcx.has_attr(def_id, sym::rustc_mir) { debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id)); @@ -37,37 +37,37 @@ impl<'tcx> MirPass<'tcx> for SanityCheck { let attributes = tcx.get_attrs(def_id); let param_env = tcx.param_env(def_id); - let move_data = MoveData::gather_moves(body, tcx).unwrap(); + let move_data = MoveData::gather_moves(body_cache, tcx).unwrap(); let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env }; - let dead_unwinds = BitSet::new_empty(body.basic_blocks().len()); + let dead_unwinds = BitSet::new_empty(body_cache.basic_blocks().len()); let flow_inits = - do_dataflow(tcx, body, def_id, &attributes, &dead_unwinds, - MaybeInitializedPlaces::new(tcx, body, &mdpe), + do_dataflow(tcx, body_cache, def_id, &attributes, &dead_unwinds, + MaybeInitializedPlaces::new(tcx, body_cache, &mdpe), |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i])); let flow_uninits = - do_dataflow(tcx, body, def_id, &attributes, &dead_unwinds, - MaybeUninitializedPlaces::new(tcx, body, &mdpe), + do_dataflow(tcx, body_cache, def_id, &attributes, &dead_unwinds, + MaybeUninitializedPlaces::new(tcx, body_cache, &mdpe), |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i])); let flow_def_inits = - do_dataflow(tcx, body, def_id, &attributes, &dead_unwinds, - DefinitelyInitializedPlaces::new(tcx, body, &mdpe), + do_dataflow(tcx, body_cache, def_id, &attributes, &dead_unwinds, + DefinitelyInitializedPlaces::new(tcx, body_cache, &mdpe), |bd, i| DebugFormatted::new(&bd.move_data().move_paths[i])); let flow_indirectly_mut = - do_dataflow(tcx, body, def_id, &attributes, &dead_unwinds, - IndirectlyMutableLocals::new(tcx, body, param_env), + do_dataflow(tcx, body_cache, def_id, &attributes, &dead_unwinds, + IndirectlyMutableLocals::new(tcx, body_cache, param_env), |_, i| DebugFormatted::new(&i)); if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_init).is_some() { - sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_inits); + sanity_check_via_rustc_peek(tcx, body_cache.body(), def_id, &attributes, &flow_inits); } if has_rustc_mir_with(&attributes, sym::rustc_peek_maybe_uninit).is_some() { - sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_uninits); + sanity_check_via_rustc_peek(tcx, body_cache.body(), def_id, &attributes, &flow_uninits); } if has_rustc_mir_with(&attributes, sym::rustc_peek_definite_init).is_some() { - sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_def_inits); + sanity_check_via_rustc_peek(tcx, body_cache.body(), def_id, &attributes, &flow_def_inits); } if has_rustc_mir_with(&attributes, sym::rustc_peek_indirectly_mutable).is_some() { - sanity_check_via_rustc_peek(tcx, body, def_id, &attributes, &flow_indirectly_mut); + sanity_check_via_rustc_peek(tcx, body_cache.body(), def_id, &attributes, &flow_indirectly_mut); } if has_rustc_mir_with(&attributes, sym::stop_after_dataflow).is_some() { tcx.sess.fatal("stop_after_dataflow ended compilation"); diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs index 040bc5c309a9..75016cf1746c 100644 --- a/src/librustc_mir/transform/simplify.rs +++ b/src/librustc_mir/transform/simplify.rs @@ -43,12 +43,12 @@ impl SimplifyCfg { } } -pub fn simplify_cfg(body: &mut Body<'_>) { - CfgSimplifier::new(body).simplify(); - remove_dead_blocks(body); +pub fn simplify_cfg(body_cache: &mut BodyCache<'_>) { + CfgSimplifier::new(body_cache).simplify(); + remove_dead_blocks(body_cache); // FIXME: Should probably be moved into some kind of pass manager - body.basic_blocks_mut().raw.shrink_to_fit(); + body_cache.basic_blocks_mut().raw.shrink_to_fit(); } impl<'tcx> MirPass<'tcx> for SimplifyCfg { @@ -56,9 +56,9 @@ impl<'tcx> MirPass<'tcx> for SimplifyCfg { Cow::Borrowed(&self.label) } - fn run_pass(&self, _tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body: &mut Body<'tcx>) { - debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, body); - simplify_cfg(body); + fn run_pass(&self, _tcx: TyCtxt<'tcx>, _src: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { + debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, body_cache.body()); + simplify_cfg(body_cache); } } @@ -68,14 +68,14 @@ pub struct CfgSimplifier<'a, 'tcx> { } impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { - pub fn new(body: &'a mut Body<'tcx>) -> Self { - let mut pred_count = IndexVec::from_elem(0u32, body.basic_blocks()); + pub fn new(body_cache: &'a mut BodyCache<'tcx>) -> Self { + let mut pred_count = IndexVec::from_elem(0u32, body_cache.basic_blocks()); // we can't use mir.predecessors() here because that counts // dead blocks, which we don't want to. pred_count[START_BLOCK] = 1; - for (_, data) in traversal::preorder(body) { + for (_, data) in traversal::preorder(body_cache) { if let Some(ref term) = data.terminator { for &tgt in term.successors() { pred_count[tgt] += 1; @@ -83,7 +83,7 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } } - let basic_blocks = body.basic_blocks_mut(); + let basic_blocks = body_cache.basic_blocks_mut(); CfgSimplifier { basic_blocks, @@ -260,13 +260,13 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } } -pub fn remove_dead_blocks(body: &mut Body<'_>) { - let mut seen = BitSet::new_empty(body.basic_blocks().len()); - for (bb, _) in traversal::preorder(body) { +pub fn remove_dead_blocks(body_cache: &mut BodyCache<'_>) { + let mut seen = BitSet::new_empty(body_cache.basic_blocks().len()); + for (bb, _) in traversal::preorder(body_cache.body()) { seen.insert(bb.index()); } - let basic_blocks = body.basic_blocks_mut(); + let basic_blocks = body_cache.basic_blocks_mut(); let num_blocks = basic_blocks.len(); let mut replacements : Vec<_> = (0..num_blocks).map(BasicBlock::new).collect(); @@ -293,27 +293,27 @@ pub fn remove_dead_blocks(body: &mut Body<'_>) { pub struct SimplifyLocals; impl<'tcx> MirPass<'tcx> for SimplifyLocals { - fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut Body<'tcx>) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { trace!("running SimplifyLocals on {:?}", source); let locals = { let mut marker = DeclMarker { - locals: BitSet::new_empty(body.local_decls.len()), - body, + locals: BitSet::new_empty(body_cache.local_decls.len()), + body: body_cache, }; - marker.visit_body(body); + marker.visit_body(body_cache.read_only()); // Return pointer and arguments are always live marker.locals.insert(RETURN_PLACE); - for arg in body.args_iter() { + for arg in body_cache.args_iter() { marker.locals.insert(arg); } marker.locals }; - let map = make_local_map(&mut body.local_decls, locals); + let map = make_local_map(&mut body_cache.local_decls, locals); // Update references to all vars and tmps now - LocalUpdater { map, tcx }.visit_body(body); - body.local_decls.shrink_to_fit(); + LocalUpdater { map, tcx }.visit_body(body_cache); + body_cache.local_decls.shrink_to_fit(); } } diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs index 0a509666d34a..df5d40484bf2 100644 --- a/src/librustc_mir/transform/simplify_branches.rs +++ b/src/librustc_mir/transform/simplify_branches.rs @@ -19,9 +19,9 @@ impl<'tcx> MirPass<'tcx> for SimplifyBranches { Cow::Borrowed(&self.label) } - fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) { + fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { let param_env = tcx.param_env(src.def_id()); - for block in body.basic_blocks_mut() { + for block in body_cache.basic_blocks_mut() { let terminator = block.terminator_mut(); terminator.kind = match terminator.kind { TerminatorKind::SwitchInt { diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs index 28f68ac2de03..d3fbfaf384a9 100644 --- a/src/librustc_mir/transform/uniform_array_move_out.rs +++ b/src/librustc_mir/transform/uniform_array_move_out.rs @@ -37,14 +37,14 @@ use crate::util::patch::MirPatch; pub struct UniformArrayMoveOut; impl<'tcx> MirPass<'tcx> for UniformArrayMoveOut { - fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) { - let mut patch = MirPatch::new(body); + fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { + let mut patch = MirPatch::new(body_cache); let param_env = tcx.param_env(src.def_id()); { - let mut visitor = UniformArrayMoveOutVisitor{body, patch: &mut patch, tcx, param_env}; - visitor.visit_body(body); + let mut visitor = UniformArrayMoveOutVisitor{ body: body_cache, patch: &mut patch, tcx, param_env}; + visitor.visit_body(body_cache.read_only()); } - patch.apply(body); + patch.apply(body_cache); } } @@ -184,18 +184,18 @@ pub struct RestoreSubsliceArrayMoveOut<'tcx> { } impl<'tcx> MirPass<'tcx> for RestoreSubsliceArrayMoveOut<'tcx> { - fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) { - let mut patch = MirPatch::new(body); + fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body_cache: &mut BodyCache<'tcx>) { + let mut patch = MirPatch::new(body_cache); let param_env = tcx.param_env(src.def_id()); { let mut visitor = RestoreDataCollector { - locals_use: IndexVec::from_elem(LocalUse::new(), &body.local_decls), + locals_use: IndexVec::from_elem(LocalUse::new(), &body_cache.local_decls), candidates: vec![], }; - visitor.visit_body(body); + visitor.visit_body(body_cache.read_only()); for candidate in &visitor.candidates { - let statement = &body[candidate.block].statements[candidate.statement_index]; + let statement = &body_cache[candidate.block].statements[candidate.statement_index]; if let StatementKind::Assign(box(ref dst_place, ref rval)) = statement.kind { if let Rvalue::Aggregate(box AggregateKind::Array(_), ref items) = *rval { let items : Vec<_> = items.iter().map(|item| { @@ -203,7 +203,7 @@ impl<'tcx> MirPass<'tcx> for RestoreSubsliceArrayMoveOut<'tcx> { if let Some(local) = place.as_local() { let local_use = &visitor.locals_use[local]; let opt_index_and_place = - Self::try_get_item_source(local_use, body); + Self::try_get_item_source(local_use, body_cache); // each local should be used twice: // in assign and in aggregate statements if local_use.use_count == 2 && opt_index_and_place.is_some() { @@ -218,7 +218,7 @@ impl<'tcx> MirPass<'tcx> for RestoreSubsliceArrayMoveOut<'tcx> { let opt_src_place = items.first().and_then(|x| *x).map(|x| x.2); let opt_size = opt_src_place.and_then(|src_place| { let src_ty = - Place::ty_from(src_place.base, src_place.projection, body, tcx).ty; + Place::ty_from(src_place.base, src_place.projection, body_cache.body(), tcx).ty; if let ty::Array(_, ref size_o) = src_ty.kind { size_o.try_eval_usize(tcx, param_env) } else { @@ -232,7 +232,7 @@ impl<'tcx> MirPass<'tcx> for RestoreSubsliceArrayMoveOut<'tcx> { } } } - patch.apply(body); + patch.apply(body_cache); } } diff --git a/src/librustc_mir/util/collect_writes.rs b/src/librustc_mir/util/collect_writes.rs index 0092c3c86d71..f94bea200246 100644 --- a/src/librustc_mir/util/collect_writes.rs +++ b/src/librustc_mir/util/collect_writes.rs @@ -12,7 +12,7 @@ crate trait FindAssignments { impl<'a, 'tcx> FindAssignments for ReadOnlyBodyCache<'a, 'tcx>{ fn find_assignments(&self, local: Local) -> Vec{ let mut visitor = FindLocalAssignmentVisitor{ needle: local, locations: vec![]}; - visitor.visit_body(self); + visitor.visit_body(*self); visitor.locations } } diff --git a/src/librustc_mir/util/def_use.rs b/src/librustc_mir/util/def_use.rs index 11b61bcd4844..256ba94af44d 100644 --- a/src/librustc_mir/util/def_use.rs +++ b/src/librustc_mir/util/def_use.rs @@ -30,7 +30,7 @@ impl DefUseAnalysis { } } - pub fn analyze(&mut self, body_cache: &ReadOnlyBodyCache<'_, '_>) { + pub fn analyze(&mut self, body_cache: ReadOnlyBodyCache<'_, '_>) { self.clear(); let mut finder = DefUseFinder { @@ -55,7 +55,7 @@ impl DefUseAnalysis { fn mutate_defs_and_uses( &self, local: Local, - body_cache: &mut BodyCache<&mut Body<'tcx>>, + body_cache: &mut BodyCache<'tcx>, new_local: Local, tcx: TyCtxt<'tcx>, ) { @@ -73,7 +73,7 @@ impl DefUseAnalysis { // FIXME(pcwalton): this should update the def-use chains. pub fn replace_all_defs_and_uses_with(&self, local: Local, - body_cache: &mut BodyCache<&mut Body<'tcx>>, + body_cache: &mut BodyCache<'tcx>, new_local: Local, tcx: TyCtxt<'tcx>) { self.mutate_defs_and_uses(local, body_cache, new_local, tcx) diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index 87e6291a4548..37611561d58e 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -57,7 +57,7 @@ pub struct LivenessResult { /// Computes which local variables are live within the given function /// `mir`, including drops. pub fn liveness_of_locals( - body_cache: &ReadOnlyBodyCache<'_, '_>, + body_cache: ReadOnlyBodyCache<'_, '_>, ) -> LivenessResult { let num_live_vars = body_cache.local_decls.len(); @@ -84,7 +84,7 @@ pub fn liveness_of_locals( // order when cycles are present, but the overhead of computing the reverse CFG may outweigh // any benefits. Benchmark this and find out. let mut dirty_queue: WorkQueue = WorkQueue::with_none(body_cache.basic_blocks().len()); - for (bb, _) in traversal::postorder(body_cache) { + for (bb, _) in traversal::postorder(body_cache.body()) { dirty_queue.insert(bb); } diff --git a/src/librustc_mir/util/patch.rs b/src/librustc_mir/util/patch.rs index 01be0f598ed2..6e110b1177f1 100644 --- a/src/librustc_mir/util/patch.rs +++ b/src/librustc_mir/util/patch.rs @@ -127,7 +127,7 @@ impl<'tcx> MirPatch<'tcx> { self.make_nop.push(loc); } - pub fn apply(self, body_cache: &mut BodyCache<&'_ mut Body<'tcx>>) { + pub fn apply(self, body_cache: &mut BodyCache<'tcx>) { debug!("MirPatch: make nops at: {:?}", self.make_nop); for loc in self.make_nop { body_cache.make_statement_nop(loc);