Skip to content

Commit cdc9f26

Browse files
committed
Auto merge of #144458 - compiler-errors:no-witness-mini, r=lcnr
Remove the witness type from coroutine *args* (without actually removing the type) This does as much of #144157 as we can without having to break #143545 and/or introduce some better way of handling higher ranked assumptions. Namely, it: * Stalls coroutines based off of the *coroutine* type rather than the witness type. * Reworks the dtorck constraint hack to not rely on the witness type. * Removes the witness type from the args of the coroutine, eagerly creating the type for nested obligations when needed (auto/clone impls). I'll experiment with actually removing the witness type in a follow-up. r? lcnr
2 parents adcb3d3 + e976578 commit cdc9f26

File tree

32 files changed

+273
-335
lines changed

32 files changed

+273
-335
lines changed

compiler/rustc_borrowck/src/type_check/input_output.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
8686
// them with fresh ty vars.
8787
resume_ty: next_ty_var(),
8888
yield_ty: next_ty_var(),
89-
witness: next_ty_var(),
9089
},
9190
)
9291
.args,

compiler/rustc_hir_analysis/src/collect/generics_of.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -379,20 +379,14 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
379379
// for info on the usage of each of these fields.
380380
let dummy_args = match kind {
381381
ClosureKind::Closure => &["<closure_kind>", "<closure_signature>", "<upvars>"][..],
382-
ClosureKind::Coroutine(_) => &[
383-
"<coroutine_kind>",
384-
"<resume_ty>",
385-
"<yield_ty>",
386-
"<return_ty>",
387-
"<witness>",
388-
"<upvars>",
389-
][..],
382+
ClosureKind::Coroutine(_) => {
383+
&["<coroutine_kind>", "<resume_ty>", "<yield_ty>", "<return_ty>", "<upvars>"][..]
384+
}
390385
ClosureKind::CoroutineClosure(_) => &[
391386
"<closure_kind>",
392387
"<closure_signature_parts>",
393388
"<upvars>",
394389
"<bound_captures_by_ref>",
395-
"<witness>",
396390
][..],
397391
};
398392

compiler/rustc_hir_typeck/src/closure.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,6 @@ 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-
let interior = Ty::new_coroutine_witness(tcx, expr_def_id.to_def_id(), parent_args);
165-
166164
// Coroutines that come from coroutine closures have not yet determined
167165
// their kind ty, so make a fresh infer var which will be constrained
168166
// later during upvar analysis. Regular coroutines always have the kind
@@ -182,7 +180,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
182180
resume_ty,
183181
yield_ty,
184182
return_ty: liberated_sig.output(),
185-
witness: interior,
186183
tupled_upvars_ty,
187184
},
188185
);
@@ -210,7 +207,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
210207
};
211208
// Compute all of the variables that will be used to populate the coroutine.
212209
let resume_ty = self.next_ty_var(expr_span);
213-
let interior = self.next_ty_var(expr_span);
214210

215211
let closure_kind_ty = match expected_kind {
216212
Some(kind) => Ty::from_closure_kind(tcx, kind),
@@ -243,7 +239,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
243239
),
244240
tupled_upvars_ty,
245241
coroutine_captures_by_ref_ty,
246-
coroutine_witness_ty: interior,
247242
},
248243
);
249244

compiler/rustc_middle/src/ty/generic_args.rs

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -96,38 +96,29 @@ impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArg
9696
signature_parts_ty,
9797
tupled_upvars_ty,
9898
coroutine_captures_by_ref_ty,
99-
coroutine_witness_ty,
10099
] => ty::CoroutineClosureArgsParts {
101100
parent_args,
102101
closure_kind_ty: closure_kind_ty.expect_ty(),
103102
signature_parts_ty: signature_parts_ty.expect_ty(),
104103
tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
105104
coroutine_captures_by_ref_ty: coroutine_captures_by_ref_ty.expect_ty(),
106-
coroutine_witness_ty: coroutine_witness_ty.expect_ty(),
107105
},
108106
_ => bug!("closure args missing synthetics"),
109107
}
110108
}
111109

