From 7b628e18a323505c175415013bcd854f38d0216e Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 17 Dec 2018 17:26:24 +0100 Subject: [PATCH] Add required lifetime parameter to BitDenotation. This avoids all sorts of confusing issues with using both `dest_place` and `self` in the `propagate_call_return` function in the `BitDenotation` implementation for `Borrows`. --- src/librustc_mir/borrow_check/flows.rs | 12 ++-- src/librustc_mir/borrow_check/nll/mod.rs | 2 +- .../nll/type_check/liveness/mod.rs | 2 +- .../nll/type_check/liveness/trace.rs | 4 +- .../borrow_check/nll/type_check/mod.rs | 2 +- src/librustc_mir/dataflow/at_location.rs | 20 +++--- src/librustc_mir/dataflow/graphviz.rs | 16 ++--- .../dataflow/impls/borrowed_locals.rs | 14 ++-- src/librustc_mir/dataflow/impls/borrows.rs | 45 +++++------- src/librustc_mir/dataflow/impls/mod.rs | 56 ++++++++------- .../dataflow/impls/storage_liveness.rs | 14 ++-- src/librustc_mir/dataflow/mod.rs | 71 ++++++++++--------- src/librustc_mir/transform/elaborate_drops.rs | 4 +- src/librustc_mir/transform/rustc_peek.rs | 8 +-- 14 files changed, 138 insertions(+), 132 deletions(-) diff --git a/src/librustc_mir/borrow_check/flows.rs b/src/librustc_mir/borrow_check/flows.rs index 16bb1ef78dc6..8a58cb056807 100644 --- a/src/librustc_mir/borrow_check/flows.rs +++ b/src/librustc_mir/borrow_check/flows.rs @@ -33,9 +33,9 @@ use std::rc::Rc; // (forced to be `pub` due to its use as an associated type below.) crate struct Flows<'b, 'gcx: 'tcx, 'tcx: 'b> { - borrows: FlowAtLocation>, - pub uninits: FlowAtLocation>, - pub ever_inits: FlowAtLocation>, + borrows: FlowAtLocation<'tcx, Borrows<'b, 'gcx, 'tcx>>, + pub uninits: FlowAtLocation<'tcx, MaybeUninitializedPlaces<'b, 'gcx, 'tcx>>, + pub ever_inits: FlowAtLocation<'tcx, EverInitializedPlaces<'b, 'gcx, 'tcx>>, /// Polonius Output pub polonius_output: Option>>, @@ -43,9 +43,9 @@ crate struct Flows<'b, 'gcx: 'tcx, 'tcx: 'b> { impl<'b, 'gcx, 'tcx> Flows<'b, 'gcx, 'tcx> { crate fn new( - borrows: FlowAtLocation>, - uninits: FlowAtLocation>, - ever_inits: FlowAtLocation>, + borrows: FlowAtLocation<'tcx, Borrows<'b, 'gcx, 'tcx>>, + uninits: FlowAtLocation<'tcx, MaybeUninitializedPlaces<'b, 'gcx, 'tcx>>, + ever_inits: FlowAtLocation<'tcx, EverInitializedPlaces<'b, 'gcx, 'tcx>>, polonius_output: Option>>, ) -> Self { Flows { diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index 0c4140caee86..31866034cc3e 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -85,7 +85,7 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>( mir: &Mir<'tcx>, location_table: &LocationTable, param_env: ty::ParamEnv<'gcx>, - flow_inits: &mut FlowAtLocation>, + flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'cx, 'gcx, 'tcx>>, move_data: &MoveData<'tcx>, borrow_set: &BorrowSet<'tcx>, errors_buffer: &mut Vec, 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 9ccdc84db156..7b216d8e587c 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 @@ -39,7 +39,7 @@ pub(super) fn generate<'gcx, 'tcx>( typeck: &mut TypeChecker<'_, 'gcx, 'tcx>, mir: &Mir<'tcx>, elements: &Rc, - flow_inits: &mut FlowAtLocation>, + flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'gcx, 'tcx>>, move_data: &MoveData<'tcx>, location_table: &LocationTable, ) { 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 bc4e0ca23513..1fbde2ae59de 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 @@ -46,7 +46,7 @@ pub(super) fn trace( typeck: &mut TypeChecker<'_, 'gcx, 'tcx>, mir: &Mir<'tcx>, elements: &Rc, - flow_inits: &mut FlowAtLocation>, + flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'gcx, 'tcx>>, move_data: &MoveData<'tcx>, liveness_map: &NllLivenessMap, location_table: &LocationTable, @@ -99,7 +99,7 @@ where /// Results of dataflow tracking which variables (and paths) have been /// initialized. - flow_inits: &'me mut FlowAtLocation>, + flow_inits: &'me mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'flow, 'gcx, 'tcx>>, /// Index indicating where each variable is assigned, used, or /// dropped. 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 5f64dfd931c8..8ff7d625f2e1 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -122,7 +122,7 @@ pub(crate) fn type_check<'gcx, 'tcx>( location_table: &LocationTable, borrow_set: &BorrowSet<'tcx>, all_facts: &mut Option, - flow_inits: &mut FlowAtLocation>, + flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'gcx, 'tcx>>, move_data: &MoveData<'tcx>, elements: &Rc, ) -> MirTypeckResults<'tcx> { diff --git a/src/librustc_mir/dataflow/at_location.rs b/src/librustc_mir/dataflow/at_location.rs index d815bfedc371..c3c28c0ec3da 100644 --- a/src/librustc_mir/dataflow/at_location.rs +++ b/src/librustc_mir/dataflow/at_location.rs @@ -70,19 +70,19 @@ pub trait FlowsAtLocation { /// (e.g. via `reconstruct_statement_effect` and /// `reconstruct_terminator_effect`; don't forget to call /// `apply_local_effect`). -pub struct FlowAtLocation +pub struct FlowAtLocation<'tcx, BD> where - BD: BitDenotation, + BD: BitDenotation<'tcx>, { - base_results: DataflowResults, + base_results: DataflowResults<'tcx, BD>, curr_state: BitSet, stmt_gen: HybridBitSet, stmt_kill: HybridBitSet, } -impl FlowAtLocation +impl<'tcx, BD> FlowAtLocation<'tcx, BD> where - BD: BitDenotation, + BD: BitDenotation<'tcx>, { /// Iterate over each bit set in the current state. pub fn each_state_bit(&self, f: F) @@ -102,7 +102,7 @@ where self.stmt_gen.iter().for_each(f) } - pub fn new(results: DataflowResults) -> Self { + pub fn new(results: DataflowResults<'tcx, BD>) -> Self { let bits_per_block = results.sets().bits_per_block(); let curr_state = BitSet::new_empty(bits_per_block); let stmt_gen = HybridBitSet::new_empty(bits_per_block); @@ -143,8 +143,8 @@ where } } -impl FlowsAtLocation for FlowAtLocation - where BD: BitDenotation +impl<'tcx, BD> FlowsAtLocation for FlowAtLocation<'tcx, BD> + where BD: BitDenotation<'tcx> { fn reset_to_entry_of(&mut self, bb: BasicBlock) { self.curr_state.overwrite(self.base_results.sets().on_entry_set_for(bb.index())); @@ -213,9 +213,9 @@ impl FlowsAtLocation for FlowAtLocation } -impl<'tcx, T> FlowAtLocation +impl<'tcx, T> FlowAtLocation<'tcx, T> where - T: HasMoveData<'tcx> + BitDenotation, + T: HasMoveData<'tcx> + BitDenotation<'tcx, Idx = MovePathIndex>, { 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/dataflow/graphviz.rs b/src/librustc_mir/dataflow/graphviz.rs index 6896c91352fd..0ab34c47f12a 100644 --- a/src/librustc_mir/dataflow/graphviz.rs +++ b/src/librustc_mir/dataflow/graphviz.rs @@ -25,19 +25,19 @@ use super::DataflowBuilder; use super::DebugFormatted; pub trait MirWithFlowState<'tcx> { - type BD: BitDenotation; + type BD: BitDenotation<'tcx>; fn node_id(&self) -> NodeId; fn mir(&self) -> &Mir<'tcx>; - fn flow_state(&self) -> &DataflowState; + fn flow_state(&self) -> &DataflowState<'tcx, Self::BD>; } impl<'a, 'tcx, BD> MirWithFlowState<'tcx> for DataflowBuilder<'a, 'tcx, BD> - where BD: BitDenotation + where BD: BitDenotation<'tcx> { type BD = BD; fn node_id(&self) -> NodeId { self.node_id } fn mir(&self) -> &Mir<'tcx> { self.flow_state.mir() } - fn flow_state(&self) -> &DataflowState { &self.flow_state.flow_state } + fn flow_state(&self) -> &DataflowState<'tcx, Self::BD> { &self.flow_state.flow_state } } struct Graph<'a, 'tcx, MWF:'a, P> where @@ -53,8 +53,8 @@ pub(crate) fn print_borrowck_graph_to<'a, 'tcx, BD, P>( path: &Path, render_idx: P) -> io::Result<()> - where BD: BitDenotation, - P: Fn(&BD, BD::Idx) -> DebugFormatted + where BD: BitDenotation<'tcx>, + P: Fn(&BD, BD::Idx) -> DebugFormatted, { let g = Graph { mbcx, phantom: PhantomData, render_idx }; let mut v = Vec::new(); @@ -76,7 +76,7 @@ fn outgoing(mir: &Mir, bb: BasicBlock) -> Vec { impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P> where MWF: MirWithFlowState<'tcx>, - P: Fn(&MWF::BD, ::Idx) -> DebugFormatted, + P: Fn(&MWF::BD, >::Idx) -> DebugFormatted, { type Node = Node; type Edge = Edge; @@ -128,7 +128,7 @@ impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P> impl<'a, 'tcx, MWF, P> Graph<'a, 'tcx, MWF, P> where MWF: MirWithFlowState<'tcx>, - P: Fn(&MWF::BD, ::Idx) -> DebugFormatted, + P: Fn(&MWF::BD, >::Idx) -> DebugFormatted, { /// Generate the node label fn node_label_internal(&self, diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs index 1e279d8dd970..374f7071ffac 100644 --- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs +++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs @@ -36,7 +36,7 @@ impl<'a, 'tcx: 'a> HaveBeenBorrowedLocals<'a, 'tcx> { } } -impl<'a, 'tcx> BitDenotation for HaveBeenBorrowedLocals<'a, 'tcx> { +impl<'a, 'tcx> BitDenotation<'tcx> for HaveBeenBorrowedLocals<'a, 'tcx> { type Idx = Local; fn name() -> &'static str { "has_been_borrowed_locals" } fn bits_per_block(&self) -> usize { @@ -71,11 +71,13 @@ impl<'a, 'tcx> BitDenotation for HaveBeenBorrowedLocals<'a, 'tcx> { }.visit_terminator(loc.block, self.mir[loc.block].terminator(), loc); } - fn propagate_call_return(&self, - _in_out: &mut BitSet, - _call_bb: mir::BasicBlock, - _dest_bb: mir::BasicBlock, - _dest_place: &mir::Place) { + fn propagate_call_return( + &self, + _in_out: &mut BitSet, + _call_bb: mir::BasicBlock, + _dest_bb: mir::BasicBlock, + _dest_place: &mir::Place<'tcx>, + ) { // Nothing to do when a call returns successfully } } diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs index 532143af6d39..9195c167c7d2 100644 --- a/src/librustc_mir/dataflow/impls/borrows.rs +++ b/src/librustc_mir/dataflow/impls/borrows.rs @@ -195,18 +195,14 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { fn kill_borrows_on_place( &self, sets: &mut BlockSets, - location: Location, place: &Place<'tcx> ) { - debug!("kill_borrows_on_place: location={:?} place={:?}", location, place); + debug!("kill_borrows_on_place: place={:?}", place); // Handle the `Place::Local(..)` case first and exit early. if let Place::Local(local) = place { - if let Some(borrow_indexes) = self.borrow_set.local_map.get(&local) { - debug!( - "kill_borrows_on_place: local={:?} borrow_indexes={:?}", - local, borrow_indexes, - ); - sets.kill_all(borrow_indexes); + if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) { + debug!("kill_borrows_on_place: borrow_indices={:?}", borrow_indices); + sets.kill_all(borrow_indices); return; } } @@ -234,8 +230,8 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { places_conflict::PlaceConflictBias::NoOverlap, ) { debug!( - "kill_borrows_on_place: (kill) place={:?} borrow_index={:?} borrow_data={:?}", - place, borrow_index, borrow_data, + "kill_borrows_on_place: (kill) borrow_index={:?} borrow_data={:?}", + borrow_index, borrow_data, ); sets.kill(borrow_index); } @@ -243,7 +239,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> { } } -impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { +impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for Borrows<'a, 'gcx, 'tcx> { type Idx = BorrowIndex; fn name() -> &'static str { "borrows" } fn bits_per_block(&self) -> usize { @@ -278,12 +274,8 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { mir::StatementKind::Assign(ref lhs, ref rhs) => { // Make sure there are no remaining borrows for variables // that are assigned over. - self.kill_borrows_on_place(sets, location, lhs); + self.kill_borrows_on_place(sets, lhs); - // NOTE: if/when the Assign case is revised to inspect - // the assigned_place here, make sure to also - // re-consider the current implementations of the - // propagate_call_return method. if let mir::Rvalue::Ref(_, _, ref place) = **rhs { if place.ignore_borrow( self.tcx, @@ -317,13 +309,13 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { mir::StatementKind::StorageDead(local) => { // Make sure there are no remaining borrows for locals that // are gone out of scope. - self.kill_borrows_on_place(sets, location, &Place::Local(local)); + self.kill_borrows_on_place(sets, &Place::Local(local)); } mir::StatementKind::InlineAsm { ref outputs, ref asm, .. } => { for (output, kind) in outputs.iter().zip(&asm.outputs) { if !kind.is_indirect && !kind.is_rw { - self.kill_borrows_on_place(sets, location, output); + self.kill_borrows_on_place(sets, output); } } } @@ -348,16 +340,13 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> { fn terminator_effect(&self, _: &mut BlockSets, _: Location) {} - fn propagate_call_return(&self, - _in_out: &mut BitSet, - _call_bb: mir::BasicBlock, - _dest_bb: mir::BasicBlock, - _dest_place: &mir::Place) { - // there are no effects on borrows from method call return... - // - // ... but if overwriting a place can affect flow state, then - // latter is not true; see NOTE on Assign case in - // statement_effect_on_borrows. + fn propagate_call_return( + &self, + _in_out: &mut BitSet, + _call_bb: mir::BasicBlock, + _dest_bb: mir::BasicBlock, + _dest_place: &mir::Place<'tcx>, + ) { } } diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs index efdf9c330237..4901061732f1 100644 --- a/src/librustc_mir/dataflow/impls/mod.rs +++ b/src/librustc_mir/dataflow/impls/mod.rs @@ -293,7 +293,7 @@ impl<'a, 'gcx, 'tcx> DefinitelyInitializedPlaces<'a, 'gcx, 'tcx> { } } -impl<'a, 'gcx, 'tcx> BitDenotation for MaybeInitializedPlaces<'a, 'gcx, 'tcx> { +impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for MaybeInitializedPlaces<'a, 'gcx, 'tcx> { type Idx = MovePathIndex; fn name() -> &'static str { "maybe_init" } fn bits_per_block(&self) -> usize { @@ -331,11 +331,13 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MaybeInitializedPlaces<'a, 'gcx, 'tcx> { ) } - fn propagate_call_return(&self, - in_out: &mut BitSet, - _call_bb: mir::BasicBlock, - _dest_bb: mir::BasicBlock, - dest_place: &mir::Place) { + fn propagate_call_return( + &self, + in_out: &mut BitSet, + _call_bb: mir::BasicBlock, + _dest_bb: mir::BasicBlock, + dest_place: &mir::Place<'tcx>, + ) { // when a call returns successfully, that means we need to set // the bits for that dest_place to 1 (initialized). on_lookup_result_bits(self.tcx, self.mir, self.move_data(), @@ -344,7 +346,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MaybeInitializedPlaces<'a, 'gcx, 'tcx> { } } -impl<'a, 'gcx, 'tcx> BitDenotation for MaybeUninitializedPlaces<'a, 'gcx, 'tcx> { +impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for MaybeUninitializedPlaces<'a, 'gcx, 'tcx> { type Idx = MovePathIndex; fn name() -> &'static str { "maybe_uninit" } fn bits_per_block(&self) -> usize { @@ -387,11 +389,13 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MaybeUninitializedPlaces<'a, 'gcx, 'tcx> ) } - fn propagate_call_return(&self, - in_out: &mut BitSet, - _call_bb: mir::BasicBlock, - _dest_bb: mir::BasicBlock, - dest_place: &mir::Place) { + fn propagate_call_return( + &self, + in_out: &mut BitSet, + _call_bb: mir::BasicBlock, + _dest_bb: mir::BasicBlock, + dest_place: &mir::Place<'tcx>, + ) { // when a call returns successfully, that means we need to set // the bits for that dest_place to 0 (initialized). on_lookup_result_bits(self.tcx, self.mir, self.move_data(), @@ -400,7 +404,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MaybeUninitializedPlaces<'a, 'gcx, 'tcx> } } -impl<'a, 'gcx, 'tcx> BitDenotation for DefinitelyInitializedPlaces<'a, 'gcx, 'tcx> { +impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for DefinitelyInitializedPlaces<'a, 'gcx, 'tcx> { type Idx = MovePathIndex; fn name() -> &'static str { "definite_init" } fn bits_per_block(&self) -> usize { @@ -441,11 +445,13 @@ impl<'a, 'gcx, 'tcx> BitDenotation for DefinitelyInitializedPlaces<'a, 'gcx, 'tc ) } - fn propagate_call_return(&self, - in_out: &mut BitSet, - _call_bb: mir::BasicBlock, - _dest_bb: mir::BasicBlock, - dest_place: &mir::Place) { + fn propagate_call_return( + &self, + in_out: &mut BitSet, + _call_bb: mir::BasicBlock, + _dest_bb: mir::BasicBlock, + dest_place: &mir::Place<'tcx>, + ) { // when a call returns successfully, that means we need to set // the bits for that dest_place to 1 (initialized). on_lookup_result_bits(self.tcx, self.mir, self.move_data(), @@ -454,7 +460,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for DefinitelyInitializedPlaces<'a, 'gcx, 'tc } } -impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedPlaces<'a, 'gcx, 'tcx> { +impl<'a, 'gcx, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'gcx, 'tcx> { type Idx = InitIndex; fn name() -> &'static str { "ever_init" } fn bits_per_block(&self) -> usize { @@ -530,11 +536,13 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedPlaces<'a, 'gcx, 'tcx> { ); } - fn propagate_call_return(&self, - in_out: &mut BitSet, - call_bb: mir::BasicBlock, - _dest_bb: mir::BasicBlock, - _dest_place: &mir::Place) { + fn propagate_call_return( + &self, + in_out: &mut BitSet, + call_bb: mir::BasicBlock, + _dest_bb: mir::BasicBlock, + _dest_place: &mir::Place<'tcx>, + ) { let move_data = self.move_data(); let bits_per_block = self.bits_per_block(); let init_loc_map = &move_data.init_loc_map; diff --git a/src/librustc_mir/dataflow/impls/storage_liveness.rs b/src/librustc_mir/dataflow/impls/storage_liveness.rs index c8faa34df8a2..caf3d3f7ab6c 100644 --- a/src/librustc_mir/dataflow/impls/storage_liveness.rs +++ b/src/librustc_mir/dataflow/impls/storage_liveness.rs @@ -29,7 +29,7 @@ impl<'a, 'tcx: 'a> MaybeStorageLive<'a, 'tcx> { } } -impl<'a, 'tcx> BitDenotation for MaybeStorageLive<'a, 'tcx> { +impl<'a, 'tcx> BitDenotation<'tcx> for MaybeStorageLive<'a, 'tcx> { type Idx = Local; fn name() -> &'static str { "maybe_storage_live" } fn bits_per_block(&self) -> usize { @@ -58,11 +58,13 @@ impl<'a, 'tcx> BitDenotation for MaybeStorageLive<'a, 'tcx> { // Terminators have no effect } - fn propagate_call_return(&self, - _in_out: &mut BitSet, - _call_bb: mir::BasicBlock, - _dest_bb: mir::BasicBlock, - _dest_place: &mir::Place) { + fn propagate_call_return( + &self, + _in_out: &mut BitSet, + _call_bb: mir::BasicBlock, + _dest_bb: mir::BasicBlock, + _dest_place: &mir::Place<'tcx>, + ) { // Nothing to do when a call returns successfully } } diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs index c19145636e6d..4e8716f3d856 100644 --- a/src/librustc_mir/dataflow/mod.rs +++ b/src/librustc_mir/dataflow/mod.rs @@ -44,7 +44,9 @@ pub mod move_paths; pub(crate) use self::move_paths::indexes; -pub(crate) struct DataflowBuilder<'a, 'tcx: 'a, BD> where BD: BitDenotation +pub(crate) struct DataflowBuilder<'a, 'tcx: 'a, BD> +where + BD: BitDenotation<'tcx> { node_id: ast::NodeId, flow_state: DataflowAnalysis<'a, 'tcx, BD>, @@ -71,7 +73,7 @@ impl fmt::Debug for DebugFormatted { } } -pub(crate) trait Dataflow { +pub(crate) trait Dataflow<'tcx, BD: BitDenotation<'tcx>> { /// Sets up and runs the dataflow problem, using `p` to render results if /// implementation so chooses. fn dataflow

