diff --git a/src/librustc_mir/dataflow/at_location.rs b/src/librustc_mir/dataflow/at_location.rs index 7735528d8f8e..f0014602e2d6 100644 --- a/src/librustc_mir/dataflow/at_location.rs +++ b/src/librustc_mir/dataflow/at_location.rs @@ -8,6 +8,7 @@ use crate::dataflow::{BitDenotation, DataflowResults, GenKillSet}; use crate::dataflow::move_paths::{HasMoveData, MovePathIndex}; use std::iter; +use std::borrow::Borrow; /// A trait for "cartesian products" of multiple FlowAtLocation. /// @@ -60,18 +61,20 @@ pub trait FlowsAtLocation { /// (e.g., via `reconstruct_statement_effect` and /// `reconstruct_terminator_effect`; don't forget to call /// `apply_local_effect`). -pub struct FlowAtLocation<'tcx, BD> +pub struct FlowAtLocation<'tcx, BD, DR = DataflowResults<'tcx, BD>> where BD: BitDenotation<'tcx>, + DR: Borrow>, { - base_results: DataflowResults<'tcx, BD>, + base_results: DR, curr_state: BitSet, stmt_trans: GenKillSet, } -impl<'tcx, BD> FlowAtLocation<'tcx, BD> +impl<'tcx, BD, DR> FlowAtLocation<'tcx, BD, DR> where BD: BitDenotation<'tcx>, + DR: Borrow>, { /// Iterate over each bit set in the current state. pub fn each_state_bit(&self, f: F) @@ -91,8 +94,8 @@ where self.stmt_trans.gen_set.iter().for_each(f) } - pub fn new(results: DataflowResults<'tcx, BD>) -> Self { - let bits_per_block = results.sets().bits_per_block(); + pub fn new(results: DR) -> Self { + let bits_per_block = results.borrow().sets().bits_per_block(); let curr_state = BitSet::new_empty(bits_per_block); let stmt_trans = GenKillSet::from_elem(HybridBitSet::new_empty(bits_per_block)); FlowAtLocation { @@ -104,7 +107,7 @@ where /// Access the underlying operator. pub fn operator(&self) -> &BD { - self.base_results.operator() + self.base_results.borrow().operator() } pub fn contains(&self, x: BD::Idx) -> bool { @@ -134,27 +137,31 @@ where } } -impl<'tcx, BD> FlowsAtLocation for FlowAtLocation<'tcx, BD> - where BD: BitDenotation<'tcx> +impl<'tcx, BD, DR> FlowsAtLocation for FlowAtLocation<'tcx, BD, DR> +where + BD: BitDenotation<'tcx>, + DR: Borrow>, { fn reset_to_entry_of(&mut self, bb: BasicBlock) { - self.curr_state.overwrite(self.base_results.sets().entry_set_for(bb.index())); + self.curr_state.overwrite(self.base_results.borrow().sets().entry_set_for(bb.index())); } fn reset_to_exit_of(&mut self, bb: BasicBlock) { self.reset_to_entry_of(bb); - let trans = self.base_results.sets().trans_for(bb.index()); + let trans = self.base_results.borrow().sets().trans_for(bb.index()); trans.apply(&mut self.curr_state) } fn reconstruct_statement_effect(&mut self, loc: Location) { self.stmt_trans.clear(); self.base_results + .borrow() .operator() .before_statement_effect(&mut self.stmt_trans, loc); self.stmt_trans.apply(&mut self.curr_state); self.base_results + .borrow() .operator() .statement_effect(&mut self.stmt_trans, loc); } @@ -162,11 +169,13 @@ impl<'tcx, BD> FlowsAtLocation for FlowAtLocation<'tcx, BD> fn reconstruct_terminator_effect(&mut self, loc: Location) { self.stmt_trans.clear(); self.base_results + .borrow() .operator() .before_terminator_effect(&mut self.stmt_trans, loc); self.stmt_trans.apply(&mut self.curr_state); self.base_results + .borrow() .operator() .terminator_effect(&mut self.stmt_trans, loc); } @@ -177,9 +186,10 @@ impl<'tcx, BD> FlowsAtLocation for FlowAtLocation<'tcx, BD> } -impl<'tcx, T> FlowAtLocation<'tcx, T> +impl<'tcx, T, DR> FlowAtLocation<'tcx, T, DR> where T: HasMoveData<'tcx> + BitDenotation<'tcx, Idx = MovePathIndex>, + DR: Borrow>, { pub fn has_any_child_of(&self, mpi: T::Idx) -> Option { // We process `mpi` before the loop below, for two reasons: diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index ba8c47c665e0..3d0d565c53be 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -66,7 +66,7 @@ use std::mem; use crate::transform::{MirPass, MirSource}; use crate::transform::simplify; use crate::transform::no_landing_pads::no_landing_pads; -use crate::dataflow::{DataflowResults, DataflowResultsConsumer, FlowAtLocation}; +use crate::dataflow::{DataflowResults, DataflowResultsConsumer, FlowAtLocation, FlowAtLocationOwned}; use crate::dataflow::{do_dataflow, DebugFormatted, state_for_location}; use crate::dataflow::{MaybeStorageLive, HaveBeenBorrowedLocals}; use crate::util::dump_mir; @@ -627,7 +627,7 @@ struct StorageConflictVisitor<'body, 'tcx, 's> { impl<'body, 'tcx, 's> DataflowResultsConsumer<'body, 'tcx> for StorageConflictVisitor<'body, 'tcx, 's> { - type FlowState = FlowAtLocation<'tcx, MaybeStorageLive<'body, 'tcx>>; + type FlowState = FlowAtLocationOwned<'tcx, MaybeStorageLive<'body, 'tcx>>; fn body(&self) -> &'body Body<'tcx> { self.body @@ -657,7 +657,7 @@ impl<'body, 'tcx, 's> DataflowResultsConsumer<'body, 'tcx> impl<'body, 'tcx, 's> StorageConflictVisitor<'body, 'tcx, 's> { fn apply_state(&mut self, - flow_state: &FlowAtLocation<'tcx, MaybeStorageLive<'body, 'tcx>>, + flow_state: &FlowAtLocationOwned<'tcx, MaybeStorageLive<'body, 'tcx>>, loc: Location) { // Ignore unreachable blocks. match self.body.basic_blocks()[loc.block].terminator().kind {