Skip to content

Commit 216cdb7

Browse files
Eagerly unify coroutine witness in old solver
1 parent 72bc11d commit 216cdb7

File tree

14 files changed

+125
-123
lines changed

14 files changed

+125
-123
lines changed

compiler/rustc_hir_typeck/src/closure.rs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -161,16 +161,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
161161
// Resume type defaults to `()` if the coroutine has no argument.
162162
let resume_ty = liberated_sig.inputs().get(0).copied().unwrap_or(tcx.types.unit);
163163

164-
// In the new solver, we can just instantiate this eagerly
165-
// with the witness. This will ensure that goals that don't need
166-
// to stall on interior types will get processed eagerly.
167-
let interior = if self.next_trait_solver() {
168-
Ty::new_coroutine_witness(tcx, expr_def_id.to_def_id(), parent_args)
169-
} else {
170-
self.next_ty_var(expr_span)
171-
};
172-
173-
self.deferred_coroutine_interiors.borrow_mut().push((expr_def_id, interior));
164+
let interior = Ty::new_coroutine_witness(tcx, expr_def_id.to_def_id(), parent_args);
174165

175166
// Coroutines that come from coroutine closures have not yet determined
176167
// their kind ty, so make a fresh infer var which will be constrained

compiler/rustc_hir_typeck/src/typeck_root_ctxt.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ pub(crate) struct TypeckRootCtxt<'tcx> {
6363

6464
pub(super) deferred_asm_checks: RefCell<Vec<(&'tcx hir::InlineAsm<'tcx>, HirId)>>,
6565

66-
pub(super) deferred_coroutine_interiors: RefCell<Vec<(LocalDefId, Ty<'tcx>)>>,
67-
6866
pub(super) deferred_repeat_expr_checks:
6967
RefCell<Vec<(&'tcx hir::Expr<'tcx>, Ty<'tcx>, ty::Const<'tcx>)>>,
7068

@@ -103,7 +101,6 @@ impl<'tcx> TypeckRootCtxt<'tcx> {
103101
deferred_cast_checks: RefCell::new(Vec::new()),
104102
deferred_transmute_checks: RefCell::new(Vec::new()),
105103
deferred_asm_checks: RefCell::new(Vec::new()),
106-
deferred_coroutine_interiors: RefCell::new(Vec::new()),
107104
deferred_repeat_expr_checks: RefCell::new(Vec::new()),
108105
diverging_type_vars: RefCell::new(Default::default()),
109106
infer_var_info: RefCell::new(Default::default()),

compiler/rustc_middle/src/ty/context.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -714,17 +714,13 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
714714
self,
715715
defining_anchor: Self::LocalDefId,
716716
) -> Self::LocalDefIds {
717-
if self.next_trait_solver_globally() {
718-
let coroutines_defined_by = self
719-
.nested_bodies_within(defining_anchor)
720-
.iter()
721-
.filter(|def_id| self.is_coroutine(def_id.to_def_id()));
722-
self.mk_local_def_ids_from_iter(
723-
self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
724-
)
725-
} else {
726-
self.opaque_types_defined_by(defining_anchor)
727-
}
717+
let coroutines_defined_by = self
718+
.nested_bodies_within(defining_anchor)
719+
.iter()
720+
.filter(|def_id| self.is_coroutine(def_id.to_def_id()));
721+
self.mk_local_def_ids_from_iter(
722+
self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
723+
)
728724
}
729725
}
730726

