Make Ok value of repeat_while_none more general
This commit is contained in:
parent
0b439b119b
commit
44a2388828
2 changed files with 31 additions and 27 deletions
|
@ -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.
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue