diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs b/src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs index 0d1443ede41..588160fff69 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs @@ -24,7 +24,7 @@ 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}; @@ -79,7 +79,7 @@ pub fn interpret_set<'c, P>(&self, } pub trait MirWithFlowState<'tcx> { - type BD: BitDenotation>; + type BD: BitDenotation>; fn node_id(&self) -> NodeId; fn mir(&self) -> &Mir<'tcx>; fn analysis_ctxt(&self) -> &::Ctxt; @@ -87,7 +87,7 @@ pub trait MirWithFlowState<'tcx> { } impl<'a, 'tcx: 'a, BD> MirWithFlowState<'tcx> for MirBorrowckCtxtPreDataflow<'a, 'tcx, BD> - where 'a, 'tcx: 'a, BD: BitDenotation> + where 'a, 'tcx: 'a, BD: BitDenotation> { type BD = BD; fn node_id(&self) -> NodeId { self.node_id } @@ -109,7 +109,7 @@ pub fn print_borrowck_graph_to<'a, 'tcx, BD, P>( path: &Path, render_idx: P) -> io::Result<()> - where BD: BitDenotation>, + where BD: BitDenotation>, P: for <'b> Fn(&'b BD::Ctxt, BD::Idx) -> &'b Debug { let g = Graph { mbcx: mbcx, phantom: PhantomData, render_idx: render_idx }; diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs b/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs index c580dc8551f..e3435ed9905 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs @@ -12,7 +12,8 @@ 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; @@ -226,10 +227,10 @@ fn update_bits(sets: &mut BlockSets, path: MovePathIndex, 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) @@ -276,8 +277,8 @@ fn propagate_call_return(&self, 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); }); } @@ -285,10 +286,10 @@ fn propagate_call_return(&self, 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 @@ -338,8 +339,8 @@ fn propagate_call_return(&self, 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); }); } @@ -347,10 +348,10 @@ fn propagate_call_return(&self, 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 @@ -399,8 +400,8 @@ fn propagate_call_return(&self, 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); }); } @@ -408,10 +409,10 @@ fn propagate_call_return(&self, 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) { @@ -423,7 +424,7 @@ fn statement_effect(&self, sets: &mut BlockSets, 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; @@ -463,7 +464,7 @@ fn terminator_effect(&self, 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 }; @@ -482,7 +483,7 @@ fn propagate_call_return(&self, _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); diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs b/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs index f91bd88d68f..c105a099701 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs @@ -18,7 +18,7 @@ use std::usize; use super::MirBorrowckCtxtPreDataflow; -use super::gather_moves::{MoveData}; +use super::MoveDataParamEnv; use bitslice::{bitwise, BitwiseOperator}; use indexed_set::{Idx, IdxSet, OwnIdxSet}; @@ -36,7 +36,7 @@ pub trait Dataflow { } impl<'a, 'tcx: 'a, BD> Dataflow for MirBorrowckCtxtPreDataflow<'a, 'tcx, BD> - where BD: BitDenotation> + DataflowOperator + where BD: BitDenotation> + DataflowOperator { fn dataflow

(&mut self, p: P) where P: Fn(&BD::Ctxt, BD::Idx) -> &Debug { self.flow_state.build_sets(); @@ -140,7 +140,7 @@ fn dataflow_path(context: &str, prepost: &str, path: &str) -> PathBuf { } impl<'a, 'tcx: 'a, BD> MirBorrowckCtxtPreDataflow<'a, 'tcx, BD> - where BD: BitDenotation> + where BD: BitDenotation> { fn pre_dataflow_instrumentation

(&self, p: P) -> io::Result<()> where P: Fn(&BD::Ctxt, BD::Idx) -> &Debug diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs index 22176899494..74dc921b0bb 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs @@ -15,7 +15,8 @@ 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; @@ -41,7 +42,7 @@ pub fn sanity_check_via_rustc_peek<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, _attributes: &[ast::Attribute], flow_ctxt: &O::Ctxt, results: &DataflowResults) - where O: BitDenotation, Idx=MovePathIndex> + where O: BitDenotation, Idx=MovePathIndex> { debug!("sanity_check_via_rustc_peek id: {:?}", id); // FIXME: this is not DRY. Figure out way to abstract this and @@ -56,11 +57,12 @@ 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>, - move_data: &O::Ctxt, + ctxt: &O::Ctxt, results: &DataflowResults, bb: repr::BasicBlock) where - O: BitDenotation, Idx=MovePathIndex> + O: BitDenotation, Idx=MovePathIndex> { + let move_data = &ctxt.move_data; let bb_data = mir.basic_block_data(bb); let &repr::BasicBlockData { ref statements, ref terminator, @@ -127,7 +129,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx.sess.span_err(span, msg); } } - + let lhs_mpi = move_data.rev_lookup.find(lvalue); debug!("rustc_peek: computing effect on lvalue: {:?} ({:?}) in stmt: {:?}", @@ -135,7 +137,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // 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); } diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs index 4b77e4c865b..1b9d08bade7 100644 --- a/src/librustc_borrowck/borrowck/mir/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/mod.rs @@ -50,6 +50,11 @@ fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option { + move_data: MoveData<'tcx>, + param_env: ty::ParameterEnvironment<'tcx>, +} + pub fn borrowck_mir<'a, 'tcx: 'a>( bcx: &mut BorrowckCtxt<'a, 'tcx>, fk: FnKind, @@ -72,21 +77,23 @@ pub fn borrowck_mir<'a, 'tcx: 'a>( 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() { @@ -97,7 +104,7 @@ pub fn borrowck_mir<'a, 'tcx: 'a>( bcx: bcx, mir: mir, node_id: id, - move_data: move_data, + move_data: mdpe.move_data, flow_inits: flow_inits, flow_uninits: flow_uninits, }; @@ -115,7 +122,7 @@ fn do_dataflow<'a, 'tcx, BD>(tcx: TyCtxt<'a, 'tcx, 'tcx>, attributes: &[ast::Attribute], ctxt: &BD::Ctxt, bd: BD) -> DataflowResults - where BD: BitDenotation> + DataflowOperator + where BD: BitDenotation> + DataflowOperator { use syntax::attr::AttrMetaMethods; @@ -145,7 +152,7 @@ fn do_dataflow<'a, 'tcx, BD>(tcx: TyCtxt<'a, 'tcx, 'tcx>, 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() } @@ -253,10 +260,11 @@ fn on_all_children_bits<'a, 'tcx, F>( 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); @@ -269,11 +277,13 @@ fn drop_flag_effects_for_function_entry<'a, 'tcx, F>( 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 @@ -284,8 +294,7 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>( // 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; } }