Eagerly unify coroutine witness in old solver

This commit is contained in:
Michael Goulet
2025-05-29 12:34:50 +00:00
parent 72bc11d146
commit 216cdb7b22
14 changed files with 125 additions and 123 deletions

View File

@@ -842,6 +842,14 @@ 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::Bool
| ty::Char
| ty::Int(_)
@@ -861,7 +869,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Coroutine(..)
| ty::Never
| ty::Tuple(_)
| ty::CoroutineWitness(..)
| ty::UnsafeBinder(_) => {
// Only consider auto impls of unsafe traits when there are
// no unsafe fields.
@@ -1119,12 +1126,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
match *self_ty.kind() {
// These impls are built-in because we cannot express sufficiently
// generic impls in libcore.
ty::FnDef(..)
| ty::FnPtr(..)
| ty::Error(_)
| ty::Tuple(..)
| ty::CoroutineWitness(..)
| ty::Pat(..) => {
ty::FnDef(..) | ty::FnPtr(..) | ty::Error(_) | ty::Tuple(..) | ty::Pat(..) => {
candidates.vec.push(BuiltinCandidate);
}
@@ -1192,6 +1194,14 @@ 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);
}
}
// Fallback to whatever user-defined impls or param-env clauses exist in this case.
ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {}
@@ -1229,7 +1239,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
| ty::Char
| ty::Ref(..)
| ty::Coroutine(..)
| ty::CoroutineWitness(..)
| ty::Array(..)
| ty::Closure(..)
| ty::CoroutineClosure(..)
@@ -1238,6 +1247,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
candidates.vec.push(SizedCandidate);
}
ty::CoroutineWitness(coroutine_def_id, _) => {
if self.should_stall_coroutine_witness(coroutine_def_id) {
candidates.ambiguous = true;
} else {
candidates.vec.push(SizedCandidate);
}
}
// Conditionally `Sized`.
ty::Tuple(..) | ty::Pat(..) | ty::Adt(..) | ty::UnsafeBinder(_) => {
candidates.vec.push(SizedCandidate);

View File

@@ -1512,7 +1512,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
defining_opaque_types_and_generators: defining_opaque_types,
}
| TypingMode::Borrowck { defining_opaque_types } => {
defining_opaque_types.is_empty() || !pred.has_opaque_types()
defining_opaque_types.is_empty()
|| (!pred.has_opaque_types() && !pred.has_coroutines())
}
// The hidden types of `defined_opaque_types` is not local to the current
// inference context, so we can freely move this to the global cache.
@@ -2811,6 +2812,18 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
obligations
}
fn should_stall_coroutine_witness(&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))
}
TypingMode::Coherence
| TypingMode::PostAnalysis
| TypingMode::Borrowck { defining_opaque_types: _ }
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => false,
}
}
}
impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> {