(&mut self, p: P) where P: Fn(&BD, BD::Idx) -> DebugFormatted { @@ -87,7 +89,9 @@ pub(crate) trait Dataflow { fn propagate(&mut self); } -impl<'a, 'tcx: 'a, BD> Dataflow for DataflowBuilder<'a, 'tcx, BD> where BD: BitDenotation +impl<'a, 'tcx: 'a, BD> Dataflow<'tcx, BD> for DataflowBuilder<'a, 'tcx, BD> +where + BD: BitDenotation<'tcx> { fn dataflow

(&mut self, p: P) where P: Fn(&BD, BD::Idx) -> DebugFormatted { self.flow_state.build_sets(); @@ -127,21 +131,21 @@ pub(crate) fn do_dataflow<'a, 'gcx, 'tcx, BD, P>(tcx: TyCtxt<'a, 'gcx, 'tcx>, dead_unwinds: &BitSet, bd: BD, p: P) - -> DataflowResults - where BD: BitDenotation + InitialFlow, + -> DataflowResults<'tcx, BD> + where BD: BitDenotation<'tcx> + InitialFlow, P: Fn(&BD, BD::Idx) -> DebugFormatted { let flow_state = DataflowAnalysis::new(mir, dead_unwinds, bd); flow_state.run(tcx, node_id, attributes, p) } -impl<'a, 'gcx: 'tcx, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation +impl<'a, 'gcx: 'tcx, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation<'tcx> { pub(crate) fn run

(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, node_id: ast::NodeId, attributes: &[ast::Attribute], - p: P) -> DataflowResults + p: P) -> DataflowResults<'tcx, BD> where P: Fn(&BD, BD::Idx) -> DebugFormatted { let name_found = |sess: &Session, attrs: &[ast::Attribute], name| -> Option { @@ -173,12 +177,12 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitD } } -struct PropagationContext<'b, 'a: 'b, 'tcx: 'a, O> where O: 'b + BitDenotation +struct PropagationContext<'b, 'a: 'b, 'tcx: 'a, O> where O: 'b + BitDenotation<'tcx> { builder: &'b mut DataflowAnalysis<'a, 'tcx, O>, } -impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation +impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation<'tcx> { fn propagate(&mut self) { let mut temp = BitSet::new_empty(self.flow_state.sets.bits_per_block); @@ -228,7 +232,7 @@ impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation } } -impl<'b, 'a: 'b, 'tcx: 'a, BD> PropagationContext<'b, 'a, 'tcx, BD> where BD: BitDenotation +impl<'b, 'a: 'b, 'tcx: 'a, BD> PropagationContext<'b, 'a, 'tcx, BD> where BD: BitDenotation<'tcx> { fn walk_cfg(&mut self, in_out: &mut BitSet) { let mut dirty_queue: WorkQueue = @@ -259,7 +263,7 @@ fn dataflow_path(context: &str, path: &str) -> PathBuf { path } -impl<'a, 'tcx: 'a, BD> DataflowBuilder<'a, 'tcx, BD> where BD: BitDenotation +impl<'a, 'tcx: 'a, BD> DataflowBuilder<'a, 'tcx, BD> where BD: BitDenotation<'tcx> { fn pre_dataflow_instrumentation

(&self, p: P) -> io::Result<()> where P: Fn(&BD, BD::Idx) -> DebugFormatted @@ -347,10 +351,10 @@ pub(crate) trait DataflowResultsConsumer<'a, 'tcx: 'a> { fn mir(&self) -> &'a Mir<'tcx>; } -pub fn state_for_location<'tcx, T: BitDenotation>(loc: Location, - analysis: &T, - result: &DataflowResults, - mir: &Mir<'tcx>) +pub fn state_for_location<'tcx, T: BitDenotation<'tcx>>(loc: Location, + analysis: &T, + result: &DataflowResults<'tcx, T>, + mir: &Mir<'tcx>) -> BitSet { let mut on_entry = result.sets().on_entry_set_for(loc.block.index()).to_owned(); let mut kill_set = on_entry.to_hybrid(); @@ -381,25 +385,25 @@ pub fn state_for_location<'tcx, T: BitDenotation>(loc: Location, gen_set.to_dense() } -pub struct DataflowAnalysis<'a, 'tcx: 'a, O> where O: BitDenotation +pub struct DataflowAnalysis<'a, 'tcx: 'a, O> where O: BitDenotation<'tcx> { - flow_state: DataflowState, + flow_state: DataflowState<'tcx, O>, dead_unwinds: &'a BitSet, mir: &'a Mir<'tcx>, } -impl<'a, 'tcx: 'a, O> DataflowAnalysis<'a, 'tcx, O> where O: BitDenotation +impl<'a, 'tcx: 'a, O> DataflowAnalysis<'a, 'tcx, O> where O: BitDenotation<'tcx> { - pub fn results(self) -> DataflowResults { + pub fn results(self) -> DataflowResults<'tcx, O> { DataflowResults(self.flow_state) } pub fn mir(&self) -> &'a Mir<'tcx> { self.mir } } -pub struct DataflowResults(pub(crate) DataflowState) where O: BitDenotation; +pub struct DataflowResults<'tcx, O>(pub(crate) DataflowState<'tcx, O>) where O: BitDenotation<'tcx>; -impl DataflowResults { +impl<'tcx, O: BitDenotation<'tcx>> DataflowResults<'tcx, O> { pub fn sets(&self) -> &AllSets { &self.0.sets } @@ -411,7 +415,7 @@ impl DataflowResults { /// State of a dataflow analysis; couples a collection of bit sets /// with operator used to initialize and merge bits during analysis. -pub struct DataflowState +pub struct DataflowState<'tcx, O: BitDenotation<'tcx>> { /// All the sets for the analysis. (Factored into its /// own structure so that we can borrow it mutably @@ -422,7 +426,7 @@ pub struct DataflowState pub(crate) operator: O, } -impl DataflowState { +impl<'tcx, O: BitDenotation<'tcx>> DataflowState<'tcx, O> { pub(crate) fn interpret_set<'c, P>(&self, o: &'c O, set: &BitSet, @@ -561,7 +565,7 @@ pub trait InitialFlow { fn bottom_value() -> bool; } -pub trait BitDenotation: BitSetOperator { +pub trait BitDenotation<'tcx>: BitSetOperator { /// Specifies what index type is used to access the bitvector. type Idx: Idx; @@ -687,14 +691,16 @@ pub trait BitDenotation: BitSetOperator { /// be better to represent this as an additional gen- and /// kill-sets associated with each edge coming out of the basic /// block. - fn propagate_call_return(&self, - in_out: &mut BitSet, - call_bb: mir::BasicBlock, - dest_bb: mir::BasicBlock, - dest_place: &mir::Place); + fn propagate_call_return( + &self, + in_out: &mut BitSet, + call_bb: mir::BasicBlock, + dest_bb: mir::BasicBlock, + dest_place: &mir::Place<'tcx>, + ); } -impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation +impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation<'tcx> { pub fn new(mir: &'a Mir<'tcx>, dead_unwinds: &'a BitSet, @@ -726,8 +732,7 @@ impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation } } -impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation -{ +impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation<'tcx> { /// Propagates the bits of `in_out` into all the successors of `bb`, /// using bitwise operator denoted by `self.operator`. /// @@ -744,7 +749,7 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation fn propagate_bits_into_graph_successors_of( &mut self, in_out: &mut BitSet, - (bb, bb_data): (mir::BasicBlock, &mir::BasicBlockData), + (bb, bb_data): (mir::BasicBlock, &mir::BasicBlockData<'tcx>), dirty_list: &mut WorkQueue) { match bb_data.terminator().kind { diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index 2b3fd552e0fa..6068af8a46d7 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -303,8 +303,8 @@ struct ElaborateDropsCtxt<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &'a Mir<'tcx>, env: &'a MoveDataParamEnv<'tcx, 'tcx>, - flow_inits: DataflowResults>, - flow_uninits: DataflowResults>, + flow_inits: DataflowResults<'tcx, MaybeInitializedPlaces<'a, 'tcx, 'tcx>>, + flow_uninits: DataflowResults<'tcx, MaybeUninitializedPlaces<'a, 'tcx, 'tcx>>, drop_flags: FxHashMap, patch: MirPatch<'tcx>, } diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs index f852195b8351..a2123449f8ba 100644 --- a/src/librustc_mir/transform/rustc_peek.rs +++ b/src/librustc_mir/transform/rustc_peek.rs @@ -95,8 +95,8 @@ pub fn sanity_check_via_rustc_peek<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &Mir<'tcx>, id: ast::NodeId, _attributes: &[ast::Attribute], - results: &DataflowResults) - where O: BitDenotation + HasMoveData<'tcx> + results: &DataflowResults<'tcx, O>) + where O: BitDenotation<'tcx, Idx=MovePathIndex> + HasMoveData<'tcx> { debug!("sanity_check_via_rustc_peek id: {:?}", id); // FIXME: this is not DRY. Figure out way to abstract this and @@ -110,9 +110,9 @@ pub fn sanity_check_via_rustc_peek<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &Mir<'tcx>, - results: &DataflowResults, + results: &DataflowResults<'tcx, O>, bb: mir::BasicBlock) where - O: BitDenotation + HasMoveData<'tcx> + O: BitDenotation<'tcx, Idx=MovePathIndex> + HasMoveData<'tcx> { let move_data = results.0.operator.move_data(); let mir::BasicBlockData { ref statements, ref terminator, is_cleanup: _ } = mir[bb];