about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/borrow_check/nll/mod.rs7
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness.rs12
-rw-r--r--src/librustc_mir/transform/generator.rs52
-rw-r--r--src/librustc_mir/util/liveness.rs63
4 files changed, 71 insertions, 63 deletions
diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index 5fcf46f6903..ba96e7c3b30 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -22,6 +22,7 @@ use rustc::infer::InferCtxt;
 use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Mir};
 use rustc::ty::{self, RegionKind, RegionVid};
 use rustc::util::nodemap::FxHashMap;
+use rustc_data_structures::indexed_vec::Idx;
 use std::collections::BTreeSet;
 use std::fmt::Debug;
 use std::env;
@@ -207,9 +208,9 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
     (regioncx, polonius_output, closure_region_requirements)
 }
 
-fn dump_mir_results<'a, 'gcx, 'tcx>(
+fn dump_mir_results<'a, 'gcx, 'tcx, V: Idx>(
     infcx: &InferCtxt<'a, 'gcx, 'tcx>,
-    liveness: &LivenessResults,
+    liveness: &LivenessResults<V>,
     source: MirSource,
     mir: &Mir<'tcx>,
     regioncx: &RegionInferenceContext,
@@ -405,7 +406,7 @@ impl ToRegionVid for RegionVid {
     }
 }
 