112110
fn split_coroutine_args(self) -> ty::CoroutineArgsParts<TyCtxt<'tcx>> {
113111
match self[..] {
114-
[
115-
ref parent_args @ ..,
116-
kind_ty,
117-
resume_ty,
118-
yield_ty,
119-
return_ty,
120-
witness,
121-
tupled_upvars_ty,
122-
] => ty::CoroutineArgsParts {
123-
parent_args,
124-
kind_ty: kind_ty.expect_ty(),
125-
resume_ty: resume_ty.expect_ty(),
126-
yield_ty: yield_ty.expect_ty(),
127-
return_ty: return_ty.expect_ty(),
128-
witness: witness.expect_ty(),
129-
tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
130-
},
112+
[ref parent_args @ .., kind_ty, resume_ty, yield_ty, return_ty, tupled_upvars_ty] => {
113+
ty::CoroutineArgsParts {
114+
parent_args,
115+
kind_ty: kind_ty.expect_ty(),
116+
resume_ty: resume_ty.expect_ty(),
117+
yield_ty: yield_ty.expect_ty(),
118+
return_ty: return_ty.expect_ty(),
119+
tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
120+
}
121+
}
131122
_ => bug!("coroutine args missing synthetics"),
132123
}
133124
}

compiler/rustc_middle/src/ty/print/pretty.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -913,9 +913,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
913913
" yield_ty=",
914914
print(args.as_coroutine().yield_ty()),
915915
" return_ty=",
916-
print(args.as_coroutine().return_ty()),
917-
" witness=",
918-
print(args.as_coroutine().witness())
916+
print(args.as_coroutine().return_ty())
919917
);
920918
}
921919

@@ -1035,9 +1033,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
10351033
" upvar_tys=",
10361034
print(args.as_coroutine_closure().tupled_upvars_ty()),
10371035
" coroutine_captures_by_ref_ty=",
1038-
print(args.as_coroutine_closure().coroutine_captures_by_ref_ty()),
1039-
" coroutine_witness_ty=",
1040-
print(args.as_coroutine_closure().coroutine_witness_ty())
1036+
print(args.as_coroutine_closure().coroutine_captures_by_ref_ty())
10411037
);
10421038
}
10431039
p!("}}");

compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,16 @@ where
7575
Ok(ty::Binder::dummy(vec![args.as_coroutine_closure().tupled_upvars_ty()]))
7676
}
7777

