1
Fork 0

Make Ok value of repeat_while_none more general

This commit is contained in:
Santiago Pastorino 2023-01-31 13:42:00 -03:00
parent 0b439b119b
commit 44a2388828
No known key found for this signature in database
GPG key ID: 8131A24E0C79EFAF
2 changed files with 31 additions and 27 deletions

View file

@ -485,35 +485,38 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
mut goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>, mut goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
) -> Result<Certainty, NoSolution> { ) -> Result<Certainty, NoSolution> {
let mut new_goals = Vec::new(); let mut new_goals = Vec::new();
self.repeat_while_none(|this| { self.repeat_while_none(
let mut has_changed = Err(Certainty::Yes); |_| Certainty::Maybe(MaybeCause::Overflow),
for goal in goals.drain(..) { |this| {
let (changed, certainty) = match this.evaluate_goal(goal) { let mut has_changed = Err(Certainty::Yes);
Ok(result) => result, for goal in goals.drain(..) {
Err(NoSolution) => return Some(Err(NoSolution)), let (changed, certainty) = match this.evaluate_goal(goal) {
}; Ok(result) => result,
Err(NoSolution) => return Some(Err(NoSolution)),
};
if changed { if changed {
has_changed = Ok(()); has_changed = Ok(());
} }
match certainty { match certainty {
Certainty::Yes => {} Certainty::Yes => {}
Certainty::Maybe(_) => { Certainty::Maybe(_) => {
new_goals.push(goal); new_goals.push(goal);
has_changed = has_changed.map_err(|c| c.unify_and(certainty)); has_changed = has_changed.map_err(|c| c.unify_and(certainty));
}
} }
} }
}
match has_changed { match has_changed {
Ok(()) => { Ok(()) => {
mem::swap(&mut new_goals, &mut goals); mem::swap(&mut new_goals, &mut goals);
None None
}
Err(certainty) => Some(Ok(certainty)),
} }
Err(certainty) => Some(Ok(certainty)), },
} )
})
} }
// Recursively evaluates a list of goals to completion, making a query response. // Recursively evaluates a list of goals to completion, making a query response.

View file

@ -63,10 +63,11 @@ impl<'tcx> SearchGraph<'tcx> {
impl<'tcx> EvalCtxt<'_, 'tcx> { impl<'tcx> EvalCtxt<'_, 'tcx> {
/// A `while`-loop which tracks overflow. /// A `while`-loop which tracks overflow.
pub fn repeat_while_none( pub fn repeat_while_none<T>(
&mut self, &mut self,
mut loop_body: impl FnMut(&mut Self) -> Option<Result<Certainty, NoSolution>>, mut overflow_body: impl FnMut(&mut Self) -> T,
) -> Result<Certainty, NoSolution> { mut loop_body: impl FnMut(&mut Self) -> Option<Result<T, NoSolution>>,
) -> Result<T, NoSolution> {
let start_depth = self.search_graph.overflow_data.additional_depth; let start_depth = self.search_graph.overflow_data.additional_depth;
let depth = self.search_graph.stack.len(); let depth = self.search_graph.stack.len();
while !self.search_graph.overflow_data.has_overflow(depth) { while !self.search_graph.overflow_data.has_overflow(depth) {
@ -79,6 +80,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
} }
self.search_graph.overflow_data.additional_depth = start_depth; self.search_graph.overflow_data.additional_depth = start_depth;
self.search_graph.overflow_data.deal_with_overflow(); self.search_graph.overflow_data.deal_with_overflow();
Ok(Certainty::Maybe(MaybeCause::Overflow)) Ok(overflow_body(self))
} }
} }