-fn live_variable_set(regular: &LocalSet, drops: &LocalSet) -> String {
+fn live_variable_set<V: Idx>(regular: &LocalSet<V>, drops: &LocalSet<V>) -> String {
     // sort and deduplicate:
     let all_locals: BTreeSet<_> = regular.iter().chain(drops.iter()).collect();
 
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs
index cd468eabd5f..7c0e7941a44 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness.rs
@@ -20,6 +20,7 @@ use rustc::traits::query::type_op::outlives::DropckOutlives;
 use rustc::traits::query::type_op::TypeOp;
 use rustc::ty::{Ty, TypeFoldable};
 use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::indexed_vec::Idx;
 use std::rc::Rc;
 use util::liveness::LivenessResults;
 
@@ -33,10 +34,10 @@ use super::TypeChecker;
 ///
 /// NB. This computation requires normalization; therefore, it must be
 /// performed before
-pub(super) fn generate<'gcx, 'tcx>(
+pub(super) fn generate<'gcx, 'tcx, V: Idx>(
     cx: &mut TypeChecker<'_, 'gcx, 'tcx>,
     mir: &Mir<'tcx>,
-    liveness: &LivenessResults,
+    liveness: &LivenessResults<V>,
     flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
     move_data: &MoveData<'tcx>,
 ) {
@@ -54,16 +55,17 @@ pub(super) fn generate<'gcx, 'tcx>(
     }
 }
 
-struct TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx>
+struct TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx, V>
 where
     'typeck: 'gen,
     'flow: 'gen,
     'tcx: 'typeck + 'flow,
     'gcx: 'tcx,
+    V: Idx + 'gen,
 {
     cx: &'gen mut TypeChecker<'typeck, 'gcx, 'tcx>,
     mir: &'gen Mir<'tcx>,
-    liveness: &'gen LivenessResults,
+    liveness: &'gen LivenessResults<V>,
     flow_inits: &'gen mut FlowAtLocation<MaybeInitializedPlaces<'flow, 'gcx, 'tcx>>,
     move_data: &'gen MoveData<'tcx>,
     drop_data: FxHashMap<Ty<'tcx>, DropData<'tcx>>,
@@ -74,7 +76,7 @@ struct DropData<'tcx> {
     region_constraint_data: Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>,
 }
 
-impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx> {
+impl<'gen, 'typeck, 'flow, 'gcx, 'tcx, V: Idx> TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx, V> {
     /// Liveness constraints:
     ///
     /// > If a variable V is live at point P, then all regions R in the type of V
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index a6017fafcc8..0b8c7e512fb 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -126,14 +126,14 @@ fn self_arg() -> Local {
     Local::new(1)
 }
 
-struct SuspensionPoint {
+struct SuspensionPoint<V: Idx> {
     state: u32,
     resume: BasicBlock,
     drop: Option<BasicBlock>,
-    storage_liveness: liveness::LocalSet,
+    storage_liveness: liveness::LocalSet<V>,
 }
 
-struct TransformVisitor<'a, 'tcx: 'a> {
+struct TransformVisitor<'a, 'tcx: 'a, V: Idx> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     state_adt_ref: &'tcx AdtDef,
     state_substs: &'tcx Substs<'tcx>,
@@ -145,16 +145,16 @@ struct TransformVisitor<'a, 'tcx: 'a> {
     remap: HashMap<Local, (Ty<'tcx>, usize)>,
 
     // A map from a suspension point in a block to the locals which have live storage at that point
-    storage_liveness: HashMap<BasicBlock, liveness::LocalSet>,
+    storage_liveness: HashMap<BasicBlock, liveness::LocalSet<V>>,
 
     // A list of suspension points, generated during the transform
-    suspension_points: Vec<SuspensionPoint>,
+    suspension_points: Vec<SuspensionPoint<V>>,
 
     // The original RETURN_PLACE local
     new_ret_local: Local,
 }
 
-impl<'a, 'tcx> TransformVisitor<'a, 'tcx> {
+impl<'a, 'tcx, V: Idx> TransformVisitor<'a, 'tcx, V> {
     // Make a GeneratorState rvalue
     fn make_state(&self, idx: usize, val: Operand<'tcx>) -> Rvalue<'tcx> {
         let adt = AggregateKind::Adt(self.state_adt_ref, idx, self.state_substs, None);
@@ -191,7 +191,7 @@ impl<'a, 'tcx> TransformVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx> {
+impl<'a, 'tcx, V: Idx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx, V> {
     fn visit_local(&mut self,
                    local: &mut Local,
                    _: PlaceContext<'tcx>,
@@ -317,9 +317,9 @@ fn replace_result_variable<'tcx>(ret_ty: Ty<'tcx>,
     new_ret_local
 }
 
-struct StorageIgnored(liveness::LocalSet);
+struct StorageIgnored<V: Idx>(liveness::LocalSet<V>);
 
-impl<'tcx> Visitor<'tcx> for StorageIgnored {
+impl<'tcx, V: Idx> Visitor<'tcx> for StorageIgnored<V> {
     fn visit_statement(&mut self,
                        _block: BasicBlock,
                        statement: &Statement<'tcx>,
@@ -332,9 +332,9 @@ impl<'tcx> Visitor<'tcx> for StorageIgnored {
     }
 }
 
-struct BorrowedLocals(liveness::LocalSet);
+struct BorrowedLocals<V: Idx>(liveness::LocalSet<V>);
 
-fn mark_as_borrowed<'tcx>(place: &Place<'tcx>, locals: &mut BorrowedLocals) {
+fn mark_as_borrowed<'tcx, V: Idx>(place: &Place<'tcx>, locals: &mut BorrowedLocals<V>) {
     match *place {
         Place::Local(l) => { locals.0.add(&l); },
         Place::Static(..) => (),
@@ -349,7 +349,7 @@ fn mark_as_borrowed<'tcx>(place: &Place<'tcx>, locals: &mut BorrowedLocals) {
     }
 }
 
-impl<'tcx> Visitor<'tcx> for BorrowedLocals {
+impl<'tcx, V: Idx> Visitor<'tcx> for BorrowedLocals<V> {
     fn visit_rvalue(&mut self,
                     rvalue: &Rvalue<'tcx>,
                     location: Location) {
@@ -361,12 +361,12 @@ impl<'tcx> Visitor<'tcx> for BorrowedLocals {
     }
 }
 
-fn locals_live_across_suspend_points<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+fn locals_live_across_suspend_points<'a, 'tcx, V: Idx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                mir: &Mir<'tcx>,
                                                source: MirSource,
                                                movable: bool) ->
-                                               (liveness::LocalSet,
-                                                HashMap<BasicBlock, liveness::LocalSet>) {
+                                               (liveness::LocalSet<V>,
+                                                HashMap<BasicBlock, liveness::LocalSet<V>>) {
     let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
     let node_id = tcx.hir.as_local_node_id(source.def_id).unwrap();
 
@@ -460,7 +460,7 @@ fn locals_live_across_suspend_points<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     (set, storage_liveness_map)
 }
 
-fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+fn compute_layout<'a, 'tcx, V: Idx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             source: MirSource,
                             upvars: Vec<Ty<'tcx>>,
                             interior: Ty<'tcx>,
@@ -468,7 +468,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             mir: &mut Mir<'tcx>)
     -> (HashMap<Local, (Ty<'tcx>, usize)>,
         GeneratorLayout<'tcx>,
-        HashMap<BasicBlock, liveness::LocalSet>)
+        HashMap<BasicBlock, liveness::LocalSet<V>>)
 {
     // Use a liveness analysis to compute locals which are live across a suspension point
     let (live_locals, storage_liveness) = locals_live_across_suspend_points(tcx,
@@ -524,10 +524,10 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     (remap, layout, storage_liveness)
 }
 
-fn insert_switch<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+fn insert_switch<'a, 'tcx, V: Idx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                            mir: &mut Mir<'tcx>,
                            cases: Vec<(u32, BasicBlock)>,
-                           transform: &TransformVisitor<'a, 'tcx>,
+                           transform: &TransformVisitor<'a, 'tcx, V>,
                            default: TerminatorKind<'tcx>) {
     let default_block = insert_term_block(mir, default);
 
@@ -608,9 +608,9 @@ fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 }
 
-fn create_generator_drop_shim<'a, 'tcx>(
+fn create_generator_drop_shim<'a, 'tcx, V: Idx>(
                 tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                transform: &TransformVisitor<'a, 'tcx>,
+                transform: &TransformVisitor<'a, 'tcx, V>,
                 def_id: DefId,
                 source: MirSource,
                 gen_ty: Ty<'tcx>,
@@ -719,9 +719,9 @@ fn insert_panic_block<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     assert_block
 }
 
-fn create_generator_resume_function<'a, 'tcx>(
+fn create_generator_resume_function<'a, 'tcx, V: Idx>(
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
-        transform: TransformVisitor<'a, 'tcx>,
+        transform: TransformVisitor<'a, 'tcx, V>,
         def_id: DefId,
         source: MirSource,
         mir: &mut Mir<'tcx>) {
@@ -790,10 +790,10 @@ fn insert_clean_drop<'a, 'tcx>(mir: &mut Mir<'tcx>) -> BasicBlock {
     drop_clean
 }
 
-fn create_cases<'a, 'tcx, F>(mir: &mut Mir<'tcx>,
-                          transform: &TransformVisitor<'a, 'tcx>,
+fn create_cases<'a, 'tcx, F, V: Idx>(mir: &mut Mir<'tcx>,
+                          transform: &TransformVisitor<'a, 'tcx, V>,
                           target: F) -> Vec<(u32, BasicBlock)>
-    where F: Fn(&SuspensionPoint) -> Option<BasicBlock> {
+    where F: Fn(&SuspensionPoint<V>) -> Option<BasicBlock> {
     let source_info = source_info(mir);
 
     transform.suspension_points.iter().filter_map(|point| {
diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs
index e1d5e302c3a..5c1b92b672f 100644
--- a/src/librustc_mir/util/liveness.rs
+++ b/src/librustc_mir/util/liveness.rs
@@ -47,18 +47,18 @@ use rustc::ty::TyCtxt;
 use std::io::{self, Write};
 use transform::MirSource;
 
-pub type LocalSet = IdxSetBuf<Local>;
+pub type LocalSet<V: Idx> = IdxSetBuf<V>;
 
 /// This gives the result of the liveness analysis at the boundary of
 /// basic blocks. You can use `simulate_block` to obtain the
 /// intra-block results.
-pub struct LivenessResult {
+pub struct LivenessResult<V: Idx> {
     /// Liveness mode in use when these results were computed.
     pub mode: LivenessMode,
 
     /// Live variables on exit to each basic block. This is equal to
     /// the union of the `ins` for each successor.
-    pub outs: IndexVec<BasicBlock, LocalSet>,
+    pub outs: IndexVec<BasicBlock, LocalSet<V>>,
 }
 
 #[derive(Copy, Clone, Debug)]
@@ -80,18 +80,18 @@ pub struct LivenessMode {
 }
 
 /// A combination of liveness results, used in NLL.
-pub struct LivenessResults {
+pub struct LivenessResults<V: Idx> {
     /// Liveness results where a regular use makes a variable X live,
     /// but not a drop.
-    pub regular: LivenessResult,
+    pub regular: LivenessResult<V>,
 
     /// Liveness results where a drop makes a variable X live,
     /// but not a regular use.
-    pub drop: LivenessResult,
+    pub drop: LivenessResult<V>,
 }
 
-impl LivenessResults {
-    pub fn compute<'tcx>(mir: &Mir<'tcx>) -> LivenessResults {
+impl<V: Idx> LivenessResults<V> {
+    pub fn compute<'tcx>(mir: &Mir<'tcx>) -> LivenessResults<V> {
         LivenessResults {
             regular: liveness_of_locals(
                 &mir,
@@ -115,7 +115,7 @@ impl LivenessResults {
 /// Compute which local variables are live within the given function
 /// `mir`. The liveness mode `mode` determines what sorts of uses are
 /// considered to make a variable live (e.g., do drops count?).
-pub fn liveness_of_locals<'tcx>(mir: &Mir<'tcx>, mode: LivenessMode) -> LivenessResult {
+pub fn liveness_of_locals<'tcx, V: Idx>(mir: &Mir<'tcx>, mode: LivenessMode) -> LivenessResult<V> {
     let locals = mir.local_decls.len();
     let def_use: IndexVec<_, _> = mir.basic_blocks()
         .iter()
@@ -156,14 +156,16 @@ pub fn liveness_of_locals<'tcx>(mir: &Mir<'tcx>, mode: LivenessMode) -> Liveness
     LivenessResult { mode, outs }
 }
 
-impl LivenessResult {
+impl<V> LivenessResult<V>
+where V:Idx
+{
     /// Walks backwards through the statements/terminator in the given
     /// basic block `block`.  At each point within `block`, invokes
     /// the callback `op` with the current location and the set of
     /// variables that are live on entry to that location.
     pub fn simulate_block<'tcx, OP>(&self, mir: &Mir<'tcx>, block: BasicBlock, mut callback: OP)
     where
-        OP: FnMut(Location, &LocalSet),
+        OP: FnMut(Location, &LocalSet<V>),
     {
         let data = &mir[block];
 
@@ -281,24 +283,25 @@ pub fn categorize<'tcx>(context: PlaceContext<'tcx>, mode: LivenessMode) -> Opti
     }
 }
 
-struct DefsUsesVisitor {
+struct DefsUsesVisitor<V: Idx> {
     mode: LivenessMode,
-    defs_uses: DefsUses,
+    defs_uses: DefsUses<V>,
 }
 
 #[derive(Eq, PartialEq, Clone)]
-struct DefsUses {
-    defs: LocalSet,
-    uses: LocalSet,
+struct DefsUses<V: Idx>
+{
+    defs: LocalSet<V>,
+    uses: LocalSet<V>,
 }
 
-impl DefsUses {
+impl<V: Idx> DefsUses<V> {
     fn clear(&mut self) {
         self.uses.clear();
         self.defs.clear();
     }
 
-    fn apply(&self, bits: &mut LocalSet) -> bool {
+    fn apply(&self, bits: &mut LocalSet<V>) -> bool {
         bits.subtract(&self.defs) | bits.union(&self.uses)
     }
 
@@ -332,15 +335,17 @@ impl DefsUses {
     }
 }
 
-impl DefsUsesVisitor {
+impl<V> DefsUsesVisitor<V>
+where V: Idx
+{
     /// Update `bits` with the effects of `value` and call `callback`. We
     /// should always visit in reverse order. This method assumes that we have
     /// not visited anything before; if you have, clear `bits` first.
     fn update_bits_and_do_callback<'tcx, OP>(&mut self, location: Location,
-                                             value: &impl MirVisitable<'tcx>, bits: &mut LocalSet,
+                                             value: &impl MirVisitable<'tcx>, bits: &mut LocalSet<V>,
                                              callback: &mut OP)
     where
-        OP: FnMut(Location, &LocalSet),
+        OP: FnMut(Location, &LocalSet<V>),
     {
         value.apply(location, self);
         self.defs_uses.apply(bits);
@@ -348,7 +353,7 @@ impl DefsUsesVisitor {
     }
 }
 
-impl<'tcx> Visitor<'tcx> for DefsUsesVisitor {
+impl<'tcx, V: Idx> Visitor<'tcx> for DefsUsesVisitor<V> {
     fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) {
         match categorize(context, self.mode) {
             Some(DefUse::Def) => {
@@ -364,7 +369,7 @@ impl<'tcx> Visitor<'tcx> for DefsUsesVisitor {
     }
 }
 
-fn block<'tcx>(mode: LivenessMode, b: &BasicBlockData<'tcx>, locals: usize) -> DefsUses {
+fn block<'tcx, V: Idx>(mode: LivenessMode, b: &BasicBlockData<'tcx>, locals: usize) -> DefsUses<V> {
     let mut visitor = DefsUsesVisitor {
         mode,
         defs_uses: DefsUses {
@@ -388,12 +393,12 @@ fn block<'tcx>(mode: LivenessMode, b: &BasicBlockData<'tcx>, locals: usize) -> D
     visitor.defs_uses
 }
 
-pub fn dump_mir<'a, 'tcx>(
+pub fn dump_mir<'a, 'tcx, V: Idx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     pass_name: &str,
     source: MirSource,
     mir: &Mir<'tcx>,
-    result: &LivenessResult,
+    result: &LivenessResult<V>,
 ) {
     if !dump_enabled(tcx, pass_name, source) {
         return;
@@ -405,13 +410,13 @@ pub fn dump_mir<'a, 'tcx>(
     dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, result);
 }
 
-fn dump_matched_mir_node<'a, 'tcx>(
+fn dump_matched_mir_node<'a, 'tcx, V: Idx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     pass_name: &str,
     node_path: &str,
     source: MirSource,
     mir: &Mir<'tcx>,
-    result: &LivenessResult,
+    result: &LivenessResult<V>,
 ) {
     let mut file_path = PathBuf::new();
     file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir));
@@ -428,12 +433,12 @@ fn dump_matched_mir_node<'a, 'tcx>(
     });
 }
 
-pub fn write_mir_fn<'a, 'tcx>(
+pub fn write_mir_fn<'a, 'tcx, V :Idx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     src: MirSource,
     mir: &Mir<'tcx>,
     w: &mut dyn Write,
-    result: &LivenessResult,
+    result: &LivenessResult<V>,
 ) -> io::Result<()> {
     write_mir_intro(tcx, src, mir, w)?;
     for block in mir.basic_blocks().indices() {