diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2018-10-16 05:42:18 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2019-01-02 17:35:05 -0500 |
| commit | 4170829e536f5b284c4c66f291acfb0da23bb526 (patch) | |
| tree | d5817f08de8e37a9fea6a26a1cc8d76683947d86 | |
| parent | 4b5f274f90d3eb925bad9a1bfa6fe58209f6a6c8 (diff) | |
| download | rust-4170829e536f5b284c4c66f291acfb0da23bb526.tar.gz rust-4170829e536f5b284c4c66f291acfb0da23bb526.zip | |
introduce ability to detect region constraints from snapshot
| -rw-r--r-- | src/librustc/infer/mod.rs | 9 | ||||
| -rw-r--r-- | src/librustc/infer/region_constraints/mod.rs | 9 | ||||
| -rw-r--r-- | src/librustc/traits/select.rs | 30 |
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), } |
