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 rustc_span::DUMMY_SP;
|
||||||
|
|
||||||
|
use crate::solve::search_graph::overflow::OverflowHandler;
|
||||||
use crate::traits::ObligationCause;
|
use crate::traits::ObligationCause;
|
||||||
|
|
||||||
mod assembly;
|
mod assembly;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
mod cache;
|
mod cache;
|
||||||
mod overflow;
|
pub(crate) mod overflow;
|
||||||
|
|
||||||
use self::cache::ProvisionalEntry;
|
use self::cache::ProvisionalEntry;
|
||||||
use super::{CanonicalGoal, Certainty, MaybeCause, QueryResult};
|
use super::{CanonicalGoal, Certainty, MaybeCause, QueryResult};
|
||||||
@ -18,7 +18,7 @@ struct StackElem<'tcx> {
|
|||||||
has_been_used: bool,
|
has_been_used: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) struct SearchGraph<'tcx> {
|
pub(crate) struct SearchGraph<'tcx> {
|
||||||
/// The stack of goals currently being computed.
|
/// The stack of goals currently being computed.
|
||||||
///
|
///
|
||||||
/// An element is *deeper* in the stack if its index is *lower*.
|
/// 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> {
|
impl<'tcx> SearchGraph<'tcx> {
|
||||||
pub fn deal_with_overflow(
|
pub fn deal_with_overflow(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -60,26 +96,3 @@ impl<'tcx> SearchGraph<'tcx> {
|
|||||||
response_no_constraints(tcx, goal, Certainty::Maybe(MaybeCause::Overflow))
|
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