about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/borrow_check/nll/constraint_set.rs33
-rw-r--r--src/librustc_mir/borrow_check/nll/mod.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/mod.rs54
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs5
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs5
7 files changed, 60 insertions, 43 deletions
diff --git a/src/librustc_mir/borrow_check/nll/constraint_set.rs b/src/librustc_mir/borrow_check/nll/constraint_set.rs
new file mode 100644
index 00000000000..4b0a0c9bce9
--- /dev/null
+++ b/src/librustc_mir/borrow_check/nll/constraint_set.rs
@@ -0,0 +1,33 @@
+use borrow_check::nll::region_infer::{ConstraintIndex, OutlivesConstraint};
+use rustc_data_structures::indexed_vec::IndexVec;
+use rustc_data_structures::fx::FxHashSet;
+use rustc::ty::RegionVid;
+
+#[derive(Clone, Default)]
+crate struct ConstraintSet {
+    constraints: IndexVec<ConstraintIndex, OutlivesConstraint>,
+    seen_constraints: FxHashSet<(RegionVid, RegionVid)>,
+}
+
+impl ConstraintSet {
+    pub fn push(&mut self, outlives_constraint: OutlivesConstraint) {
+        debug!("add_outlives({:?}: {:?} @ {:?}", outlives_constraint.sup, outlives_constraint.sub, outlives_constraint.point);
+        if outlives_constraint.sup == outlives_constraint.sub {
+            // 'a: 'a is pretty uninteresting
+            return;
+        }
+        if self.seen_constraints.insert(outlives_constraint.dedup_key()) {
+            self.constraints.push(outlives_constraint);
+        }
+    }
+
+    pub fn iner(&self) -> &IndexVec<ConstraintIndex, OutlivesConstraint> {
+        &self.constraints
+    }
+
+    /// Do Not use this to add nor remove items to the Vec, nor change the `sup`, nor `sub` of the data.
+    pub fn iner_mut(&mut self) -> &mut IndexVec<ConstraintIndex, OutlivesConstraint> {
+        &mut self.constraints
+    }
+}
+
diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index e26665e8291..07b160ed66f 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -45,6 +45,8 @@ mod renumber;
 crate mod type_check;
 mod universal_regions;
 
+crate mod constraint_set;
+
 use self::facts::AllFacts;
 use self::region_infer::RegionInferenceContext;
 use self::universal_regions::UniversalRegions;
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs b/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
index 6c796ea4c73..7c17f6a1aeb 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/dump_mir.rs
@@ -76,7 +76,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             }
         }
 
