// (forced to be `pub` due to its use as an associated type below.)
crate struct Flows<'b, 'gcx: 'tcx, 'tcx: 'b> {
- borrows: FlowAtLocation<Borrows<'b, 'gcx, 'tcx>>,
- pub uninits: FlowAtLocation<MaybeUninitializedPlaces<'b, 'gcx, 'tcx>>,
- pub ever_inits: FlowAtLocation<EverInitializedPlaces<'b, 'gcx, 'tcx>>,
+ 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<Rc<Output<RegionVid, BorrowIndex, LocationIndex>>>,
impl<'b, 'gcx, 'tcx> Flows<'b, 'gcx, 'tcx> {
crate fn new(
- borrows: FlowAtLocation<Borrows<'b, 'gcx, 'tcx>>,
- uninits: FlowAtLocation<MaybeUninitializedPlaces<'b, 'gcx, 'tcx>>,
- ever_inits: FlowAtLocation<EverInitializedPlaces<'b, 'gcx, 'tcx>>,
+ 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<Rc<Output<RegionVid, BorrowIndex, LocationIndex>>>,
) -> Self {
Flows {
mir: &Mir<'tcx>,
location_table: &LocationTable,
param_env: ty::ParamEnv<'gcx>,
- flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'cx, 'gcx, 'tcx>>,
+ flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'cx, 'gcx, 'tcx>>,
move_data: &MoveData<'tcx>,
borrow_set: &BorrowSet<'tcx>,
errors_buffer: &mut Vec<Diagnostic>,
typeck: &mut TypeChecker<'_, 'gcx, 'tcx>,
mir: &Mir<'tcx>,
elements: &Rc<RegionValueElements>,
- flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
+ flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
move_data: &MoveData<'tcx>,
location_table: &LocationTable,
) {
typeck: &mut TypeChecker<'_, 'gcx, 'tcx>,
mir: &Mir<'tcx>,
elements: &Rc<RegionValueElements>,
- flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
+ flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
move_data: &MoveData<'tcx>,
liveness_map: &NllLivenessMap,
location_table: &LocationTable,
/// Results of dataflow tracking which variables (and paths) have been
/// initialized.
- flow_inits: &'me mut FlowAtLocation<MaybeInitializedPlaces<'flow, 'gcx, 'tcx>>,
+ flow_inits: &'me mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'flow, 'gcx, 'tcx>>,
/// Index indicating where each variable is assigned, used, or
/// dropped.
location_table: &LocationTable,
borrow_set: &BorrowSet<'tcx>,
all_facts: &mut Option<AllFacts>,
- flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
+ flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
move_data: &MoveData<'tcx>,
elements: &Rc<RegionValueElements>,
) -> MirTypeckResults<'tcx> {
/// (e.g. via `reconstruct_statement_effect` and
/// `reconstruct_terminator_effect`; don't forget to call
/// `apply_local_effect`).
-pub struct FlowAtLocation<BD>
+pub struct FlowAtLocation<'tcx, BD>
where
- BD: BitDenotation,
+ BD: BitDenotation<'tcx>,
{
- base_results: DataflowResults<BD>,
+ base_results: DataflowResults<'tcx, BD>,
curr_state: BitSet<BD::Idx>,
stmt_gen: HybridBitSet<BD::Idx>,
stmt_kill: HybridBitSet<BD::Idx>,
}
-impl<BD> FlowAtLocation<BD>
+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<F>(&self, f: F)
self.stmt_gen.iter().for_each(f)
}
- pub fn new(results: DataflowResults<BD>) -> 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);
}
}
-impl<BD> FlowsAtLocation for FlowAtLocation<BD>
- 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()));
}
-impl<'tcx, T> FlowAtLocation<T>
+impl<'tcx, T> FlowAtLocation<'tcx, T>
where
- T: HasMoveData<'tcx> + BitDenotation<Idx = MovePathIndex>,
+ T: HasMoveData<'tcx> + BitDenotation<'tcx, Idx = MovePathIndex>,
{
pub fn has_any_child_of(&self, mpi: T::Idx) -> Option<T::Idx> {
// We process `mpi` before the loop below, for two reasons:
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<Self::BD>;
+ 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::BD> { &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
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();
impl<'a, 'tcx, MWF, P> dot::Labeller<'a> for Graph<'a, 'tcx, MWF, P>
where MWF: MirWithFlowState<'tcx>,
- P: Fn(&MWF::BD, <MWF::BD as BitDenotation>::Idx) -> DebugFormatted,
+ P: Fn(&MWF::BD, <MWF::BD as BitDenotation<'tcx>>::Idx) -> DebugFormatted,
{
type Node = Node;
type Edge = Edge;
impl<'a, 'tcx, MWF, P> Graph<'a, 'tcx, MWF, P>
where MWF: MirWithFlowState<'tcx>,
- P: Fn(&MWF::BD, <MWF::BD as BitDenotation>::Idx) -> DebugFormatted,
+ P: Fn(&MWF::BD, <MWF::BD as BitDenotation<'tcx>>::Idx) -> DebugFormatted,
{
/// Generate the node label
fn node_label_internal<W: io::Write>(&self,
}
}
-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 {
}.visit_terminator(loc.block, self.mir[loc.block].terminator(), loc);
}
- fn propagate_call_return(&self,
- _in_out: &mut BitSet<Local>,
- _call_bb: mir::BasicBlock,
- _dest_bb: mir::BasicBlock,
- _dest_place: &mir::Place) {
+ fn propagate_call_return(
+ &self,
+ _in_out: &mut BitSet<Local>,
+ _call_bb: mir::BasicBlock,
+ _dest_bb: mir::BasicBlock,
+ _dest_place: &mir::Place<'tcx>,
+ ) {
// Nothing to do when a call returns successfully
}
}
fn kill_borrows_on_place(
&self,
sets: &mut BlockSets<BorrowIndex>,
- 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;
}
}
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);
}
}
}
-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 {
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,
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);
}
}
}
fn terminator_effect(&self, _: &mut BlockSets<BorrowIndex>, _: Location) {}
- fn propagate_call_return(&self,
- _in_out: &mut BitSet<BorrowIndex>,
- _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<BorrowIndex>,
+ _call_bb: mir::BasicBlock,
+ _dest_bb: mir::BasicBlock,
+ _dest_place: &mir::Place<'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 {
)
}
- fn propagate_call_return(&self,
- in_out: &mut BitSet<MovePathIndex>,
- _call_bb: mir::BasicBlock,
- _dest_bb: mir::BasicBlock,
- dest_place: &mir::Place) {
+ fn propagate_call_return(
+ &self,
+ in_out: &mut BitSet<MovePathIndex>,
+ _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(),
}
}
-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 {
)
}
- fn propagate_call_return(&self,
- in_out: &mut BitSet<MovePathIndex>,
- _call_bb: mir::BasicBlock,
- _dest_bb: mir::BasicBlock,
- dest_place: &mir::Place) {
+ fn propagate_call_return(
+ &self,
+ in_out: &mut BitSet<MovePathIndex>,
+ _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(),
}
}
-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 {
)
}
- fn propagate_call_return(&self,
- in_out: &mut BitSet<MovePathIndex>,
- _call_bb: mir::BasicBlock,
- _dest_bb: mir::BasicBlock,
- dest_place: &mir::Place) {
+ fn propagate_call_return(
+ &self,
+ in_out: &mut BitSet<MovePathIndex>,
+ _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(),
}
}
-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 {
);
}
- fn propagate_call_return(&self,
- in_out: &mut BitSet<InitIndex>,
- call_bb: mir::BasicBlock,
- _dest_bb: mir::BasicBlock,
- _dest_place: &mir::Place) {
+ fn propagate_call_return(
+ &self,
+ in_out: &mut BitSet<InitIndex>,
+ 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;
}
}
-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 {
// Terminators have no effect
}
- fn propagate_call_return(&self,
- _in_out: &mut BitSet<Local>,
- _call_bb: mir::BasicBlock,
- _dest_bb: mir::BasicBlock,
- _dest_place: &mir::Place) {
+ fn propagate_call_return(
+ &self,
+ _in_out: &mut BitSet<Local>,
+ _call_bb: mir::BasicBlock,
+ _dest_bb: mir::BasicBlock,
+ _dest_place: &mir::Place<'tcx>,
+ ) {
// Nothing to do when a call returns successfully
}
}
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>,
}
}
-pub(crate) trait Dataflow<BD: BitDenotation> {
+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<P>(&mut self, p: P) where P: Fn(&BD, BD::Idx) -> DebugFormatted {
fn propagate(&mut self);
}
-impl<'a, 'tcx: 'a, BD> Dataflow<BD> 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<P>(&mut self, p: P) where P: Fn(&BD, BD::Idx) -> DebugFormatted {
self.flow_state.build_sets();
dead_unwinds: &BitSet<BasicBlock>,
bd: BD,
p: P)
- -> DataflowResults<BD>
- 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<P>(self,
tcx: TyCtxt<'a, 'gcx, 'tcx>,
node_id: ast::NodeId,
attributes: &[ast::Attribute],
- p: P) -> DataflowResults<BD>
+ p: P) -> DataflowResults<'tcx, BD>
where P: Fn(&BD, BD::Idx) -> DebugFormatted
{
let name_found = |sess: &Session, attrs: &[ast::Attribute], name| -> Option<String> {
}
}
-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);
}
}
-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<BD::Idx>) {
let mut dirty_queue: WorkQueue<mir::BasicBlock> =
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<P>(&self, p: P) -> io::Result<()>
where P: Fn(&BD, BD::Idx) -> DebugFormatted
fn mir(&self) -> &'a Mir<'tcx>;
}
-pub fn state_for_location<'tcx, T: BitDenotation>(loc: Location,
- analysis: &T,
- result: &DataflowResults<T>,
- mir: &Mir<'tcx>)
+pub fn state_for_location<'tcx, T: BitDenotation<'tcx>>(loc: Location,
+ analysis: &T,
+ result: &DataflowResults<'tcx, T>,
+ mir: &Mir<'tcx>)
-> BitSet<T::Idx> {
let mut on_entry = result.sets().on_entry_set_for(loc.block.index()).to_owned();
let mut kill_set = on_entry.to_hybrid();
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<O>,
+ flow_state: DataflowState<'tcx, O>,
dead_unwinds: &'a BitSet<mir::BasicBlock>,
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<O> {
+ pub fn results(self) -> DataflowResults<'tcx, O> {
DataflowResults(self.flow_state)
}
pub fn mir(&self) -> &'a Mir<'tcx> { self.mir }
}
-pub struct DataflowResults<O>(pub(crate) DataflowState<O>) where O: BitDenotation;
+pub struct DataflowResults<'tcx, O>(pub(crate) DataflowState<'tcx, O>) where O: BitDenotation<'tcx>;
-impl<O: BitDenotation> DataflowResults<O> {
+impl<'tcx, O: BitDenotation<'tcx>> DataflowResults<'tcx, O> {
pub fn sets(&self) -> &AllSets<O::Idx> {
&self.0.sets
}
/// State of a dataflow analysis; couples a collection of bit sets
/// with operator used to initialize and merge bits during analysis.
-pub struct DataflowState<O: BitDenotation>
+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
pub(crate) operator: O,
}
-impl<O: BitDenotation> DataflowState<O> {
+impl<'tcx, O: BitDenotation<'tcx>> DataflowState<'tcx, O> {
pub(crate) fn interpret_set<'c, P>(&self,
o: &'c O,
set: &BitSet<O::Idx>,
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;
/// 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<Self::Idx>,
- call_bb: mir::BasicBlock,
- dest_bb: mir::BasicBlock,
- dest_place: &mir::Place);
+ fn propagate_call_return(
+ &self,
+ in_out: &mut BitSet<Self::Idx>,
+ 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<mir::BasicBlock>,
}
}
-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`.
///
fn propagate_bits_into_graph_successors_of(
&mut self,
in_out: &mut BitSet<D::Idx>,
- (bb, bb_data): (mir::BasicBlock, &mir::BasicBlockData),
+ (bb, bb_data): (mir::BasicBlock, &mir::BasicBlockData<'tcx>),
dirty_list: &mut WorkQueue<mir::BasicBlock>)
{
match bb_data.terminator().kind {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &'a Mir<'tcx>,
env: &'a MoveDataParamEnv<'tcx, 'tcx>,
- flow_inits: DataflowResults<MaybeInitializedPlaces<'a, 'tcx, 'tcx>>,
- flow_uninits: DataflowResults<MaybeUninitializedPlaces<'a, 'tcx, 'tcx>>,
+ flow_inits: DataflowResults<'tcx, MaybeInitializedPlaces<'a, 'tcx, 'tcx>>,
+ flow_uninits: DataflowResults<'tcx, MaybeUninitializedPlaces<'a, 'tcx, 'tcx>>,
drop_flags: FxHashMap<MovePathIndex, Local>,
patch: MirPatch<'tcx>,
}
mir: &Mir<'tcx>,
id: ast::NodeId,
_attributes: &[ast::Attribute],
- results: &DataflowResults<O>)
- where O: BitDenotation<Idx=MovePathIndex> + 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
fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &Mir<'tcx>,
- results: &DataflowResults<O>,
+ results: &DataflowResults<'tcx, O>,
bb: mir::BasicBlock) where
- O: BitDenotation<Idx=MovePathIndex> + 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];