Skip to content

Commit

Permalink
move the tcx and mir parts of associated Ctxt onto each `BitDen…
Browse files Browse the repository at this point in the history
…otation` impl.
  • Loading branch information
pnkfelix committed May 24, 2016
1 parent ae09c5e commit 221cce9
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 79 deletions.
118 changes: 59 additions & 59 deletions src/librustc_borrowck/borrowck/mir/dataflow/impls.rs
Expand Up @@ -24,23 +24,9 @@ use bitslice::BitSlice; // adds set_bit/get_bit to &[usize] bitvector rep.
use bitslice::{BitwiseOperator};
use indexed_set::{Idx, IdxSet};

use std::marker::PhantomData;

// Dataflow analyses are built upon some interpretation of the
// bitvectors attached to each basic block, represented via a
// zero-sized structure.
//
// Note on PhantomData: Each interpretation will need to instantiate
// the `Bit` and `Ctxt` associated types, and in this case, those
// associated types need an associated lifetime `'tcx`. The
// interpretive structures are zero-sized, so they all need to carry a
// `PhantomData` representing how the structures relate to the `'tcx`
// lifetime.
//
// But, since all of the uses of `'tcx` are solely via instances of
// `Ctxt` that are passed into the `BitDenotation` methods, we can
// consistently use a `PhantomData` that is just a function over a
// `&Ctxt` (== `&MoveData<'tcx>).

/// `MaybeInitializedLvals` tracks all l-values that might be
/// initialized upon reaching a particular point in the control flow
Expand Down Expand Up @@ -77,10 +63,15 @@ use std::marker::PhantomData;
/// Similarly, at a given `drop` statement, the set-intersection
/// between this data and `MaybeUninitializedLvals` yields the set of
/// l-values that would require a dynamic drop-flag at that statement.
#[derive(Debug, Default)]
pub struct MaybeInitializedLvals<'a, 'tcx: 'a> {
// See "Note on PhantomData" above.
phantom: PhantomData<Fn(&'a MoveData<'tcx>, TyCtxt<'a, 'tcx, 'tcx>, &'a Mir<'tcx>)>
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &'a Mir<'tcx>,
}

impl<'a, 'tcx: 'a> MaybeInitializedLvals<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &'a Mir<'tcx>) -> Self {
MaybeInitializedLvals { tcx: tcx, mir: mir }
}
}

/// `MaybeUninitializedLvals` tracks all l-values that might be
Expand Down Expand Up @@ -118,10 +109,15 @@ pub struct MaybeInitializedLvals<'a, 'tcx: 'a> {
/// Similarly, at a given `drop` statement, the set-intersection
/// between this data and `MaybeInitializedLvals` yields the set of
/// l-values that would require a dynamic drop-flag at that statement.
#[derive(Debug, Default)]
pub struct MaybeUninitializedLvals<'a, 'tcx: 'a> {
// See "Note on PhantomData" above.
phantom: PhantomData<Fn(&'a MoveData<'tcx>, TyCtxt<'a, 'tcx, 'tcx>, &'a Mir<'tcx>)>
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &'a Mir<'tcx>,
}

impl<'a, 'tcx: 'a> MaybeUninitializedLvals<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &'a Mir<'tcx>) -> Self {
MaybeUninitializedLvals { tcx: tcx, mir: mir }
}
}

/// `DefinitelyInitializedLvals` tracks all l-values that are definitely
Expand Down Expand Up @@ -165,10 +161,15 @@ pub struct MaybeUninitializedLvals<'a, 'tcx: 'a> {
/// Similarly, at a given `drop` statement, the set-difference between
/// this data and `MaybeInitializedLvals` yields the set of l-values
/// that would require a dynamic drop-flag at that statement.
#[derive(Debug, Default)]
pub struct DefinitelyInitializedLvals<'a, 'tcx: 'a> {
// See "Note on PhantomData" above.
phantom: PhantomData<Fn(&'a MoveData<'tcx>, TyCtxt<'a, 'tcx, 'tcx>, &'a Mir<'tcx>)>
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &'a Mir<'tcx>,
}

impl<'a, 'tcx: 'a> DefinitelyInitializedLvals<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &'a Mir<'tcx>) -> Self {
DefinitelyInitializedLvals { tcx: tcx, mir: mir }
}
}