78-
ty::Coroutine(_, args) => {
78+
ty::Coroutine(def_id, args) => {
7979
let coroutine_args = args.as_coroutine();
80-
Ok(ty::Binder::dummy(vec![coroutine_args.tupled_upvars_ty(), coroutine_args.witness()]))
80+
Ok(ty::Binder::dummy(vec![
81+
coroutine_args.tupled_upvars_ty(),
82+
Ty::new_coroutine_witness(
83+
ecx.cx(),
84+
def_id,
85+
ecx.cx().mk_args(coroutine_args.parent_args().as_slice()),
86+
),
87+
]))
8188
}
8289

8390
ty::CoroutineWitness(def_id, args) => Ok(ecx
@@ -245,7 +252,14 @@ where
245252
Movability::Movable => {
246253
if ecx.cx().features().coroutine_clone() {
247254
let coroutine = args.as_coroutine();
248-
Ok(ty::Binder::dummy(vec![coroutine.tupled_upvars_ty(), coroutine.witness()]))
255+
Ok(ty::Binder::dummy(vec![
256+
coroutine.tupled_upvars_ty(),
257+
Ty::new_coroutine_witness(
258+
ecx.cx(),
259+
def_id,
260+
ecx.cx().mk_args(coroutine.parent_args().as_slice()),
261+
),
262+
]))
249263
} else {
250264
Err(NoSolution)
251265
}

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ where
229229
}
230230

231231
// We need to make sure to stall any coroutines we are inferring to avoid query cycles.
232-
if let Some(cand) = ecx.try_stall_coroutine_witness(goal.predicate.self_ty()) {
232+
if let Some(cand) = ecx.try_stall_coroutine(goal.predicate.self_ty()) {
233233
return cand;
234234
}
235235

@@ -294,7 +294,7 @@ where
294294
}
295295

296296
// We need to make sure to stall any coroutines we are inferring to avoid query cycles.
297-
if let Some(cand) = ecx.try_stall_coroutine_witness(goal.predicate.self_ty()) {
297+
if let Some(cand) = ecx.try_stall_coroutine(goal.predicate.self_ty()) {
298298
return cand;
299299
}
300300

@@ -1432,11 +1432,8 @@ where
14321432
self.merge_trait_candidates(candidates)
14331433
}
14341434

1435-
fn try_stall_coroutine_witness(
1436-
&mut self,
1437-
self_ty: I::Ty,
1438-
) -> Option<Result<Candidate<I>, NoSolution>> {
1439-
if let ty::CoroutineWitness(def_id, _) = self_ty.kind() {
1435+
fn try_stall_coroutine(&mut self, self_ty: I::Ty) -> Option<Result<Candidate<I>, NoSolution>> {
1436+
if let ty::Coroutine(def_id, _) = self_ty.kind() {
14401437
match self.typing_mode() {
14411438
TypingMode::Analysis {
14421439
defining_opaque_types_and_generators: stalled_generators,

compiler/rustc_trait_selection/src/solve/fulfill.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for StalledOnCoroutines<'tcx> {
355355
return ControlFlow::Continue(());
356356
}
357357

358-
if let ty::CoroutineWitness(def_id, _) = *ty.kind()
358+
if let ty::Coroutine(def_id, _) = *ty.kind()
359359
&& def_id.as_local().is_some_and(|def_id| self.stalled_coroutines.contains(&def_id))
360360
{
361361
ControlFlow::Break(())

compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
318318
})
319319
}
320320

321-
ty::Coroutine(_, args) => {
321+
ty::Coroutine(def_id, args) => {
322322
// rust-lang/rust#49918: types can be constructed, stored
323323
// in the interior, and sit idle when coroutine yields
324324
// (and is subsequently dropped).
@@ -346,7 +346,10 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
346346
// While we conservatively assume that all coroutines require drop
347347
// to avoid query cycles during MIR building, we can check the actual
348348
// witness during borrowck to avoid unnecessary liveness constraints.
349-
if args.witness().needs_drop(tcx, tcx.erase_regions(typing_env)) {
349+
let typing_env = tcx.erase_regions(typing_env);
350+
if tcx.mir_coroutine_witnesses(def_id).is_some_and(|witness| {
351+
witness.field_tys.iter().any(|field| field.ty.needs_drop(tcx, typing_env))
352+
}) {
350353
constraints.outlives.extend(args.upvar_tys().iter().map(ty::GenericArg::from));
351354
constraints.outlives.push(args.resume_ty().into());
352355
}

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

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -794,18 +794,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
794794
// The auto impl might apply; we don't know.
795795
candidates.ambiguous = true;
796796
}
797-
ty::Coroutine(coroutine_def_id, _)
798-
if self.tcx().is_lang_item(def_id, LangItem::Unpin) =>
799-
{
800-
match self.tcx().coroutine_movability(coroutine_def_id) {
801-
hir::Movability::Static => {
802-
// Immovable coroutines are never `Unpin`, so
803-
// suppress the normal auto-impl candidate for it.
797+
ty::Coroutine(coroutine_def_id, _) => {
798+
if self.tcx().is_lang_item(def_id, LangItem::Unpin) {
799+
match self.tcx().coroutine_movability(coroutine_def_id) {
800+
hir::Movability::Static => {
801+
// Immovable coroutines are never `Unpin`, so
802+
// suppress the normal auto-impl candidate for it.
803+
}
804+
hir::Movability::Movable => {
805+
// Movable coroutines are always `Unpin`, so add an
806+
// unconditional builtin candidate with no sub-obligations.
807+
candidates.vec.push(BuiltinCandidate);
808+
}
804809
}
805-
hir::Movability::Movable => {
806-
// Movable coroutines are always `Unpin`, so add an
807-
// unconditional builtin candidate.
808-
candidates.vec.push(BuiltinCandidate);
810+
} else {
811+
if self.should_stall_coroutine(coroutine_def_id) {
812+
candidates.ambiguous = true;
813+
} else {
814+
// Coroutines implement all other auto traits normally.
815+
candidates.vec.push(AutoImplCandidate);
809816
}
810817
}
811818
}
@@ -842,12 +849,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
842849
}
843850
}
844851

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-
}
852+
ty::CoroutineWitness(..) => {
853+
candidates.vec.push(AutoImplCandidate);
851854
}
852855

853856
ty::Bool
@@ -866,7 +869,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
866869
| ty::FnPtr(..)
867870
| ty::Closure(..)
868871
| ty::CoroutineClosure(..)
869-
| ty::Coroutine(..)
870872
| ty::Never
871873
| ty::Tuple(_)
872874
| ty::UnsafeBinder(_) => {
@@ -1153,15 +1155,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11531155
ty::Ref(_, _, hir::Mutability::Mut) => {}
11541156

11551157
ty::Coroutine(coroutine_def_id, args) => {
1158+
if self.should_stall_coroutine(coroutine_def_id) {
1159+
candidates.ambiguous = true;
1160+
return;
1161+
}
1162+
11561163
match self.tcx().coroutine_movability(coroutine_def_id) {
11571164
hir::Movability::Static => {}
11581165
hir::Movability::Movable => {
11591166
if self.tcx().features().coroutine_clone() {
11601167
let resolved_upvars =
11611168
self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
1162-
let resolved_witness =
1163-
self.infcx.shallow_resolve(args.as_coroutine().witness());
1164-
if resolved_upvars.is_ty_var() || resolved_witness.is_ty_var() {
1169+
if resolved_upvars.is_ty_var() {
11651170
// Not yet resolved.
11661171
candidates.ambiguous = true;
11671172
} else {
@@ -1194,12 +1199,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11941199
}
11951200
}
11961201

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-
}
1202+
ty::CoroutineWitness(..) => {
1203+
candidates.vec.push(SizedCandidate);
12031204
}
12041205

12051206
// Fallback to whatever user-defined impls or param-env clauses exist in this case.
@@ -1238,7 +1239,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12381239
| ty::RawPtr(..)
12391240
| ty::Char
12401241
| ty::Ref(..)
1241-
| ty::Coroutine(..)
12421242
| ty::Array(..)
12431243
| ty::Closure(..)
12441244
| ty::CoroutineClosure(..)
@@ -1247,14 +1247,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
12471247
candidates.vec.push(SizedCandidate);
12481248
}
12491249

1250-
ty::CoroutineWitness(coroutine_def_id, _) => {
1251-
if self.should_stall_coroutine_witness(coroutine_def_id) {
1250+
ty::Coroutine(coroutine_def_id, _) => {
1251+
if self.should_stall_coroutine(coroutine_def_id) {
12521252
candidates.ambiguous = true;
12531253
} else {
12541254
candidates.vec.push(SizedCandidate);
12551255
}
12561256
}
12571257

1258+
ty::CoroutineWitness(..) => {
1259+
candidates.vec.push(SizedCandidate);
1260+
}
1261+
12581262
// Conditionally `Sized`.
12591263
ty::Tuple(..) | ty::Pat(..) | ty::Adt(..) | ty::UnsafeBinder(_) => {
12601264
candidates.vec.push(SizedCandidate);

0 commit comments

Comments
 (0)