]> git.lizzy.rs Git - rust.git/commitdiff
threaded a `ty::ParameterEnvironment` for the current node id via the associated...
authorFelix S. Klock II <pnkfelix@pnkfx.org>
Tue, 24 May 2016 21:03:52 +0000 (23:03 +0200)
committerFelix S. Klock II <pnkfelix@pnkfx.org>
Tue, 24 May 2016 21:03:52 +0000 (23:03 +0200)
used this to address a long-standing wart/bug in how filtering-out of
values with type impl'ing `Copy` was done.

src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs
src/librustc_borrowck/borrowck/mir/dataflow/impls.rs
src/librustc_borrowck/borrowck/mir/dataflow/mod.rs
src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs
src/librustc_borrowck/borrowck/mir/mod.rs

index 0d1443ede4101d0c0d82339e14bc16630c407d3b..588160fff692b5321f144153dae7c22138b7ab89 100644 (file)
@@ -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<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;
@@ -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<Ctxt=MoveData<'tcx>>
+    where 'a, 'tcx: 'a, BD: BitDenotation<Ctxt=MoveDataParamEnv<'tcx>>
 {
     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<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 };
index c580dc8551f265abfe8fd87bd5f3e6131f8dd02d..e3435ed990506e1238631f97ad3597f2443b553f 100644 (file)
@@ -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<MovePathIndex>, 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<MovePathIndex>)
@@ -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<MoveOutIndex>) {
@@ -423,7 +424,7 @@ fn statement_effect(&self,
                         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;
@@ -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);
 
index f91bd88d68f0695f2c630eda82c9184b1271b6c6..c105a0997017883b527048fa9f34d595fc425b59 100644 (file)
@@ -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<BD: BitDenotation> {
 }
 
 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();
@@ -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<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
index 221768994942d8acb598940b5258bb7f2e328dec..74dc921b0bba55909c9901c3c098c3d5badf535f 100644 (file)
@@ -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<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
@@ -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<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,
@@ -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);
     }
index 4b77e4c865b58fa4cbc0a821437afa4e16643f06..1b9d08bade7c4a798652627ceccf0db9ba977061 100644 (file)
@@ -50,6 +50,11 @@ fn has_rustc_mir_with(attrs: &[ast::Attribute], name: &str) -> Option<P<MetaItem
     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,
@@ -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<BD>
-    where BD: BitDenotation<Idx=MovePathIndex, Ctxt=MoveData<'tcx>> + DataflowOperator
+    where BD: BitDenotation<Idx=MovePathIndex, Ctxt=MoveDataParamEnv<'tcx>> + 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;
             }
         }