/// `MovingOutStatements` tracks the statements that perform moves out
Expand All @@ -184,10 +185,10 @@ pub struct DefinitelyInitializedLvals<'a, 'tcx: 'a> {
/// control flow. But `MovingOutStatements` also includes the added
/// data of *which* particular statement causing the deinitialization
/// that the borrow checker's error meessage may need to report.
#[derive(Debug, Default)]
#[allow(dead_code)]
pub struct MovingOutStatements<'a, 'tcx: 'a> {
// See "Note on PhantomData" above.
phantom: PhantomData<Fn(&'a MoveData<'tcx>, TyCtxt<'a, 'tcx, 'tcx>, &'a Mir<'tcx>)>
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &'a Mir<'tcx>,
}

impl<'a, 'tcx> MaybeInitializedLvals<'a, 'tcx> {
Expand Down Expand Up @@ -226,18 +227,18 @@ impl<'a, 'tcx> DefinitelyInitializedLvals<'a, 'tcx> {
impl<'a, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'tcx> {
type Idx = MovePathIndex;
type Bit = MovePath<'tcx>;
type Ctxt = (TyCtxt<'a, 'tcx, 'tcx>, &'a Mir<'tcx>, MoveData<'tcx>);
type Ctxt = MoveData<'tcx>;
fn name() -> &'static str { "maybe_init" }
fn bits_per_block(&self, ctxt: &Self::Ctxt) -> usize {
ctxt.2.move_paths.len()
ctxt.move_paths.len()
}
fn interpret<'c>(&self, ctxt: &'c Self::Ctxt, idx: usize) -> &'c Self::Bit {
&ctxt.2.move_paths[MovePathIndex::new(idx)]
&ctxt.move_paths[MovePathIndex::new(idx)]
}
fn start_block_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<MovePathIndex>)
{
drop_flag_effects_for_function_entry(
ctxt.0, ctxt.1, &ctxt.2,
self.tcx, self.mir, ctxt,
|path, s| {
assert!(s == DropFlagState::Present);
sets.on_entry.add(&path);
Expand All @@ -251,7 +252,7 @@ impl<'a, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'tcx> {
idx: usize)
{
drop_flag_effects_for_location(
ctxt.0, ctxt.1, &ctxt.2,
self.tcx, self.mir, ctxt,
Location { block: bb, index: idx },
|path, s| Self::update_bits(sets, path, s)
)
Expand All @@ -264,7 +265,7 @@ impl<'a, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'tcx> {
statements_len: usize)
{
drop_flag_effects_for_location(
ctxt.0, ctxt.1, &ctxt.2,
self.tcx, self.mir, ctxt,
Location { block: bb, index: statements_len },
|path, s| Self::update_bits(sets, path, s)
)
Expand All @@ -278,9 +279,8 @@ impl<'a, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'tcx> {
dest_lval: &repr::Lvalue) {
// when a call returns successfully, that means we need to set
// the bits for that dest_lval to 1 (initialized).
let move_data = &ctxt.2;
let move_path_index = move_data.rev_lookup.find(dest_lval);
on_all_children_bits(ctxt.0, ctxt.1, &ctxt.2,
let move_path_index = ctxt.rev_lookup.find(dest_lval);
on_all_children_bits(self.tcx, self.mir, ctxt,
move_path_index,
|mpi| { in_out.add(&mpi); });
}
Expand All @@ -289,13 +289,13 @@ impl<'a, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'tcx> {
impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> {
type Idx = MovePathIndex;
type Bit = MovePath<'tcx>;
type Ctxt = (TyCtxt<'a, 'tcx, 'tcx>, &'a Mir<'tcx>, MoveData<'tcx>);
type Ctxt = MoveData<'tcx>;
fn name() -> &'static str { "maybe_uninit" }
fn bits_per_block(&self, ctxt: &Self::Ctxt) -> usize {
ctxt.2.move_paths.len()
ctxt.move_paths.len()
}
fn interpret<'c>(&self, ctxt: &'c Self::Ctxt, idx: usize) -> &'c Self::Bit {
&ctxt.2.move_paths[MovePathIndex::new(idx)]
&ctxt.move_paths[MovePathIndex::new(idx)]
}

// sets on_entry bits for Arg lvalues
Expand All @@ -304,7 +304,7 @@ impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> {
for e in sets.on_entry.words_mut() { *e = !0; }

drop_flag_effects_for_function_entry(
ctxt.0, ctxt.1, &ctxt.2,
self.tcx, self.mir, ctxt,
|path, s| {
assert!(s == DropFlagState::Present);
sets.on_entry.remove(&path);
Expand All @@ -318,7 +318,7 @@ impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> {
idx: usize)
{
drop_flag_effects_for_location(
ctxt.0, ctxt.1, &ctxt.2,
self.tcx, self.mir, ctxt,
Location { block: bb, index: idx },
|path, s| Self::update_bits(sets, path, s)
)
Expand All @@ -331,7 +331,7 @@ impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> {
statements_len: usize)
{
drop_flag_effects_for_location(
ctxt.0, ctxt.1, &ctxt.2,
self.tcx, self.mir, ctxt,
Location { block: bb, index: statements_len },
|path, s| Self::update_bits(sets, path, s)
)
Expand All @@ -345,8 +345,8 @@ impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> {
dest_lval: &repr::Lvalue) {
// when a call returns successfully, that means we need to set
// the bits for that dest_lval to 1 (initialized).
let move_path_index = ctxt.2.rev_lookup.find(dest_lval);
on_all_children_bits(ctxt.0, ctxt.1, &ctxt.2,
let move_path_index = ctxt.rev_lookup.find(dest_lval);
on_all_children_bits(self.tcx, self.mir, ctxt,
move_path_index,
|mpi| { in_out.remove(&mpi); });
}
Expand All @@ -355,21 +355,21 @@ impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> {
impl<'a, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'tcx> {
type Idx = MovePathIndex;
type Bit = MovePath<'tcx>;
type Ctxt = (TyCtxt<'a, 'tcx, 'tcx>, &'a Mir<'tcx>, MoveData<'tcx>);
type Ctxt = MoveData<'tcx>;
fn name() -> &'static str { "definite_init" }
fn bits_per_block(&self, ctxt: &Self::Ctxt) -> usize {
ctxt.2.move_paths.len()
ctxt.move_paths.len()
}
fn interpret<'c>(&self, ctxt: &'c Self::Ctxt, idx: usize) -> &'c Self::Bit {
&ctxt.2.move_paths[MovePathIndex::new(idx)]
&ctxt.move_paths[MovePathIndex::new(idx)]
}

// sets on_entry bits for Arg lvalues
fn start_block_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<MovePathIndex>) {
for e in sets.on_entry.words_mut() { *e = 0; }

drop_flag_effects_for_function_entry(
ctxt.0, ctxt.1, &ctxt.2,
self.tcx, self.mir, ctxt,
|path, s| {
assert!(s == DropFlagState::Present);
sets.on_entry.add(&path);
Expand All @@ -383,7 +383,7 @@ impl<'a, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'tcx> {
idx: usize)
{
drop_flag_effects_for_location(
ctxt.0, ctxt.1, &ctxt.2,
self.tcx, self.mir, ctxt,
Location { block: bb, index: idx },
|path, s| Self::update_bits(sets, path, s)
)
Expand All @@ -396,7 +396,7 @@ impl<'a, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'tcx> {
statements_len: usize)
{
drop_flag_effects_for_location(
ctxt.0, ctxt.1, &ctxt.2,
self.tcx, self.mir, ctxt,
Location { block: bb, index: statements_len },
|path, s| Self::update_bits(sets, path, s)
)
Expand All @@ -410,8 +410,8 @@ impl<'a, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'tcx> {
dest_lval: &repr::Lvalue) {
// when a call returns successfully, that means we need to set
// the bits for that dest_lval to 1 (initialized).
let move_path_index = ctxt.2.rev_lookup.find(dest_lval);
on_all_children_bits(ctxt.0, ctxt.1, &ctxt.2,
let move_path_index = ctxt.rev_lookup.find(dest_lval);
on_all_children_bits(self.tcx, self.mir, ctxt,
move_path_index,
|mpi| { in_out.add(&mpi); });
}
Expand All @@ -420,13 +420,13 @@ impl<'a, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'tcx> {
impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
type Idx = MoveOutIndex;
type Bit = MoveOut;
type Ctxt = (TyCtxt<'a, 'tcx, 'tcx>, &'a Mir<'tcx>, MoveData<'tcx>);
type Ctxt = MoveData<'tcx>;
fn name() -> &'static str { "moving_out" }
fn bits_per_block(&self, ctxt: &Self::Ctxt) -> usize {
ctxt.2.moves.len()
ctxt.moves.len()
}
fn interpret<'c>(&self, ctxt: &'c Self::Ctxt, idx: usize) -> &'c Self::Bit {
&ctxt.2.moves[idx]
&ctxt.moves[idx]
}
fn start_block_effect(&self,_move_data: &Self::Ctxt, _sets: &mut BlockSets<MoveOutIndex>) {
// no move-statements have been executed prior to function
Expand All @@ -437,7 +437,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
sets: &mut BlockSets<MoveOutIndex>,
bb: repr::BasicBlock,
idx: usize) {
let &(tcx, mir, ref move_data) = ctxt;
let (tcx, mir, move_data) = (self.tcx, self.mir, ctxt);
let stmt = &mir.basic_block_data(bb).statements[idx];
let loc_map = &move_data.loc_map;
let path_map = &move_data.path_map;
Expand Down Expand Up @@ -477,7 +477,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
bb: repr::BasicBlock,
statements_len: usize)
{
let &(_tcx, mir, ref move_data) = ctxt;
let (mir, move_data) = (self.mir, ctxt);
let term = mir.basic_block_data(bb).terminator.as_ref().unwrap();
let loc_map = &move_data.loc_map;
let loc = Location { block: bb, index: statements_len };
Expand All @@ -496,13 +496,13 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
_call_bb: repr::BasicBlock,
_dest_bb: repr::BasicBlock,
dest_lval: &repr::Lvalue) {
let move_data = &ctxt.2;
let move_data = ctxt;
let move_path_index = move_data.rev_lookup.find(dest_lval);
let bits_per_block = self.bits_per_block(ctxt);

let path_map = &move_data.path_map;
on_all_children_bits(ctxt.0,
ctxt.1,
on_all_children_bits(self.tcx,
self.mir,
move_data,
move_path_index,
|mpi| for moi in &path_map[mpi] {
Expand Down
12 changes: 6 additions & 6 deletions src/librustc_borrowck/borrowck/mir/dataflow/mod.rs
Expand Up @@ -49,7 +49,7 @@ impl<'a, 'tcx: 'a, BD> Dataflow for MirBorrowckCtxtPreDataflow<'a, 'tcx, BD>
}

struct PropagationContext<'b, 'a: 'b, 'tcx: 'a, O>
where O: 'b + BitDenotation, O::Ctxt: HasMoveData<'tcx>
where O: 'b + BitDenotation, O::Ctxt: 'a+HasMoveData<'tcx>
{
builder: &'b mut DataflowAnalysis<'a, 'tcx, O>,
changed: bool,
Expand Down Expand Up @@ -191,18 +191,18 @@ impl<'tcx, A, B> HasMoveData<'tcx> for (A, B, MoveData<'tcx>) {
}

pub struct DataflowAnalysis<'a, 'tcx: 'a, O>
where O: BitDenotation, O::Ctxt: HasMoveData<'tcx>
where O: BitDenotation, O::Ctxt: 'a+HasMoveData<'tcx>
{
flow_state: DataflowState<O>,
ctxt: O::Ctxt,
mir: &'a Mir<'tcx>,
ctxt: &'a O::Ctxt,
}

impl<'a, 'tcx: 'a, O> DataflowAnalysis<'a, 'tcx, O>
where O: BitDenotation, O::Ctxt: HasMoveData<'tcx>
{
pub fn results(self) -> (O::Ctxt, DataflowResults<O>) {
(self.ctxt, DataflowResults(self.flow_state))
pub fn results(self) -> DataflowResults<O> {
DataflowResults(self.flow_state)
}

pub fn mir(&self) -> &'a Mir<'tcx> { self.mir }
Expand Down Expand Up @@ -440,7 +440,7 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D>
{
pub fn new(_tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &'a Mir<'tcx>,
ctxt: D::Ctxt,
ctxt: &'a D::Ctxt,
denotation: D) -> Self {
let bits_per_block = denotation.bits_per_block(&ctxt);
let usize_bits = mem::size_of::<usize>() * 8;
Expand Down

0 comments on commit 221cce9

Please sign in to comment.