Skip to content

Commit ea6b0b0

Browse files
Unstall obligations by looking for coroutines in old solver
1 parent a2e7e6f commit ea6b0b0

File tree

3 files changed

+54
-54
lines changed

3 files changed

+54
-54
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -631,50 +631,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
631631
// trigger query cycle ICEs, as doing so requires MIR.
632632
self.select_obligations_where_possible(|_| {});
633633

634-
let coroutines = std::mem::take(&mut *self.deferred_coroutine_interiors.borrow_mut());
635-
debug!(?coroutines);
636-
637-
let mut obligations = vec![];
638-
639-
if !self.next_trait_solver() {
640-
for &(coroutine_def_id, interior) in coroutines.iter() {
641-
debug!(?coroutine_def_id);
642-
643-
// Create the `CoroutineWitness` type that we will unify with `interior`.
644-
let args = ty::GenericArgs::identity_for_item(
645-
self.tcx,
646-
self.tcx.typeck_root_def_id(coroutine_def_id.to_def_id()),
647-
);
648-
let witness =
649-
Ty::new_coroutine_witness(self.tcx, coroutine_def_id.to_def_id(), args);
650-
651-
// Unify `interior` with `witness` and collect all the resulting obligations.
652-
let span = self.tcx.hir_body_owned_by(coroutine_def_id).value.span;
653-
let ty::Infer(ty::InferTy::TyVar(_)) = interior.kind() else {
654-
span_bug!(span, "coroutine interior witness not infer: {:?}", interior.kind())
655-
};
656-
let ok = self
657-
.at(&self.misc(span), self.param_env)
658-
// Will never define opaque types, as all we do is instantiate a type variable.
659-
.eq(DefineOpaqueTypes::Yes, interior, witness)
660-
.expect("Failed to unify coroutine interior type");
661-
662-
obligations.extend(ok.obligations);
663-
}
664-
}
634+
let ty::TypingMode::Analysis { defining_opaque_types_and_generators } = self.typing_mode()
635+
else {
636+
bug!();
637+
};
665638