compiler/rustc_trait_selection/src/infer.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ impl<'tcx> InferCtxt<'tcx> {
3333
let ty = self.resolve_vars_if_possible(ty);
3434

3535
// FIXME(#132279): This should be removed as it causes us to incorrectly
36-
// handle opaques in their defining scope.
37-
if !self.next_trait_solver() && !(param_env, ty).has_infer() {
36+
// handle opaques in their defining scope, and stalled coroutines.
37+
if !self.next_trait_solver() && !(param_env, ty).has_infer() && !ty.has_coroutines() {
3838
return self.tcx.type_is_copy_modulo_regions(self.typing_env(param_env), ty);
3939
}
4040

compiler/rustc_trait_selection/src/solve.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod normalize;
77
mod select;
88

99
pub(crate) use delegate::SolverDelegate;
10-
pub use fulfill::{FulfillmentCtxt, NextSolverError};
10+
pub use fulfill::{FulfillmentCtxt, NextSolverError, StalledOnCoroutines};
1111
pub(crate) use normalize::deeply_normalize_for_diagnostics;
1212
pub use normalize::{
1313
deeply_normalize, deeply_normalize_with_skipped_universes,

compiler/rustc_trait_selection/src/traits/fulfill.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use rustc_middle::ty::abstract_const::NotConstEvaluatable;
1414
use rustc_middle::ty::error::{ExpectedFound, TypeError};
1515
use rustc_middle::ty::{
1616
self, Binder, Const, GenericArgsRef, TypeVisitable, TypeVisitableExt, TypingMode,
17+
may_use_unstable_feature,
1718
};
1819
use rustc_span::DUMMY_SP;
1920
use thin_vec::{ThinVec, thin_vec};

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
842842
}
843843
}
844844

845+
ty::CoroutineWitness(def_id, _) => {
846+
if self.should_stall_coroutine_witness(def_id) {
847+
candidates.ambiguous = true;
848+
} else {
849+
candidates.vec.push(AutoImplCandidate);
850+
}
851+
}
852+
845853
ty::Bool
846854
| ty::Char
847855
| ty::Int(_)
@@ -861,7 +869,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
861869
| ty::Coroutine(..)
862870
| ty::Never
863871
| ty::Tuple(_)
864-
| ty::CoroutineWitness(..)
865872
| ty::UnsafeBinder(_) => {
866873
// Only consider auto impls of unsafe traits when there are
867874
// no unsafe fields.
@@ -1119,12 +1126,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11191126
match *self_ty.kind() {
11201127
// These impls are built-in because we cannot express sufficiently
11211128
// generic impls in libcore.
1122-
ty::FnDef(..)
1123-
| ty::FnPtr(..)
1124-
| ty::Error(_)
1125-
| ty::Tuple(..)
1126-
| ty::CoroutineWitness(..)
1127-
| ty::Pat(..) => {
1129+
ty::FnDef(..) | ty::FnPtr(..) | ty::Error(_) | ty::Tuple(..) | ty::Pat(..) => {
11281130
candidates.vec.push(BuiltinCandidate);
11291131
}
11301132

@@ -1192,6 +1194,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11921194
}
11931195
}
11941196

1197+
ty::CoroutineWitness(coroutine_def_id, _) => {
1198+
if self.should_stall_coroutine_witness(coroutine_def_id) {
1199+
candidates.ambiguous = true;
1200+
} else {
1201+
candidates.vec.push(SizedCandidate);
1202+
}
1203+
}
1204+
11951205
// Fallback to whatever user-defined impls or param-env clauses exist in this case.
11961206
ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => {}
11971207

@@ -1229,7 +1239,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12291239
| ty::Char
12301240
| ty::Ref(..)
12311241
| ty::Coroutine(..)
1232-
| ty::CoroutineWitness(..)
12331242
| ty::Array(..)
12341243
| ty::Closure(..)
12351244
| ty::CoroutineClosure(..)
@@ -1238,6 +1247,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12381247
candidates.vec.push(SizedCandidate);
12391248
}
12401249

1250+
ty::CoroutineWitness(coroutine_def_id, _) => {
1251+
if self.should_stall_coroutine_witness(coroutine_def_id) {
1252+
candidates.ambiguous = true;
1253+
} else {
1254+
candidates.vec.push(SizedCandidate);
1255+
}
1256+
}
1257+
12411258
// Conditionally `Sized`.
12421259
ty::Tuple(..) | ty::Pat(..) | ty::Adt(..) | ty::UnsafeBinder(_) => {
12431260
candidates.vec.push(SizedCandidate);

compiler/rustc_trait_selection/src/traits/select/mod.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1512,7 +1512,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15121512
defining_opaque_types_and_generators: defining_opaque_types,
15131513
}
15141514
| TypingMode::Borrowck { defining_opaque_types } => {
1515-
defining_opaque_types.is_empty() || !pred.has_opaque_types()
1515+
defining_opaque_types.is_empty()
1516+
|| (!pred.has_opaque_types() && !pred.has_coroutines())
15161517
}
15171518
// The hidden types of `defined_opaque_types` is not local to the current
15181519
// inference context, so we can freely move this to the global cache.
@@ -2811,6 +2812,18 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
28112812

28122813
obligations
28132814
}
2815+
2816+
fn should_stall_coroutine_witness(&self, def_id: DefId) -> bool {
2817+
match self.infcx.typing_mode() {
2818+
TypingMode::Analysis { defining_opaque_types_and_generators: stalled_generators } => {
2819+
def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id))
2820+
}
2821+
TypingMode::Coherence
2822+
| TypingMode::PostAnalysis
2823+
| TypingMode::Borrowck { defining_opaque_types: _ }
2824+
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => false,
2825+
}
2826+
}
28142827
}
28152828

