1
Fork 0

Check for overflow in evaluate_canonical_goal

This commit is contained in:
Santiago Pastorino 2023-02-06 17:11:43 -03:00
parent 826bee7085
commit c8dae10f14
No known key found for this signature in database
GPG key ID: 8131A24E0C79EFAF
3 changed files with 46 additions and 24 deletions

View file

@ -211,27 +211,16 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
search_graph: &'a mut search_graph::SearchGraph<'tcx>,
canonical_goal: CanonicalGoal<'tcx>,
) -> QueryResult<'tcx> {
match search_graph.try_push_stack(tcx, canonical_goal) {
Ok(()) => {}
// Our goal is already on the stack, eager return.
Err(response) => return response,
}
// We may have to repeatedly recompute the goal in case of coinductive cycles,
// check out the `cache` module for more information.
// Deal with overflow, caching, and coinduction.
//
// FIXME: Similar to `evaluate_all`, this has to check for overflow.
loop {
// The actual solver logic happens in `ecx.compute_goal`.
search_graph.with_new_goal(tcx, canonical_goal, |search_graph| {
let (ref infcx, goal, var_values) =
tcx.infer_ctxt().build_with_canonical(DUMMY_SP, &canonical_goal);
let mut ecx =
EvalCtxt { infcx, var_values, search_graph, in_projection_eq_hack: false };
let result = ecx.compute_goal(goal);
if search_graph.try_finalize_goal(tcx, canonical_goal, result) {
return result;
}
}
ecx.compute_goal(goal)
})
}
fn make_canonical_response(&self, certainty: Certainty) -> QueryResult<'tcx> {
@ -487,7 +476,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
) -> Result<Certainty, NoSolution> {
let mut new_goals = Vec::new();
self.repeat_while_none(
|_| Certainty::Maybe(MaybeCause::Overflow),
|_| Ok(Certainty::Maybe(MaybeCause::Overflow)),
|this| {
let mut has_changed = Err(Certainty::Yes);
for goal in goals.drain(..) {