Skip to content

Commit 7bff9fb

Browse files
Eagerly unify coroutine witness in old solver
1 parent 0b23106 commit 7bff9fb

File tree

15 files changed

+133
-126
lines changed

15 files changed

+133
-126
lines changed

compiler/rustc_hir_typeck/src/closure.rs

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

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

177168
// Coroutines that come from coroutine closures have not yet determined
178169
// 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
@@ -698,17 +698,13 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
698698
self,
699699
defining_anchor: Self::LocalDefId,
700700
) -> Self::LocalDefIds {
701-
if self.next_trait_solver_globally() {
702-
let coroutines_defined_by = self
703-
.nested_bodies_within(defining_anchor)
704-
.iter()
705-
.filter(|def_id| self.is_coroutine(def_id.to_def_id()));
706-
self.mk_local_def_ids_from_iter(
707-
self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
708-
)
709-
} else {
710-
self.opaque_types_defined_by(defining_anchor)
711-
}
701+
let coroutines_defined_by = self
702+
.nested_bodies_within(defining_anchor)
703+
.iter()
704+
.filter(|def_id| self.is_coroutine(def_id.to_def_id()));
705+
self.mk_local_def_ids_from_iter(
706+
self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
707+
)
712708
}
713709
}
714710

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/select/candidate_assembly.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,6 +804,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
804804
}
805805
}
806806

807+
ty::CoroutineWitness(def_id, _) => {
808+
if self.should_stall_coroutine_witness(def_id) {
809+
candidates.ambiguous = true;
810+
} else {
811+
candidates.vec.push(AutoImplCandidate);
812+
}
813+
}
814+
807815
ty::Bool
808816
| ty::Char
809817
| ty::Int(_)
@@ -823,7 +831,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
823831
| ty::Coroutine(..)
824832
| ty::Never
825833
| ty::Tuple(_)
826-
| ty::CoroutineWitness(..)
827834
| ty::UnsafeBinder(_) => {
828835
// Only consider auto impls of unsafe traits when there are
829836
// no unsafe fields.

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

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,7 +1508,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
15081508
defining_opaque_types_and_generators: defining_opaque_types,
15091509
}
15101510
| TypingMode::Borrowck { defining_opaque_types } => {
1511-
defining_opaque_types.is_empty() || !pred.has_opaque_types()
1511+
defining_opaque_types.is_empty()
1512+
|| (!pred.has_opaque_types() && !pred.has_coroutines())
15121513
}
15131514
// The hidden types of `defined_opaque_types` is not local to the current
15141515
// inference context, so we can freely move this to the global cache.
@@ -2224,13 +2225,17 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
22242225
}
22252226

22262227
ty::CoroutineWitness(def_id, args) => {
2227-
let hidden_types = rebind_coroutine_witness_types(
2228-
self.infcx.tcx,
2229-
def_id,
2230-
args,
2231-
obligation.predicate.bound_vars(),
2232-
);
2233-
Where(hidden_types)
2228+
if self.should_stall_coroutine_witness(def_id) {
2229+
Ambiguous
2230+
} else {
2231+
let hidden_types = rebind_coroutine_witness_types(
2232+
self.infcx.tcx,
2233+
def_id,
2234+
args,
2235+
obligation.predicate.bound_vars(),
2236+
);
2237+
Where(hidden_types)
2238+
}
22342239
}
22352240

22362241
ty::Closure(_, args) => {
@@ -2856,6 +2861,22 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
28562861

28572862
obligations
28582863
}
2864+
2865+
fn should_stall_coroutine_witness(&self, def_id: DefId) -> bool {
2866+
match self.infcx.typing_mode() {
2867+
TypingMode::Analysis { defining_opaque_types_and_generators: stalled_generators } => {
2868+
if def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id)) {
2869+
return true;
2870+
}
2871+
}
2872+
TypingMode::Coherence
2873+
| TypingMode::PostAnalysis
2874+
| TypingMode::Borrowck { defining_opaque_types: _ }
2875+
| TypingMode::PostBorrowckAnalysis { defined_opaque_types: _ } => {}
2876+
}
2877+
2878+
false
2879+
}
28592880
}
28602881

28612882
fn rebind_coroutine_witness_types<'tcx>(

compiler/rustc_type_ir/src/flags.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ bitflags::bitflags! {
130130

131131
/// Does this have any binders with bound vars (e.g. that need to be anonymized)?
132132
const HAS_BINDER_VARS = 1 << 23;
133+
134+
const HAS_TY_CORO = 1 << 24;
133135
}
134136
}
135137

@@ -240,10 +242,12 @@ impl<I: Interner> FlagComputation<I> {
240242
self.add_flags(TypeFlags::HAS_TY_PARAM);
241243
}
242244

243-
ty::Closure(_, args)
244-
| ty::Coroutine(_, args)
245-
| ty::CoroutineClosure(_, args)
246-
| ty::CoroutineWitness(_, args) => {
245+
ty::Closure(_, args) | ty::Coroutine(_, args) | ty::CoroutineClosure(_, args) => {
246+
self.add_args(args.as_slice());
247+
}
248+
249+
ty::CoroutineWitness(_, args) => {
250+
self.add_flags(TypeFlags::HAS_TY_CORO);
247251
self.add_args(args.as_slice());
248252
}
249253

compiler/rustc_type_ir/src/visit.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,10 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
269269
self.has_type_flags(TypeFlags::HAS_TY_OPAQUE)
270270
}
271271

272+
fn has_coroutines(&self) -> bool {
273+
self.has_type_flags(TypeFlags::HAS_TY_CORO)
274+
}
275+
272276
fn references_error(&self) -> bool {
273277
self.has_type_flags(TypeFlags::HAS_ERROR)
274278
}

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: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,35 +42,36 @@ fn test3() {
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)