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 | 60 |
1 files changed, 33 insertions, 27 deletions
diff --git a/crates/hir-ty/src/next_solver/fulfill.rs b/crates/hir-ty/src/next_solver/fulfill.rs index 6739795a00..33dd33cb1d 100644 --- a/crates/hir-ty/src/next_solver/fulfill.rs +++ b/crates/hir-ty/src/next_solver/fulfill.rs @@ -9,17 +9,20 @@ use rustc_next_trait_solver::{ }; use rustc_type_ir::{ Interner, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, - inherent::{IntoKind, Span as _}, + inherent::IntoKind, solve::{Certainty, NoSolution}, }; -use crate::next_solver::{ - DbInterner, SolverContext, SolverDefId, Span, Ty, TyKind, TypingMode, - infer::{ - InferCtxt, - traits::{PredicateObligation, PredicateObligations}, +use crate::{ + Span, + next_solver::{ + DbInterner, SolverContext, SolverDefId, Ty, TyKind, TypingMode, + infer::{ + InferCtxt, + traits::{PredicateObligation, PredicateObligations}, + }, + inspect::ProofTreeVisitor, }, - inspect::ProofTreeVisitor, }; type PendingObligations<'db> = @@ -36,7 +39,7 @@ type PendingObligations<'db> = /// /// It is also likely that we want to use slightly different datastructures /// here as this will have to deal with far more root goals than `evaluate_all`. -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct FulfillmentCtxt<'db> { obligations: ObligationStorage<'db>, @@ -44,7 +47,6 @@ 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, try_evaluate_obligations_scratch: PendingObligations<'db>, } @@ -98,7 +100,7 @@ impl<'db> ObligationStorage<'db> { let goal = o.as_goal(); let result = <&SolverContext<'db>>::from(infcx).evaluate_root_goal( goal, - Span::dummy(), + o.cause.span(), stalled_on.take(), ); matches!(result, Ok(GoalEvaluation { has_changed: HasChanged::Yes, .. })) @@ -120,24 +122,22 @@ 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 `try_evaluate_obligations()`. - // assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots()); + 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 `try_evaluate_obligations()`. - // assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots()); + assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots()); obligations.into_iter().for_each(|obligation| self.obligations.register(obligation, None)); } @@ -157,11 +157,7 @@ impl<'db> FulfillmentCtxt<'db> { &mut self, infcx: &InferCtxt<'db>, ) -> Vec<NextSolverError<'db>> { - // FIXME(next-solver): We should bring this assertion back. Currently it panics because - // there are places which use `InferenceTable` and open a snapshot and register obligations - // and select. They should use a different `ObligationCtxt` instead. Then we'll be also able - // to not put the obligations queue in `InferenceTable`'s snapshots. - // assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots()); + assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots()); self.try_evaluate_obligations_scratch.clear(); let mut errors = Vec::new(); loop { @@ -176,7 +172,9 @@ impl<'db> FulfillmentCtxt<'db> { let goal = obligation.as_goal(); let delegate = <&SolverContext<'db>>::from(infcx); - if let Some(certainty) = delegate.compute_goal_fast_path(goal, Span::dummy()) { + if let Some(certainty) = + delegate.compute_goal_fast_path(goal, obligation.cause.span()) + { match certainty { Certainty::Yes => {} Certainty::Maybe { .. } => { @@ -186,9 +184,11 @@ impl<'db> FulfillmentCtxt<'db> { continue; } - let result = delegate.evaluate_root_goal(goal, Span::dummy(), stalled_on); + let result = delegate.evaluate_root_goal(goal, obligation.cause.span(), stalled_on); infcx.inspect_evaluated_obligation(&obligation, &result, || { - Some(delegate.evaluate_root_goal_for_proof_tree(goal, Span::dummy()).1) + Some( + delegate.evaluate_root_goal_for_proof_tree(goal, obligation.cause.span()).1, + ) }); let GoalEvaluation { goal: _, certainty, has_changed, stalled_on } = match result { Ok(result) => result, @@ -243,7 +243,7 @@ impl<'db> FulfillmentCtxt<'db> { &mut self, infcx: &InferCtxt<'db>, ) -> PredicateObligations<'db> { - let stalled_coroutines = match infcx.typing_mode() { + let stalled_coroutines = match infcx.typing_mode_raw().assert_not_erased() { TypingMode::Analysis { defining_opaque_types_and_generators } => { defining_opaque_types_and_generators } @@ -266,6 +266,7 @@ impl<'db> FulfillmentCtxt<'db> { obl.as_goal(), &mut StalledOnCoroutines { stalled_coroutines, + span: obl.cause.span(), cache: Default::default(), }, ) @@ -287,12 +288,17 @@ impl<'db> FulfillmentCtxt<'db> { /// so we want to keep this visitor *precise* too. pub struct StalledOnCoroutines<'a, 'db> { pub stalled_coroutines: &'a [SolverDefId], + pub span: Span, pub cache: FxHashSet<Ty<'db>>, } impl<'db> ProofTreeVisitor<'db> for StalledOnCoroutines<'_, 'db> { type Result = ControlFlow<()>; + fn span(&self) -> Span { + self.span + } + fn visit_goal(&mut self, inspect_goal: &super::inspect::InspectGoal<'_, 'db>) -> Self::Result { inspect_goal.goal().predicate.visit_with(self)?; @@ -324,7 +330,7 @@ impl<'db> TypeVisitor<DbInterner<'db>> for StalledOnCoroutines<'_, 'db> { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum NextSolverError<'db> { TrueError(PredicateObligation<'db>), Ambiguity(PredicateObligation<'db>), |