use std::mem;
use std::path::Path;
-use super::super::gather_moves::{MoveData};
+use super::super::MoveDataParamEnv;
use super::super::MirBorrowckCtxtPreDataflow;
use bitslice::bits_to_string;
use indexed_set::{Idx, IdxSet};
}
pub trait MirWithFlowState<'tcx> {
- type BD: BitDenotation<Ctxt=MoveData<'tcx>>;
+ type BD: BitDenotation<Ctxt=MoveDataParamEnv<'tcx>>;
fn node_id(&self) -> NodeId;
fn mir(&self) -> &Mir<'tcx>;
fn analysis_ctxt(&self) -> &<Self::BD as BitDenotation>::Ctxt;
}
impl<'a, 'tcx: 'a, BD> MirWithFlowState<'tcx> for MirBorrowckCtxtPreDataflow<'a, 'tcx, BD>
- where 'a, 'tcx: 'a, BD: BitDenotation<Ctxt=MoveData<'tcx>>
+ where 'a, 'tcx: 'a, BD: BitDenotation<Ctxt=MoveDataParamEnv<'tcx>>
{
type BD = BD;
fn node_id(&self) -> NodeId { self.node_id }
path: &Path,
render_idx: P)
-> io::Result<()>
- where BD: BitDenotation<Ctxt=MoveData<'tcx>>,
+ where BD: BitDenotation<Ctxt=MoveDataParamEnv<'tcx>>,
P: for <'b> Fn(&'b BD::Ctxt, BD::Idx) -> &'b Debug
{
let g = Graph { mbcx: mbcx, phantom: PhantomData, render_idx: render_idx };
use rustc::mir::repr::{self, Mir};
use super::super::gather_moves::{Location};
-use super::super::gather_moves::{MoveData, MoveOutIndex, MovePathIndex};
+use super::super::gather_moves::{MoveOutIndex, MovePathIndex};
+use super::super::MoveDataParamEnv;
use super::super::DropFlagState;
use super::super::drop_flag_effects_for_function_entry;
use super::super::drop_flag_effects_for_location;
impl<'a, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'tcx> {
type Idx = MovePathIndex;
- type Ctxt = MoveData<'tcx>;
+ type Ctxt = MoveDataParamEnv<'tcx>;
fn name() -> &'static str { "maybe_init" }
fn bits_per_block(&self, ctxt: &Self::Ctxt) -> usize {
- ctxt.move_paths.len()
+ ctxt.move_data.move_paths.len()
}
fn start_block_effect(&self, ctxt: &Self::Ctxt, sets: &mut BlockSets<MovePathIndex>)
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.rev_lookup.find(dest_lval);
- on_all_children_bits(self.tcx, self.mir, ctxt,
+ let move_path_index = ctxt.move_data.rev_lookup.find(dest_lval);
+ on_all_children_bits(self.tcx, self.mir, &ctxt.move_data,
move_path_index,
|mpi| { in_out.add(&mpi); });
}
impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> {
type Idx = MovePathIndex;
- type Ctxt = MoveData<'tcx>;
+ type Ctxt = MoveDataParamEnv<'tcx>;
fn name() -> &'static str { "maybe_uninit" }
fn bits_per_block(&self, ctxt: &Self::Ctxt) -> usize {
- ctxt.move_paths.len()
+ ctxt.move_data.move_paths.len()
}
// sets on_entry bits for Arg lvalues
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.rev_lookup.find(dest_lval);
- on_all_children_bits(self.tcx, self.mir, ctxt,
+ let move_path_index = ctxt.move_data.rev_lookup.find(dest_lval);
+ on_all_children_bits(self.tcx, self.mir, &ctxt.move_data,
move_path_index,
|mpi| { in_out.remove(&mpi); });
}
impl<'a, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'tcx> {
type Idx = MovePathIndex;
- type Ctxt = MoveData<'tcx>;
+ type Ctxt = MoveDataParamEnv<'tcx>;
fn name() -> &'static str { "definite_init" }
fn bits_per_block(&self, ctxt: &Self::Ctxt) -> usize {
- ctxt.move_paths.len()
+ ctxt.move_data.move_paths.len()
}
// sets on_entry bits for Arg lvalues
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.rev_lookup.find(dest_lval);
- on_all_children_bits(self.tcx, self.mir, ctxt,
+ let move_path_index = ctxt.move_data.rev_lookup.find(dest_lval);
+ on_all_children_bits(self.tcx, self.mir, &ctxt.move_data,
move_path_index,
|mpi| { in_out.add(&mpi); });
}
impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
type Idx = MoveOutIndex;
- type Ctxt = MoveData<'tcx>;
+ type Ctxt = MoveDataParamEnv<'tcx>;
fn name() -> &'static str { "moving_out" }
fn bits_per_block(&self, ctxt: &Self::Ctxt) -> usize {
- ctxt.moves.len()
+ ctxt.move_data.moves.len()
}
fn start_block_effect(&self,_move_data: &Self::Ctxt, _sets: &mut BlockSets<MoveOutIndex>) {
sets: &mut BlockSets<MoveOutIndex>,
bb: repr::BasicBlock,
idx: usize) {
- let (tcx, mir, move_data) = (self.tcx, self.mir, ctxt);
+ let (tcx, mir, move_data) = (self.tcx, self.mir, &ctxt.move_data);
let stmt = &mir.basic_block_data(bb).statements[idx];
let loc_map = &move_data.loc_map;
let path_map = &move_data.path_map;
bb: repr::BasicBlock,
statements_len: usize)
{
- let (mir, move_data) = (self.mir, ctxt);
+ let (mir, move_data) = (self.mir, &ctxt.move_data);
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 };
_call_bb: repr::BasicBlock,
_dest_bb: repr::BasicBlock,
dest_lval: &repr::Lvalue) {
- let move_data = ctxt;
+ let move_data = &ctxt.move_data;
let move_path_index = move_data.rev_lookup.find(dest_lval);
let bits_per_block = self.bits_per_block(ctxt);
use std::usize;
use super::MirBorrowckCtxtPreDataflow;
-use super::gather_moves::{MoveData};
+use super::MoveDataParamEnv;
use bitslice::{bitwise, BitwiseOperator};
use indexed_set::{Idx, IdxSet, OwnIdxSet};
}
impl<'a, 'tcx: 'a, BD> Dataflow<BD> for MirBorrowckCtxtPreDataflow<'a, 'tcx, BD>
- where BD: BitDenotation<Ctxt=MoveData<'tcx>> + DataflowOperator
+ where BD: BitDenotation<Ctxt=MoveDataParamEnv<'tcx>> + DataflowOperator
{
fn dataflow<P>(&mut self, p: P) where P: Fn(&BD::Ctxt, BD::Idx) -> &Debug {
self.flow_state.build_sets();
}
impl<'a, 'tcx: 'a, BD> MirBorrowckCtxtPreDataflow<'a, 'tcx, BD>
- where BD: BitDenotation<Ctxt=MoveData<'tcx>>
+ where BD: BitDenotation<Ctxt=MoveDataParamEnv<'tcx>>
{
fn pre_dataflow_instrumentation<P>(&self, p: P) -> io::Result<()>
where P: Fn(&BD::Ctxt, BD::Idx) -> &Debug
use rustc::ty::{self, TyCtxt};
use rustc::mir::repr::{self, Mir};
-use super::super::gather_moves::{MoveData, MovePathIndex};
+use super::super::gather_moves::{MovePathIndex};
+use super::super::MoveDataParamEnv;
use super::BitDenotation;
use super::DataflowResults;
_attributes: &[ast::Attribute],
flow_ctxt: &O::Ctxt,
results: &DataflowResults<O>)
- where O: BitDenotation<Ctxt=MoveData<'tcx>, Idx=MovePathIndex>
+ where O: BitDenotation<Ctxt=MoveDataParamEnv<'tcx>, Idx=MovePathIndex>
{
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>,
- move_data: &O::Ctxt,
+ ctxt: &O::Ctxt,
results: &DataflowResults<O>,
bb: repr::BasicBlock) where
- O: BitDenotation<Ctxt=MoveData<'tcx>, Idx=MovePathIndex>
+ O: BitDenotation<Ctxt=MoveDataParamEnv<'tcx>, Idx=MovePathIndex>
{
+ let move_data = &ctxt.move_data;
let bb_data = mir.basic_block_data(bb);
let &repr::BasicBlockData { ref statements,
ref terminator,
tcx.sess.span_err(span, msg);
}
}
-
+
let lhs_mpi = move_data.rev_lookup.find(lvalue);
debug!("rustc_peek: computing effect on lvalue: {:?} ({:?}) in stmt: {:?}",
// reset GEN and KILL sets before emulating their effect.
for e in sets.gen_set.words_mut() { *e = 0; }
for e in sets.kill_set.words_mut() { *e = 0; }
- results.0.operator.statement_effect(move_data, &mut sets, bb, j);
+ results.0.operator.statement_effect(ctxt, &mut sets, bb, j);
sets.on_entry.union(sets.gen_set);
sets.on_entry.subtract(sets.kill_set);
}
return None;
}
+pub struct MoveDataParamEnv<'tcx> {
+ move_data: MoveData<'tcx>,
+ param_env: ty::ParameterEnvironment<'tcx>,
+}
+
pub fn borrowck_mir<'a, 'tcx: 'a>(
bcx: &mut BorrowckCtxt<'a, 'tcx>,
fk: FnKind,
let tcx = bcx.tcx;
let move_data = MoveData::gather_moves(mir, tcx);
+ let param_env = ty::ParameterEnvironment::for_item(tcx, id);
+ let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
let flow_inits =
- do_dataflow(tcx, mir, id, attributes, &move_data, MaybeInitializedLvals::new(tcx, mir));
+ do_dataflow(tcx, mir, id, attributes, &mdpe, MaybeInitializedLvals::new(tcx, mir));
let flow_uninits =
- do_dataflow(tcx, mir, id, attributes, &move_data, MaybeUninitializedLvals::new(tcx, mir));
+ do_dataflow(tcx, mir, id, attributes, &mdpe, MaybeUninitializedLvals::new(tcx, mir));
let flow_def_inits =
- do_dataflow(tcx, mir, id, attributes, &move_data, DefinitelyInitializedLvals::new(tcx, mir));
+ do_dataflow(tcx, mir, id, attributes, &mdpe, DefinitelyInitializedLvals::new(tcx, mir));
if has_rustc_mir_with(attributes, "rustc_peek_maybe_init").is_some() {
- dataflow::sanity_check_via_rustc_peek(bcx.tcx, mir, id, attributes, &move_data, &flow_inits);
+ dataflow::sanity_check_via_rustc_peek(bcx.tcx, mir, id, attributes, &mdpe, &flow_inits);
}
if has_rustc_mir_with(attributes, "rustc_peek_maybe_uninit").is_some() {
- dataflow::sanity_check_via_rustc_peek(bcx.tcx, mir, id, attributes, &move_data, &flow_uninits);
+ dataflow::sanity_check_via_rustc_peek(bcx.tcx, mir, id, attributes, &mdpe, &flow_uninits);
}
if has_rustc_mir_with(attributes, "rustc_peek_definite_init").is_some() {
- dataflow::sanity_check_via_rustc_peek(bcx.tcx, mir, id, attributes, &move_data, &flow_def_inits);
+ dataflow::sanity_check_via_rustc_peek(bcx.tcx, mir, id, attributes, &mdpe, &flow_def_inits);
}
if has_rustc_mir_with(attributes, "stop_after_dataflow").is_some() {
bcx: bcx,
mir: mir,
node_id: id,
- move_data: move_data,
+ move_data: mdpe.move_data,
flow_inits: flow_inits,
flow_uninits: flow_uninits,
};
attributes: &[ast::Attribute],
ctxt: &BD::Ctxt,
bd: BD) -> DataflowResults<BD>
- where BD: BitDenotation<Idx=MovePathIndex, Ctxt=MoveData<'tcx>> + DataflowOperator
+ where BD: BitDenotation<Idx=MovePathIndex, Ctxt=MoveDataParamEnv<'tcx>> + DataflowOperator
{
use syntax::attr::AttrMetaMethods;
flow_state: DataflowAnalysis::new(tcx, mir, ctxt, bd),
};
- mbcx.dataflow(|move_data, i| &move_data.move_paths[i]);
+ mbcx.dataflow(|ctxt, i| &ctxt.move_data.move_paths[i]);
mbcx.flow_state.results()
}
fn drop_flag_effects_for_function_entry<'a, 'tcx, F>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &Mir<'tcx>,
- move_data: &MoveData<'tcx>,
+ ctxt: &MoveDataParamEnv<'tcx>,
mut callback: F)
where F: FnMut(MovePathIndex, DropFlagState)
{
+ let move_data = &ctxt.move_data;
for i in 0..(mir.arg_decls.len() as u32) {
let lvalue = repr::Lvalue::Arg(i);
let move_path_index = move_data.rev_lookup.find(&lvalue);
fn drop_flag_effects_for_location<'a, 'tcx, F>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &Mir<'tcx>,
- move_data: &MoveData<'tcx>,
+ ctxt: &MoveDataParamEnv<'tcx>,
loc: Location,
mut callback: F)
where F: FnMut(MovePathIndex, DropFlagState)
{
+ let move_data = &ctxt.move_data;
+ let param_env = &ctxt.param_env;
debug!("drop_flag_effects_for_location({:?})", loc);
// first, move out of the RHS
// don't move out of non-Copy things
if let MovePathContent::Lvalue(ref lvalue) = move_data.move_paths[path].content {
let ty = mir.lvalue_ty(tcx, lvalue).to_ty(tcx);
- let empty_param_env = tcx.empty_parameter_environment();
- if !ty.moves_by_default(tcx, &empty_param_env, DUMMY_SP) {
+ if !ty.moves_by_default(tcx, param_env, DUMMY_SP) {
continue;
}
}