666-
if !coroutines.is_empty() {
667-
obligations.extend(
639+
if defining_opaque_types_and_generators
640+
.iter()
641+
.any(|def_id| self.tcx.is_coroutine(def_id.to_def_id()))
642+
{
643+
self.typeck_results.borrow_mut().coroutine_stalled_predicates.extend(
668644
self.fulfillment_cx
669645
.borrow_mut()
670-
.drain_stalled_obligations_for_coroutines(&self.infcx),
646+
.drain_stalled_obligations_for_coroutines(&self.infcx)
647+
.into_iter()
648+
.map(|o| (o.predicate, o.cause)),
671649
);
672650
}
673-
674-
self.typeck_results
675-
.borrow_mut()
676-
.coroutine_stalled_predicates
677-
.extend(obligations.into_iter().map(|o| (o.predicate, o.cause)));
678651
}
679652

680653
#[instrument(skip(self), level = "debug")]

compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ where
255255
&mut self,
256256
infcx: &InferCtxt<'tcx>,
257257
) -> PredicateObligations<'tcx> {
258-
let stalled_generators = match infcx.typing_mode() {
258+
let stalled_coroutines = match infcx.typing_mode() {
259259
TypingMode::Analysis { defining_opaque_types_and_generators } => {
260260
defining_opaque_types_and_generators
261261
}
@@ -265,7 +265,7 @@ where
265265
| TypingMode::PostAnalysis => return Default::default(),
266266
};
267267

268-
if stalled_generators.is_empty() {
268+
if stalled_coroutines.is_empty() {
269269
return Default::default();
270270
}
271271

@@ -276,7 +276,7 @@ where
276276
.visit_proof_tree(
277277
obl.as_goal(),
278278
&mut StalledOnCoroutines {
279-
stalled_generators,
279+
stalled_coroutines,
280280
span: obl.cause.span,
281281
cache: Default::default(),
282282
},
@@ -298,10 +298,10 @@ where
298298
///
299299
/// This function can be also return false positives, which will lead to poor diagnostics
300300
/// so we want to keep this visitor *precise* too.
301-
struct StalledOnCoroutines<'tcx> {
302-
stalled_generators: &'tcx ty::List<LocalDefId>,
303-
span: Span,
304-
cache: DelayedSet<Ty<'tcx>>,
301+
pub struct StalledOnCoroutines<'tcx> {
302+
pub stalled_coroutines: &'tcx ty::List<LocalDefId>,
303+
pub span: Span,
304+
pub cache: DelayedSet<Ty<'tcx>>,
305305
}
306306

307307
impl<'tcx> inspect::ProofTreeVisitor<'tcx> for StalledOnCoroutines<'tcx> {
@@ -331,7 +331,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for StalledOnCoroutines<'tcx> {
331331
}
332332

333333
if let ty::CoroutineWitness(def_id, _) = *ty.kind()
334-
&& def_id.as_local().is_some_and(|def_id| self.stalled_generators.contains(&def_id))
334+
&& def_id.as_local().is_some_and(|def_id| self.stalled_coroutines.contains(&def_id))
335335
{
336336
ControlFlow::Break(())
337337
} else if ty.has_coroutines() {

compiler/rustc_trait_selection/src/traits/fulfill.rs

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::marker::PhantomData;
33
use rustc_data_structures::obligation_forest::{
44
Error, ForestObligation, ObligationForest, ObligationProcessor, Outcome, ProcessResult,
55
};
6+
use rustc_hir::def_id::LocalDefId;
67
use rustc_infer::infer::DefineOpaqueTypes;
78
use rustc_infer::traits::{
89
FromSolverError, PolyTraitObligation, PredicateObligations, ProjectionCacheKey, SelectionError,
@@ -11,7 +12,10 @@ use rustc_infer::traits::{
1112
use rustc_middle::bug;
1213
use rustc_middle::ty::abstract_const::NotConstEvaluatable;
1314
use rustc_middle::ty::error::{ExpectedFound, TypeError};
14-
use rustc_middle::ty::{self, Binder, Const, GenericArgsRef, TypeVisitableExt, TypingMode};
15+
use rustc_middle::ty::{
16+
self, Binder, Const, GenericArgsRef, TypeVisitable, TypeVisitableExt, TypingMode,
17+
};
18+
use rustc_span::DUMMY_SP;
1519
use thin_vec::ThinVec;
1620
use tracing::{debug, debug_span, instrument};
1721

@@ -24,6 +28,7 @@ use super::{
2428
};
2529
use crate::error_reporting::InferCtxtErrorExt;
2630
use crate::infer::{InferCtxt, TyOrConstInferVar};
31+
use crate::solve::StalledOnCoroutines;
2732
use crate::traits::normalize::normalize_with_depth_to;
2833
use crate::traits::project::{PolyProjectionObligation, ProjectionCacheKeyExt as _};
2934
use crate::traits::query::evaluate_obligation::InferCtxtExt;
@@ -166,15 +171,33 @@ where
166171
&mut self,
167172
infcx: &InferCtxt<'tcx>,
168173
) -> PredicateObligations<'tcx> {
169-
let mut processor =
170-
DrainProcessor { removed_predicates: PredicateObligations::new(), infcx };
174+
let stalled_coroutines = match infcx.typing_mode() {
175+
TypingMode::Analysis { defining_opaque_types_and_generators } => {
176+
defining_opaque_types_and_generators
177+
}
178+
TypingMode::Coherence
179+
| TypingMode::Borrowck { defining_opaque_types: _ }
180+
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ }
181+
| TypingMode::PostAnalysis => return Default::default(),
182+
};
183+
184+
if stalled_coroutines.is_empty() {
185+
return Default::default();
186+
}
187+
188+
let mut processor = DrainProcessor {
189+
infcx,
190+
removed_predicates: PredicateObligations::new(),
191+
stalled_coroutines,
192+
};
171193
let outcome: Outcome<_, _> = self.predicates.process_obligations(&mut processor);
172194
assert!(outcome.errors.is_empty());
173195
return processor.removed_predicates;
174196

175197
struct DrainProcessor<'a, 'tcx> {
176198
infcx: &'a InferCtxt<'tcx>,
177199
removed_predicates: PredicateObligations<'tcx>,
200+
stalled_coroutines: &'tcx ty::List<LocalDefId>,
178201
}
179202

180203
impl<'tcx> ObligationProcessor for DrainProcessor<'_, 'tcx> {
@@ -183,10 +206,14 @@ where
183206
type OUT = Outcome<Self::Obligation, Self::Error>;
184207

185208
fn needs_process_obligation(&self, pending_obligation: &Self::Obligation) -> bool {
186-
pending_obligation
187-
.stalled_on
188-
.iter()
189-
.any(|&var| self.infcx.ty_or_const_infer_var_changed(var))
209+
self.infcx
210+
.resolve_vars_if_possible(pending_obligation.obligation.predicate)
211+
.visit_with(&mut StalledOnCoroutines {
212+
stalled_coroutines: self.stalled_coroutines,
213+
span: DUMMY_SP,
214+
cache: Default::default(),
215+
})
216+
.is_break()
190217
}
191218

192219
fn process_obligation(

0 commit comments

Comments
 (0)