-        let mut constraints: Vec<_> = self.constraints.iter().collect();
+        let mut constraints: Vec<_> = self.constraints.iner().iter().collect();
         constraints.sort();
         for constraint in &constraints {
             let OutlivesConstraint {
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs b/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
index c02e4ff3156..ad15a435359 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/graphviz.rs
@@ -55,7 +55,7 @@ impl<'this, 'tcx> dot::GraphWalk<'this> for RegionInferenceContext<'tcx> {
         vids.into_cow()
     }
     fn edges(&'this self) -> dot::Edges<'this, OutlivesConstraint> {
-        (&self.constraints.raw[..]).into_cow()
+        (&self.constraints.iner().raw[..]).into_cow()
     }
 
     // Render `a: b` as `a <- b`, indicating the flow
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
index 624636652f3..5da486815e1 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -10,6 +10,7 @@
 
 use super::universal_regions::UniversalRegions;
 use borrow_check::nll::region_infer::values::ToElementIndex;
+use borrow_check::nll::constraint_set::ConstraintSet;
 use rustc::hir::def_id::DefId;
 use rustc::infer::canonical::QueryRegionConstraint;
 use rustc::infer::error_reporting::nice_region_error::NiceRegionError;
@@ -24,7 +25,6 @@ use rustc::mir::{
 use rustc::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable};
 use rustc::util::common::{self, ErrorReported};
 use rustc_data_structures::bitvec::BitVector;
-use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 use std::fmt;
 use std::rc::Rc;
@@ -66,8 +66,7 @@ pub struct RegionInferenceContext<'tcx> {
     dependency_map: Option<IndexVec<RegionVid, Option<ConstraintIndex>>>,
 
     /// The constraints we have accumulated and used during solving.
-    constraints: IndexVec<ConstraintIndex, OutlivesConstraint>,
-    seen_constraints: FxHashSet<(RegionVid, RegionVid)>,
+    constraints: ConstraintSet,
 
     /// Type constraints that we check after solving.
     type_tests: Vec<TypeTest<'tcx>>,
@@ -146,7 +145,7 @@ pub struct OutlivesConstraint {
 }
 
 impl OutlivesConstraint {
-    fn dedup_key(&self) -> (RegionVid, RegionVid) {
+    pub fn dedup_key(&self) -> (RegionVid, RegionVid) {
         (self.sup, self.sub)
     }
 }
@@ -251,11 +250,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         var_infos: VarInfos,
         universal_regions: UniversalRegions<'tcx>,
         mir: &Mir<'tcx>,
-        mut outlives_constraints: Vec<OutlivesConstraint>,
+        outlives_constraints: ConstraintSet,
         type_tests: Vec<TypeTest<'tcx>>,
     ) -> Self {
         // The `next` field should not yet have been initialized:
-        debug_assert!(outlives_constraints.iter().all(|c| c.next.is_none()));
+        debug_assert!(outlives_constraints.iner().iter().all(|c| c.next.is_none()));
 
         let num_region_variables = var_infos.len();
         let num_universal_regions = universal_regions.len();
@@ -268,18 +267,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             .map(|info| RegionDefinition::new(info.origin))
             .collect();
 
-        let mut seen_constraints: FxHashSet<(RegionVid, RegionVid)> = Default::default();
-
-        outlives_constraints.retain(|c| c.sup != c.sub && seen_constraints.insert(c.dedup_key()));
-
         let mut result = Self {
             definitions,
             elements: elements.clone(),
             liveness_constraints: RegionValues::new(elements, num_region_variables),
             inferred_values: None,
             dependency_map: None,
-            constraints: IndexVec::from_raw(outlives_constraints),
-            seen_constraints,
+            constraints: outlives_constraints,
             type_tests,
             universal_regions,
         };
@@ -405,7 +399,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         sub: RegionVid,
         point: Location,
     ) {
-        self.add_outlives_iner(OutlivesConstraint {
+        assert!(self.inferred_values.is_none(), "values already inferred");
+        self.constraints.push(OutlivesConstraint {
             span,
             sup,
             sub,
@@ -414,22 +409,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         })
     }
 
-    /// Indicates that the region variable `sup` must outlive `sub` is live at the point `point`.
-    fn add_outlives_iner(
-        &mut self,
-        outlives_constraint: OutlivesConstraint
-    ) {
-        debug!("add_outlives({:?}: {:?} @ {:?}", outlives_constraint.sup, outlives_constraint.sub, outlives_constraint.point);
-        assert!(self.inferred_values.is_none(), "values already inferred");
-        if outlives_constraint.sup == outlives_constraint.sub {
-            // 'a: 'a is pretty uninteresting
-            return;
-        }
-        if self.seen_constraints.insert(outlives_constraint.dedup_key()) {
-            self.constraints.push(outlives_constraint);
-        }
-    }
-
     /// Perform region inference and report errors if we see any
     /// unsatisfiable constraints. If this is a closure, returns the
     /// region requirements to propagate to our creator, if any.
@@ -497,7 +476,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     fn compute_region_values(&self, _mir: &Mir<'tcx>) -> RegionValues {
         debug!("compute_region_values()");
         debug!("compute_region_values: constraints={:#?}", {
-            let mut constraints: Vec<_> = self.constraints.iter().collect();
+            let mut constraints: Vec<_> = self.constraints.iner().iter().collect();
             constraints.sort();
             constraints
         });
@@ -509,7 +488,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         let dependency_map = self.dependency_map.as_ref().unwrap();
 
         // Constraints that may need to be repropagated (initially all):
-        let mut dirty_list: Vec<_> = self.constraints.indices().collect();
+        let mut dirty_list: Vec<_> = self.constraints.iner().indices().collect();
 
         // Set to 0 for each constraint that is on the dirty list:
         let mut clean_bit_vec = BitVector::new(dirty_list.len());
@@ -518,7 +497,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         while let Some(constraint_idx) = dirty_list.pop() {
             clean_bit_vec.insert(constraint_idx.index());
 
-            let constraint = &self.constraints[constraint_idx];
+            let constraint = &self.constraints.iner()[constraint_idx];
             debug!("propagate_constraints: constraint={:?}", constraint);
 
             if inferred_values.add_region(constraint.sup, constraint.sub) {
@@ -530,7 +509,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
                     if clean_bit_vec.remove(dep_idx.index()) {
                         dirty_list.push(dep_idx);
                     }
-                    opt_dep_idx = self.constraints[dep_idx].next;
+                    opt_dep_idx = self.constraints.iner()[dep_idx].next;
                 }
             }
 
@@ -547,7 +526,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     fn build_dependency_map(&mut self) -> IndexVec<RegionVid, Option<ConstraintIndex>> {
         let mut map = IndexVec::from_elem(None, &self.definitions);
 
-        for (idx, constraint) in self.constraints.iter_enumerated_mut().rev() {
+        for (idx, constraint) in self.constraints.iner_mut().iter_enumerated_mut().rev() {
             let mut head = &mut map[constraint.sub];
             debug_assert!(constraint.next.is_none());
             constraint.next = *head;
@@ -995,7 +974,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             );
 
             let blame_index = self.blame_constraint(longer_fr, shorter_fr);
-            let blame_span = self.constraints[blame_index].span;
+            let blame_span = self.constraints.iner()[blame_index].span;
 
             if let Some(propagated_outlives_requirements) = propagated_outlives_requirements {
                 // Shrink `fr` until we find a non-local region (if we do).
@@ -1086,7 +1065,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // - `fr1: X` transitively
         // - and `Y` is live at `elem`
         let index = self.blame_constraint(fr1, elem);
-        let region_sub = self.constraints[index].sub;
+        let region_sub = self.constraints.iner()[index].sub;
 
         // then return why `Y` was live at `elem`
         self.liveness_constraints.cause(region_sub, elem)
@@ -1107,6 +1086,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // of dependencies, which doesn't account for the locations of
         // contraints at all. But it will do for now.
         let relevant_constraint = self.constraints
+            .iner()
             .iter_enumerated()
             .filter_map(|(i, constraint)| {
                 if !self.liveness_constraints.contains(constraint.sub, elem) {
@@ -1142,7 +1122,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
         while changed {
             changed = false;
-            for constraint in &self.constraints {
+            for constraint in self.constraints.iner() {
                 if let Some(n) = result_set[constraint.sup] {
                     let m = n + 1;
                     if result_set[constraint.sub]
diff --git a/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs b/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs
index 900899b9cde..263dd334e78 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/constraint_conversion.rs
@@ -13,6 +13,7 @@ use borrow_check::nll::facts::AllFacts;
 use borrow_check::nll::region_infer::{OutlivesConstraint, RegionTest, TypeTest};
 use borrow_check::nll::type_check::Locations;
 use borrow_check::nll::universal_regions::UniversalRegions;
+use borrow_check::nll::constraint_set::ConstraintSet;
 use rustc::infer::canonical::QueryRegionConstraint;
 use rustc::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
 use rustc::infer::region_constraints::{GenericKind, VerifyBound};
@@ -31,7 +32,7 @@ crate struct ConstraintConversion<'a, 'gcx: 'tcx, 'tcx: 'a> {
     implicit_region_bound: Option<ty::Region<'tcx>>,
     param_env: ty::ParamEnv<'tcx>,
     locations: Locations,
-    outlives_constraints: &'a mut Vec<OutlivesConstraint>,
+    outlives_constraints: &'a mut ConstraintSet,
     type_tests: &'a mut Vec<TypeTest<'tcx>>,
     all_facts: &'a mut Option<AllFacts>,
 }
@@ -46,7 +47,7 @@ impl<'a, 'gcx, 'tcx> ConstraintConversion<'a, 'gcx, 'tcx> {
         implicit_region_bound: Option<ty::Region<'tcx>>,
         param_env: ty::ParamEnv<'tcx>,
         locations: Locations,
-        outlives_constraints: &'a mut Vec<OutlivesConstraint>,
+        outlives_constraints: &'a mut ConstraintSet,
         type_tests: &'a mut Vec<TypeTest<'tcx>>,
         all_facts: &'a mut Option<AllFacts>,
     ) -> Self {
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 2da2b10edb8..ee607ccae89 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -12,9 +12,10 @@
 #![allow(unreachable_code)]
 
 use borrow_check::location::LocationTable;
+use borrow_check::nll::constraint_set::ConstraintSet;
 use borrow_check::nll::facts::AllFacts;
 use borrow_check::nll::region_infer::Cause;
-use borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, OutlivesConstraint, TypeTest};
+use borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest};
 use borrow_check::nll::universal_regions::UniversalRegions;
 use dataflow::move_paths::MoveData;
 use dataflow::FlowAtLocation;
@@ -621,7 +622,7 @@ crate struct MirTypeckRegionConstraints<'tcx> {
     /// hence it must report on their liveness constraints.
     crate liveness_set: Vec<(ty::Region<'tcx>, Location, Cause)>,
 
-    crate outlives_constraints: Vec<OutlivesConstraint>,
+    crate outlives_constraints: ConstraintSet,
 
     crate type_tests: Vec<TypeTest<'tcx>>,
 }