28162829
impl<'o, 'tcx> TraitObligationStack<'o, 'tcx> {

tests/ui/async-await/async-closures/def-path.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ LL | let x = async || {};
55
| -- the expected `async` closure body
66
LL |
77
LL | let () = x();
8-
| ^^ --- this expression has type `{static main::{closure#0}::{closure#0}<?17t> upvar_tys=?16t resume_ty=ResumeTy yield_ty=() return_ty=() witness=?5t}`
8+
| ^^ --- this expression has type `{static main::{closure#0}::{closure#0}<?16t> upvar_tys=?15t resume_ty=ResumeTy yield_ty=() return_ty=() witness={main::{closure#0}::{closure#0}}}`
99
| |
1010
| expected `async` closure body, found `()`
1111
|
12-
= note: expected `async` closure body `{static main::{closure#0}::{closure#0}<?17t> upvar_tys=?16t resume_ty=ResumeTy yield_ty=() return_ty=() witness=?5t}`
12+
= note: expected `async` closure body `{static main::{closure#0}::{closure#0}<?16t> upvar_tys=?15t resume_ty=ResumeTy yield_ty=() return_ty=() witness={main::{closure#0}::{closure#0}}}`
1313
found unit type `()`
1414

1515
error: aborting due to 1 previous error

tests/ui/coroutine/clone-impl.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,39 +38,40 @@ fn test2() {
3838
check_clone(&gen_copy_1);
3939
}
4040

41-
fn test3() {
41+
fn test3_upvars() {
4242
let clonable_0: Vec<u32> = Vec::new();
4343
let gen_clone_0 = #[coroutine]
4444
move || {
45-
let v = vec!['a'];
46-
yield;
47-
drop(v);
4845
drop(clonable_0);
4946
};
5047
check_copy(&gen_clone_0);
5148
//~^ ERROR the trait bound `Vec<u32>: Copy` is not satisfied
52-
//~| ERROR the trait bound `Vec<char>: Copy` is not satisfied
5349
check_clone(&gen_clone_0);
5450
}
5551

52+
fn test3_witness() {
53+
let gen_clone_1 = #[coroutine]
54+
move || {
55+
let v = vec!['a'];
56+
yield;
57+
drop(v);
58+
};
59+
check_copy(&gen_clone_1);
60+
//~^ ERROR the trait bound `Vec<char>: Copy` is not satisfied
61+
check_clone(&gen_clone_1);
62+
}
63+
5664
fn test4() {
5765
let clonable_1: Vec<u32> = Vec::new();
5866
let gen_clone_1 = #[coroutine]
5967
move || {
60-
let v = vec!['a'];
61-
/*
62-
let n = NonClone;
63-
drop(n);
64-
*/
6568
yield;
6669
let n = NonClone;
6770
drop(n);
68-
drop(v);
6971
drop(clonable_1);
7072
};
7173
check_copy(&gen_clone_1);
7274
//~^ ERROR the trait bound `Vec<u32>: Copy` is not satisfied
73-
//~| ERROR the trait bound `Vec<char>: Copy` is not satisfied
7475
check_clone(&gen_clone_1);
7576
}
7677

0 commit comments

Comments
 (0)