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.rs60
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>),