about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEh2406 <YeomanYaacov@gmail.com>2018-06-27 14:32:00 -0400
committerEh2406 <YeomanYaacov@gmail.com>2018-06-28 10:15:37 -0400
commit8a356011aeae6895e4d89dd95b37e8c7706ec5a3 (patch)
tree643536b8dccd9a05a0cc6c20a0161192da58beca
parent9f79d2f86af73da483f4fe8e2422c15c79221d32 (diff)
Remove duplicates
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/mod.rs37
1 files changed, 32 insertions, 5 deletions
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 2e1f7fc9e70..f6d5de63f17 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs
@@ -24,6 +24,7 @@ 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,6 +67,7 @@ pub struct RegionInferenceContext<'tcx> {
 
     /// The constraints we have accumulated and used during solving.
     constraints: IndexVec<ConstraintIndex, OutlivesConstraint>,
+    seen_constraints: FxHashSet<(RegionVid, RegionVid)>,
 
     /// Type constraints that we check after solving.
     type_tests: Vec<TypeTest<'tcx>>,
@@ -143,6 +145,12 @@ pub struct OutlivesConstraint {
     pub span: Span,
 }
 
+impl OutlivesConstraint {
+    fn dedup_key(&self) -> (RegionVid, RegionVid) {
+        (self.sup, self.sub)
+    }
+}
+
 newtype_index!(ConstraintIndex { DEBUG_FORMAT = "ConstraintIndex({})" });
 
 /// A "type test" corresponds to an outlives constraint between a type
@@ -266,11 +274,16 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             liveness_constraints: RegionValues::new(elements, num_region_variables),
             inferred_values: None,
             dependency_map: None,
-            constraints: IndexVec::from_raw(outlives_constraints),
+            constraints: Default::default(),
+            seen_constraints: Default::default(),
             type_tests,
             universal_regions,
         };
 
+        for c in outlives_constraints {
+            result.add_outlives_iner(c);
+        }
+
         result.init_universal_regions();
 
         result
@@ -392,15 +405,29 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         sub: RegionVid,
         point: Location,
     ) {
-        debug!("add_outlives({:?}: {:?} @ {:?}", sup, sub, point);
-        assert!(self.inferred_values.is_none(), "values already inferred");
-        self.constraints.push(OutlivesConstraint {
+        self.add_outlives_iner(OutlivesConstraint {
             span,
             sup,
             sub,
             point,
             next: None,
-        });
+        })
+    }
+
+    /// 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