Implement repeat_while_none for both SearchGraph and EvalCtxt

This commit is contained in:
Santiago Pastorino 2023-02-06 16:28:27 -03:00
parent 873c83ba56
commit 826bee7085
No known key found for this signature in database
GPG Key ID: 8131A24E0C79EFAF
3 changed files with 39 additions and 25 deletions

View File

@ -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;

View File

@ -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*.

View File

@ -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))
}
}