Check if type has coroutines before visiting

This commit is contained in:
Michael Goulet
2025-06-25 16:03:52 +00:00
parent bf5e6cc7a7
commit 96171dc78f
3 changed files with 23 additions and 8 deletions

View File

@@ -10,7 +10,8 @@ use rustc_infer::traits::{
FromSolverError, PredicateObligation, PredicateObligations, TraitEngine, FromSolverError, PredicateObligation, PredicateObligations, TraitEngine,
}; };
use rustc_middle::ty::{ use rustc_middle::ty::{
self, DelayedSet, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, TypingMode, self, DelayedSet, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
TypingMode,
}; };
use rustc_next_trait_solver::delegate::SolverDelegate as _; use rustc_next_trait_solver::delegate::SolverDelegate as _;
use rustc_next_trait_solver::solve::{ use rustc_next_trait_solver::solve::{
@@ -332,10 +333,12 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for StalledOnCoroutines<'tcx> {
if let ty::CoroutineWitness(def_id, _) = *ty.kind() if let ty::CoroutineWitness(def_id, _) = *ty.kind()
&& def_id.as_local().is_some_and(|def_id| self.stalled_generators.contains(&def_id)) && def_id.as_local().is_some_and(|def_id| self.stalled_generators.contains(&def_id))
{ {
return ControlFlow::Break(()); ControlFlow::Break(())
} else if ty.has_coroutines() {
ty.super_visit_with(self)
} else {
ControlFlow::Continue(())
} }
ty.super_visit_with(self)
} }
} }

View File

@@ -130,6 +130,12 @@ bitflags::bitflags! {
/// Does this have any binders with bound vars (e.g. that need to be anonymized)? /// Does this have any binders with bound vars (e.g. that need to be anonymized)?
const HAS_BINDER_VARS = 1 << 23; const HAS_BINDER_VARS = 1 << 23;
/// Does this type have any coroutine witnesses in it?
// FIXME: This should probably be changed to track whether the type has any
// *coroutines* in it, though this will happen if we remove coroutine witnesses
// altogether.
const HAS_TY_CORO = 1 << 24;
} }
} }
@@ -240,10 +246,12 @@ impl<I: Interner> FlagComputation<I> {
self.add_flags(TypeFlags::HAS_TY_PARAM); self.add_flags(TypeFlags::HAS_TY_PARAM);
} }
ty::Closure(_, args) ty::Closure(_, args) | ty::Coroutine(_, args) | ty::CoroutineClosure(_, args) => {
| ty::Coroutine(_, args) self.add_args(args.as_slice());
| ty::CoroutineClosure(_, args) }
| ty::CoroutineWitness(_, args) => {
ty::CoroutineWitness(_, args) => {
self.add_flags(TypeFlags::HAS_TY_CORO);
self.add_args(args.as_slice()); self.add_args(args.as_slice());
} }

View File

@@ -269,6 +269,10 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
self.has_type_flags(TypeFlags::HAS_TY_OPAQUE) self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
} }
fn has_coroutines(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_CORO)
}
fn references_error(&self) -> bool { fn references_error(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_ERROR) self.has_type_flags(TypeFlags::HAS_ERROR)
} }