Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/next_solver/fulfill.rs')
| -rw-r--r-- | crates/hir-ty/src/next_solver/fulfill.rs | 52 |
1 files changed, 22 insertions, 30 deletions
diff --git a/crates/hir-ty/src/next_solver/fulfill.rs b/crates/hir-ty/src/next_solver/fulfill.rs index 34dff37972..40cc84e0c0 100644 --- a/crates/hir-ty/src/next_solver/fulfill.rs +++ b/crates/hir-ty/src/next_solver/fulfill.rs @@ -2,7 +2,7 @@ mod errors; -use std::{marker::PhantomData, mem, ops::ControlFlow, vec::ExtractIf}; +use std::ops::ControlFlow; use rustc_hash::FxHashSet; use rustc_next_trait_solver::{ @@ -46,6 +46,7 @@ pub struct FulfillmentCtxt<'db> { /// outside of this snapshot leads to subtle bugs if the snapshot /// gets rolled back. Because of this we explicitly check that we only /// use the context in exactly this snapshot. + #[expect(unused)] usable_in_snapshot: usize, } @@ -54,7 +55,7 @@ struct ObligationStorage<'db> { /// Obligations which resulted in an overflow in fulfillment itself. /// /// We cannot eagerly return these as error so we instead store them here - /// to avoid recomputing them each time `select_where_possible` is called. + /// to avoid recomputing them each time `try_evaluate_obligations` is called. /// This also allows us to return the correct `FulfillmentError` for them. overflowed: Vec<PredicateObligation<'db>>, pending: PendingObligations<'db>, @@ -69,10 +70,6 @@ impl<'db> ObligationStorage<'db> { self.pending.push((obligation, stalled_on)); } - fn has_pending_obligations(&self) -> bool { - !self.pending.is_empty() || !self.overflowed.is_empty() - } - fn clone_pending(&self) -> PredicateObligations<'db> { let mut obligations: PredicateObligations<'db> = self.pending.iter().map(|(o, _)| o.clone()).collect(); @@ -80,14 +77,12 @@ impl<'db> ObligationStorage<'db> { obligations } - fn drain_pending( - &mut self, - cond: impl Fn(&PredicateObligation<'db>) -> bool, - ) -> PendingObligations<'db> { - let (not_stalled, pending) = - mem::take(&mut self.pending).into_iter().partition(|(o, _)| cond(o)); - self.pending = pending; - not_stalled + fn drain_pending<'this, 'cond>( + &'this mut self, + cond: impl 'cond + Fn(&PredicateObligation<'db>) -> bool, + ) -> impl Iterator<Item = (PredicateObligation<'db>, Option<GoalStalledOn<DbInterner<'db>>>)> + { + self.pending.extract_if(.., move |(o, _)| cond(o)) } fn on_fulfillment_overflow(&mut self, infcx: &InferCtxt<'db>) { @@ -95,7 +90,7 @@ impl<'db> ObligationStorage<'db> { // IMPORTANT: we must not use solve any inference variables in the obligations // as this is all happening inside of a probe. We use a probe to make sure // we get all obligations involved in the overflow. We pretty much check: if - // we were to do another step of `select_where_possible`, which goals would + // we were to do another step of `try_evaluate_obligations`, which goals would // change. // FIXME: <https://github.com/Gankra/thin-vec/pull/66> is merged, this can be removed. self.overflowed.extend( @@ -125,30 +120,30 @@ impl<'db> FulfillmentCtxt<'db> { } impl<'db> FulfillmentCtxt<'db> { - #[tracing::instrument(level = "trace", skip(self, infcx))] + #[tracing::instrument(level = "trace", skip(self, _infcx))] pub(crate) fn register_predicate_obligation( &mut self, - infcx: &InferCtxt<'db>, + _infcx: &InferCtxt<'db>, obligation: PredicateObligation<'db>, ) { - // FIXME: See the comment in `select_where_possible()`. + // FIXME: See the comment in `try_evaluate_obligations()`. // assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots()); self.obligations.register(obligation, None); } pub(crate) fn register_predicate_obligations( &mut self, - infcx: &InferCtxt<'db>, + _infcx: &InferCtxt<'db>, obligations: impl IntoIterator<Item = PredicateObligation<'db>>, ) { - // FIXME: See the comment in `select_where_possible()`. + // FIXME: See the comment in `try_evaluate_obligations()`. // assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots()); obligations.into_iter().for_each(|obligation| self.obligations.register(obligation, None)); } pub(crate) fn collect_remaining_errors( &mut self, - infcx: &InferCtxt<'db>, + _infcx: &InferCtxt<'db>, ) -> Vec<NextSolverError<'db>> { self.obligations .pending @@ -158,7 +153,7 @@ impl<'db> FulfillmentCtxt<'db> { .collect() } - pub(crate) fn select_where_possible( + pub(crate) fn try_evaluate_obligations( &mut self, infcx: &InferCtxt<'db>, ) -> Vec<NextSolverError<'db>> { @@ -168,9 +163,11 @@ impl<'db> FulfillmentCtxt<'db> { // to not put the obligations queue in `InferenceTable`'s snapshots. // assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots()); let mut errors = Vec::new(); + let mut obligations = Vec::new(); loop { let mut any_changed = false; - for (mut obligation, stalled_on) in self.obligations.drain_pending(|_| true) { + obligations.extend(self.obligations.drain_pending(|_| true)); + for (mut obligation, stalled_on) in obligations.drain(..) { if obligation.recursion_depth >= infcx.interner.recursion_limit() { self.obligations.on_fulfillment_overflow(infcx); // Only return true errors that we have accumulated while processing. @@ -223,11 +220,11 @@ impl<'db> FulfillmentCtxt<'db> { errors } - pub(crate) fn select_all_or_error( + pub(crate) fn evaluate_obligations_error_on_ambiguity( &mut self, infcx: &InferCtxt<'db>, ) -> Vec<NextSolverError<'db>> { - let errors = self.select_where_possible(infcx); + let errors = self.try_evaluate_obligations(infcx); if !errors.is_empty() { return errors; } @@ -235,10 +232,6 @@ impl<'db> FulfillmentCtxt<'db> { self.collect_remaining_errors(infcx) } - fn has_pending_obligations(&self) -> bool { - self.obligations.has_pending_obligations() - } - pub(crate) fn pending_obligations(&self) -> PredicateObligations<'db> { self.obligations.clone_pending() } @@ -276,7 +269,6 @@ impl<'db> FulfillmentCtxt<'db> { .is_break() }) }) - .into_iter() .map(|(o, _)| o) .collect() } |