Stall coroutines based off of ty::Coroutine, not ty::CoroutineWitness

This commit is contained in:
Michael Goulet
2025-07-18 18:17:15 +00:00
parent 3fb1b53a9d
commit d525e79157
15 changed files with 218 additions and 210 deletions

View File

@@ -794,18 +794,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// The auto impl might apply; we don't know.
candidates.ambiguous = true;
}
ty::Coroutine(coroutine_def_id, _)
if self.tcx().is_lang_item(def_id, LangItem::Unpin) =>
{
match self.tcx().coroutine_movability(coroutine_def_id) {
hir::Movability::Static => {
// Immovable coroutines are never `Unpin`, so
// suppress the normal auto-impl candidate for it.
ty::Coroutine(coroutine_def_id, _) => {
if self.tcx().is_lang_item(def_id, LangItem::Unpin) {
match self.tcx().coroutine_movability(coroutine_def_id) {
hir::Movability::Static => {
// Immovable coroutines are never `Unpin`, so
// suppress the normal auto-impl candidate for it.
}
hir::Movability::Movable => {
// Movable coroutines are always `Unpin`, so add an
// unconditional builtin candidate with no sub-obligations.
candidates.vec.push(BuiltinCandidate);
}
}
hir::Movability::Movable => {
// Movable coroutines are always `Unpin`, so add an
// unconditional builtin candidate.
candidates.vec.push(BuiltinCandidate);
} else {
if self.should_stall_coroutine(coroutine_def_id) {
candidates.ambiguous = true;
} else {
// Coroutines implement all other auto traits normally.
candidates.vec.push(AutoImplCandidate);
}
}
}
@@ -842,12 +849,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
ty::CoroutineWitness(def_id, _) => {
if self.should_stall_coroutine_witness(def_id) {
candidates.ambiguous = true;
} else {
candidates.vec.push(AutoImplCandidate);
}
ty::CoroutineWitness(..) => {
candidates.vec.push(AutoImplCandidate);
}
ty::Bool
@@ -866,7 +869,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::FnPtr(..)
| ty::Closure(..)
| ty::CoroutineClosure(..)
| ty::Coroutine(..)
| ty::Never
| ty::Tuple(_)
| ty::UnsafeBinder(_) => {
@@ -1153,6 +1155,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ty::Ref(_, _, hir::Mutability::Mut) => {}
ty::Coroutine(coroutine_def_id, args) => {
if self.should_stall_coroutine(coroutine_def_id) {
candidates.ambiguous = true;
return;
}
match self.tcx().coroutine_movability(coroutine_def_id) {
hir::Movability::Static => {}
hir::Movability::Movable => {
@@ -1194,12 +1201,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
ty::CoroutineWitness(coroutine_def_id, _) => {
if self.should_stall_coroutine_witness(coroutine_def_id) {
candidates.ambiguous = true;
} else {
candidates.vec.push(SizedCandidate);
}
ty::CoroutineWitness(..) => {
candidates.vec.push(SizedCandidate);
}
// Fallback to whatever user-defined impls or param-env clauses exist in this case.
@@ -1238,7 +1241,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::RawPtr(..)
| ty::Char
| ty::Ref(..)
| ty::Coroutine(..)
| ty::Array(..)
| ty::Closure(..)
| ty::CoroutineClosure(..)
@@ -1247,14 +1249,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
candidates.vec.push(SizedCandidate);
}
ty::CoroutineWitness(coroutine_def_id, _) => {
if self.should_stall_coroutine_witness(coroutine_def_id) {
ty::Coroutine(coroutine_def_id, _) => {
if self.should_stall_coroutine(coroutine_def_id) {
candidates.ambiguous = true;
} else {
candidates.vec.push(SizedCandidate);
}
}
ty::CoroutineWitness(..) => {
candidates.vec.push(SizedCandidate);
}
// Conditionally `Sized`.
ty::Tuple(..) | ty::Pat(..) | ty::Adt(..) | ty::UnsafeBinder(_) => {
candidates.vec.push(SizedCandidate);

View File

@@ -2841,7 +2841,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
obligations
}
fn should_stall_coroutine_witness(&self, def_id: DefId) -> bool {
fn should_stall_coroutine(&self, def_id: DefId) -> bool {
match self.infcx.typing_mode() {
TypingMode::Analysis { defining_opaque_types_and_generators: stalled_generators } => {
def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id))