Skip to content

Commit 49fc0cc

Browse files
committed
Auto merge of #145395 - lcnr:review-coroutine-witness, r=petrochenkov
[BETA] Revert "Remove the witness type from coroutine args" fixes #145151 and #145288 we do not revert on nightly as its instead fixed by #145194 and #145338. See the discussion in https://rust-lang.zulipchat.com/#narrow/channel/238009-t-compiler.2Fmeetings/topic/.5Bweekly.5D.202025-08-14/near/534490313
2 parents 47b72a3 + a89083b commit 49fc0cc

File tree

19 files changed

+150
-54
lines changed

19 files changed

+150
-54
lines changed

compiler/rustc_borrowck/src/type_check/input_output.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ 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(),
8990
},
9091
)
9192
.args,

compiler/rustc_hir_analysis/src/collect/generics_of.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,14 +379,20 @@ 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>", "<resume_ty>", "<yield_ty>", "<return_ty>", "<upvars>"][..]
384-
}
382+
ClosureKind::Coroutine(_) => &[
383+
"<coroutine_kind>",
384+
"<resume_ty>",
385+
"<yield_ty>",
386+
"<return_ty>",
387+
"<witness>",
388+
"<upvars>",
389+
][..],
385390
ClosureKind::CoroutineClosure(_) => &[
386391
"<closure_kind>",
387392
"<closure_signature_parts>",
388393
"<upvars>",
389394
"<bound_captures_by_ref>",
395+
"<witness>",
390396
][..],
391397
};
392398

compiler/rustc_hir_typeck/src/closure.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ 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+
164166
// Coroutines that come from coroutine closures have not yet determined
165167
// their kind ty, so make a fresh infer var which will be constrained
166168
// later during upvar analysis. Regular coroutines always have the kind
@@ -180,6 +182,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
180182
resume_ty,
181183
yield_ty,
182184
return_ty: liberated_sig.output(),
185+
witness: interior,
183186
tupled_upvars_ty,
184187
},
185188
);
@@ -207,6 +210,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
207210
};
208211
// Compute all of the variables that will be used to populate the coroutine.
209212
let resume_ty = self.next_ty_var(expr_span);
213+
let interior = self.next_ty_var(expr_span);
210214

211215
let closure_kind_ty = match expected_kind {
212216
Some(kind) => Ty::from_closure_kind(tcx, kind),
@@ -239,6 +243,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
239243
),
240244
tupled_upvars_ty,
241245
coroutine_captures_by_ref_ty,
246+
coroutine_witness_ty: interior,
242247
},
243248
);
244249

compiler/rustc_middle/src/ty/generic_args.rs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -96,29 +96,38 @@ 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,
99100
] => ty::CoroutineClosureArgsParts {
100101
parent_args,
101102
closure_kind_ty: closure_kind_ty.expect_ty(),
102103
signature_parts_ty: signature_parts_ty.expect_ty(),
103104
tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
104105
coroutine_captures_by_ref_ty: coroutine_captures_by_ref_ty.expect_ty(),
106+
coroutine_witness_ty: coroutine_witness_ty.expect_ty(),
105107
},
106108
_ => bug!("closure args missing synthetics"),
107109
}
108110
}
109111

110112
fn split_coroutine_args(self) -> ty::CoroutineArgsParts<TyCtxt<'tcx>> {
111113
match self[..] {
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-
}
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+
},
122131
_ => bug!("coroutine args missing synthetics"),
123132
}
124133
}

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,9 @@ 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())
916+
print(args.as_coroutine().return_ty()),
917+
" witness=",
918+
print(args.as_coroutine().witness())
917919
);
918920
}
919921

@@ -1033,7 +1035,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
10331035
" upvar_tys=",
10341036
print(args.as_coroutine_closure().tupled_upvars_ty()),
10351037
" coroutine_captures_by_ref_ty=",
1036-
print(args.as_coroutine_closure().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())
10371041
);
10381042
}
10391043
p!("}}");

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

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

