about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-10-16 05:42:18 -0400
committerNiko Matsakis <niko@alum.mit.edu>2019-01-02 17:35:05 -0500
commit4170829e536f5b284c4c66f291acfb0da23bb526 (patch)
treed5817f08de8e37a9fea6a26a1cc8d76683947d86
parent4b5f274f90d3eb925bad9a1bfa6fe58209f6a6c8 (diff)
downloadrust-4170829e536f5b284c4c66f291acfb0da23bb526.tar.gz
rust-4170829e536f5b284c4c66f291acfb0da23bb526.zip
introduce ability to detect region constraints from snapshot
-rw-r--r--src/librustc/infer/mod.rs9
-rw-r--r--src/librustc/infer/region_constraints/mod.rs9
-rw-r--r--src/librustc/traits/select.rs30
3 files changed, 40 insertions, 8 deletions
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 2eb9f1d6784..9a5e707b57d 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -868,6 +868,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         r
     }
 
+    pub fn region_constraints_added_in_snapshot(
+        &self,
+        snapshot: &CombinedSnapshot<'a, 'tcx>,
+    ) -> bool {
+        self.borrow_region_constraints().region_constraints_added_in_snapshot(
+            &snapshot.region_constraints_snapshot,
+        )
+    }
+
     pub fn add_given(&self, sub: ty::Region<'tcx>, sup: ty::RegionVid) {
         self.borrow_region_constraints().add_given(sub, sup);
     }
diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs
index 66ebbe111db..89086e66dff 100644
--- a/src/librustc/infer/region_constraints/mod.rs
+++ b/src/librustc/infer/region_constraints/mod.rs
@@ -854,6 +854,15 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
         debug!("tainted: result={:?}", taint_set);
         return taint_set.into_set();
     }
+
+    pub fn region_constraints_added_in_snapshot(&self, mark: &RegionSnapshot) -> bool {
+        self.undo_log[mark.length..]
+            .iter()
+            .any(|&elt| match elt {
+                AddConstraint(_) => true,
+                _ => false,
+            })
+    }
 }
 
 impl fmt::Debug for RegionSnapshot {
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 6b4c3469acd..6ba3e54eaca 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -629,8 +629,22 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         &mut self,
         obligation: &PredicateObligation<'tcx>,
     ) -> Result<EvaluationResult, OverflowError> {
-        self.infcx.probe(|_| {
-            self.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation)
+        self.evaluation_probe(|this| {
+            this.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation)
+        })
+    }
+
+    fn evaluation_probe(
+        &mut self,
+        op: impl FnOnce(&mut Self) -> Result<EvaluationResult, OverflowError>,
+    ) -> Result<EvaluationResult, OverflowError> {
+        self.infcx.probe(|snapshot| -> Result<EvaluationResult, OverflowError> {
+            let result = op(self)?;
+            if !self.infcx.region_constraints_added_in_snapshot(snapshot) {
+                Ok(result)
+            } else {
+                Ok(result.max(EvaluatedToOkModuloRegions))
+            }
         })
     }
 
@@ -988,10 +1002,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
             "evaluate_candidate: depth={} candidate={:?}",
             stack.obligation.recursion_depth, candidate
         );
-        let result = self.infcx.probe(|_| {
+        let result = self.evaluation_probe(|this| {
             let candidate = (*candidate).clone();
-            match self.confirm_candidate(stack.obligation, candidate) {
-                Ok(selection) => self.evaluate_predicates_recursively(
+            match this.confirm_candidate(stack.obligation, candidate) {
+                Ok(selection) => this.evaluate_predicates_recursively(
                     stack.list(),
                     selection.nested_obligations().iter(),
                 ),
@@ -1775,10 +1789,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         stack: &TraitObligationStack<'o, 'tcx>,
         where_clause_trait_ref: ty::PolyTraitRef<'tcx>,
     ) -> Result<EvaluationResult, OverflowError> {
-        self.infcx.probe(|_| {
-            match self.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) {
+        self.evaluation_probe(|this| {
+            match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) {
                 Ok(obligations) => {
-                    self.evaluate_predicates_recursively(stack.list(), obligations.iter())
+                    this.evaluate_predicates_recursively(stack.list(), obligations.iter())
                 }
                 Err(()) => Ok(EvaluatedToErr),
             }