Skip to content

Commit

Permalink
introduce ability to detect region constraints from snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed Jan 2, 2019
1 parent 4b5f274 commit 4170829
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 8 deletions.
9 changes: 9 additions & 0 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
9 changes: 9 additions & 0 deletions src/librustc/infer/region_constraints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
30 changes: 22 additions & 8 deletions src/librustc/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
})
}

Expand Down Expand Up @@ -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(),
),
Expand Down Expand Up @@ -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),
}
Expand Down

0 comments on commit 4170829

Please sign in to comment.