78-
ty::Coroutine(def_id, args) => {
78+
ty::Coroutine(_, args) => {
7979
let coroutine_args = args.as_coroutine();
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-
]))
80+
Ok(ty::Binder::dummy(vec![coroutine_args.tupled_upvars_ty(), coroutine_args.witness()]))
8881
}
8982

9083
ty::CoroutineWitness(def_id, args) => Ok(ecx
@@ -252,14 +245,7 @@ where
252245
Movability::Movable => {
253246
if ecx.cx().features().coroutine_clone() {
254247
let coroutine = args.as_coroutine();
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-
]))
248+
Ok(ty::Binder::dummy(vec![coroutine.tupled_upvars_ty(), coroutine.witness()]))
263249
} else {
264250
Err(NoSolution)
265251
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1166,7 +1166,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11661166
if self.tcx().features().coroutine_clone() {
11671167
let resolved_upvars =
11681168
self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
1169-
if resolved_upvars.is_ty_var() {
1169+
let resolved_witness =
1170+
self.infcx.shallow_resolve(args.as_coroutine().witness());
1171+
if resolved_upvars.is_ty_var() || resolved_witness.is_ty_var() {
11701172
// Not yet resolved.
11711173
candidates.ambiguous = true;
11721174
} else {

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

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,11 +2196,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
21962196
args.as_coroutine()
21972197
.upvar_tys()
21982198
.iter()
2199-
.chain([Ty::new_coroutine_witness(
2200-
self.tcx(),
2201-
coroutine_def_id,
2202-
self.tcx().mk_args(args.as_coroutine().parent_args()),
2203-
)])
2199+
.chain([args.as_coroutine().witness()])
22042200
.collect::<Vec<_>>(),
22052201
)
22062202
} else {
@@ -2331,13 +2327,9 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
23312327
ty::Binder::dummy(AutoImplConstituents { types: vec![ty], assumptions: vec![] })
23322328
}
23332329

2334-
ty::Coroutine(def_id, args) => {
2330+
ty::Coroutine(_, args) => {
23352331
let ty = self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
2336-
let witness = Ty::new_coroutine_witness(
2337-
self.tcx(),
2338-
def_id,
2339-
self.tcx().mk_args(args.as_coroutine().parent_args()),
2340-
);
2332+
let witness = args.as_coroutine().witness();
23412333
ty::Binder::dummy(AutoImplConstituents {
23422334
types: [ty].into_iter().chain(iter::once(witness)).collect(),
23432335
assumptions: vec![],

compiler/rustc_type_ir/src/ty_kind/closure.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ use crate::{self as ty, Interner};
101101
/// `yield` inside the coroutine.
102102
/// * `GR`: The "return type", which is the type of value returned upon
103103
/// completion of the coroutine.
104+
/// * `GW`: The "coroutine witness".
104105
#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
105106
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
106107
pub struct ClosureArgs<I: Interner> {
@@ -238,6 +239,8 @@ pub struct CoroutineClosureArgsParts<I: Interner> {
238239
/// while the `tupled_upvars_ty`, representing the by-move version of the same
239240
/// captures, will be `(String,)`.
240241
pub coroutine_captures_by_ref_ty: I::Ty,
242+
/// Witness type returned by the generator produced by this coroutine-closure.
243+
pub coroutine_witness_ty: I::Ty,
241244
}
242245

243246
impl<I: Interner> CoroutineClosureArgs<I> {
@@ -248,6 +251,7 @@ impl<I: Interner> CoroutineClosureArgs<I> {
248251
parts.signature_parts_ty.into(),
249252
parts.tupled_upvars_ty.into(),
250253
parts.coroutine_captures_by_ref_ty.into(),
254+
parts.coroutine_witness_ty.into(),
251255
])),
252256
}
253257
}
@@ -288,6 +292,7 @@ impl<I: Interner> CoroutineClosureArgs<I> {
288292
}
289293

290294
pub fn coroutine_closure_sig(self) -> ty::Binder<I, CoroutineClosureSignature<I>> {
295+
let interior = self.coroutine_witness_ty();
291296
let ty::FnPtr(sig_tys, hdr) = self.signature_parts_ty().kind() else { panic!() };
292297
sig_tys.map_bound(|sig_tys| {
293298
let [resume_ty, tupled_inputs_ty] = *sig_tys.inputs().as_slice() else {
@@ -297,6 +302,7 @@ impl<I: Interner> CoroutineClosureArgs<I> {
297302
panic!()
298303
};
299304
CoroutineClosureSignature {
305+
interior,
300306
tupled_inputs_ty,
301307
resume_ty,
302308
yield_ty,
@@ -312,6 +318,10 @@ impl<I: Interner> CoroutineClosureArgs<I> {
312318
self.split().coroutine_captures_by_ref_ty
313319
}
314320

321+
pub fn coroutine_witness_ty(self) -> I::Ty {
322+
self.split().coroutine_witness_ty
323+
}
324+
315325
pub fn has_self_borrows(&self) -> bool {
316326
match self.coroutine_captures_by_ref_ty().kind() {
317327
ty::FnPtr(sig_tys, _) => sig_tys
@@ -351,6 +361,7 @@ impl<I: Interner> TypeVisitor<I> for HasRegionsBoundAt {
351361
#[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
352362
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
353363
pub struct CoroutineClosureSignature<I: Interner> {
364+
pub interior: I::Ty,
354365
pub tupled_inputs_ty: I::Ty,
355366
pub resume_ty: I::Ty,
356367
pub yield_ty: I::Ty,
@@ -396,6 +407,7 @@ impl<I: Interner> CoroutineClosureSignature<I> {
396407
resume_ty: self.resume_ty,
397408
yield_ty: self.yield_ty,
398409
return_ty: self.return_ty,
410+
witness: self.interior,
399411
tupled_upvars_ty,
400412
},
401413
);
@@ -575,6 +587,11 @@ pub struct CoroutineArgsParts<I: Interner> {
575587
pub yield_ty: I::Ty,
576588
pub return_ty: I::Ty,
577589

590+
/// The interior type of the coroutine.
591+
/// Represents all types that are stored in locals
592+
/// in the coroutine's body.
593+
pub witness: I::Ty,
594+
578595
/// The upvars captured by the closure. Remains an inference variable
579596
/// until the upvar analysis, which happens late in HIR typeck.
580597
pub tupled_upvars_ty: I::Ty,
@@ -590,6 +607,7 @@ impl<I: Interner> CoroutineArgs<I> {
590607
parts.resume_ty.into(),
591608
parts.yield_ty.into(),
592609
parts.return_ty.into(),
610+
parts.witness.into(),
593611
parts.tupled_upvars_ty.into(),
594612
])),
595613
}
@@ -611,6 +629,15 @@ impl<I: Interner> CoroutineArgs<I> {
611629
self.split().kind_ty
612630
}
613631

632+
/// This describes the types that can be contained in a coroutine.
633+
/// It will be a type variable initially and unified in the last stages of typeck of a body.
634+
/// It contains a tuple of all the types that could end up on a coroutine frame.
635+
/// The state transformation MIR pass may only produce layouts which mention types
636+
/// in this tuple. Upvars are not counted here.
637+
pub fn witness(self) -> I::Ty {
638+
self.split().witness
639+
}
640+
614641
/// Returns an iterator over the list of types of captured paths by the coroutine.
615642
/// In case there was a type error in figuring out the types of the captured path, an
616643
/// empty iterator is returned.

tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
std::future::ResumeTy,
1010
(),
1111
(),
12+
CoroutineWitness(
13+
DefId(0:5 ~ async_await[ccf8]::a::{closure#0}),
14+
[],
15+
),
1216
(),
1317
],
1418
),
@@ -26,6 +30,10 @@
2630
std::future::ResumeTy,
2731
(),
2832
(),
33+
CoroutineWitness(
34+
DefId(0:5 ~ async_await[ccf8]::a::{closure#0}),
35+
[],
36+
),
2937
(),
3038
],
3139
),

0 commit comments

Comments
 (0)