Implement repeat_while_none for both SearchGraph and EvalCtxt
This commit is contained in:
parent
873c83ba56
commit
826bee7085
@ -31,6 +31,7 @@ use rustc_middle::ty::{
|
||||
};
|
||||
use rustc_span::DUMMY_SP;
|
||||
|
||||
use crate::solve::search_graph::overflow::OverflowHandler;
|
||||
use crate::traits::ObligationCause;
|
||||
|
||||
mod assembly;
|
||||
|
@ -1,5 +1,5 @@
|
||||
mod cache;
|
||||
mod overflow;
|
||||
pub(crate) mod overflow;
|
||||
|
||||
use self::cache::ProvisionalEntry;
|
||||
use super::{CanonicalGoal, Certainty, MaybeCause, QueryResult};
|
||||
@ -18,7 +18,7 @@ struct StackElem<'tcx> {
|
||||
has_been_used: bool,
|
||||
}
|
||||
|
||||
pub(super) struct SearchGraph<'tcx> {
|
||||
pub(crate) struct SearchGraph<'tcx> {
|
||||
/// The stack of goals currently being computed.
|
||||
///
|
||||
/// An element is *deeper* in the stack if its index is *lower*.
|
||||
|
@ -50,6 +50,42 @@ impl OverflowData {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait OverflowHandler<'tcx> {
|
||||
fn search_graph(&mut self) -> &mut SearchGraph<'tcx>;
|
||||
|
||||
fn repeat_while_none<T>(
|
||||
&mut self,
|
||||
on_overflow: impl FnOnce(&mut Self) -> T,
|
||||
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 depth = self.search_graph().stack.len();
|
||||
while !self.search_graph().overflow_data.has_overflow(depth) {
|
||||
if let Some(result) = loop_body(self) {
|
||||
self.search_graph().overflow_data.additional_depth = start_depth;
|
||||
return result;
|
||||
}
|
||||
|
||||
self.search_graph().overflow_data.additional_depth += 1;
|
||||
}
|
||||
self.search_graph().overflow_data.additional_depth = start_depth;
|
||||
self.search_graph().overflow_data.deal_with_overflow();
|
||||
Ok(on_overflow(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> OverflowHandler<'tcx> for EvalCtxt<'_, 'tcx> {
|
||||
fn search_graph(&mut self) -> &mut SearchGraph<'tcx> {
|
||||
&mut self.search_graph
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> OverflowHandler<'tcx> for SearchGraph<'tcx> {
|
||||
fn search_graph(&mut self) -> &mut SearchGraph<'tcx> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> SearchGraph<'tcx> {
|
||||
pub fn deal_with_overflow(
|
||||
&mut self,
|
||||
@ -60,26 +96,3 @@ impl<'tcx> SearchGraph<'tcx> {
|
||||
response_no_constraints(tcx, goal, Certainty::Maybe(MaybeCause::Overflow))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
/// A `while`-loop which tracks overflow.
|
||||
pub fn repeat_while_none<T>(
|
||||
&mut self,
|
||||
mut overflow_body: impl FnMut(&mut Self) -> T,
|
||||
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 depth = self.search_graph.stack.len();
|
||||
while !self.search_graph.overflow_data.has_overflow(depth) {
|
||||
if let Some(result) = loop_body(self) {
|
||||
self.search_graph.overflow_data.additional_depth = start_depth;
|
||||
return result;
|
||||
}
|
||||
|
||||
self.search_graph.overflow_data.additional_depth += 1;
|
||||
}
|
||||
self.search_graph.overflow_data.additional_depth = start_depth;
|
||||
self.search_graph.overflow_data.deal_with_overflow();
|
||||
Ok(overflow_body(self))
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user