Skip to content

Commit b0597b4

Browse files
authored
Rollup merge of #134295 - compiler-errors:smir-async-closure, r=oli-obk
Encode coroutine-closures in SMIR Fixes #134246 r? oli-obk
2 parents 752f79a + 91e74ed commit b0597b4

File tree

9 files changed

+137
-4
lines changed

9 files changed

+137
-4
lines changed

Diff for: compiler/rustc_smir/src/rustc_internal/internal.rs

+4
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ impl RustcInternal for RigidTy {
141141
RigidTy::Coroutine(def, args, _mov) => {
142142
rustc_ty::TyKind::Coroutine(def.0.internal(tables, tcx), args.internal(tables, tcx))
143143
}
144+
RigidTy::CoroutineClosure(def, args) => rustc_ty::TyKind::CoroutineClosure(
145+
def.0.internal(tables, tcx),
146+
args.internal(tables, tcx),
147+
),
144148
RigidTy::CoroutineWitness(def, args) => rustc_ty::TyKind::CoroutineWitness(
145149
def.0.internal(tables, tcx),
146150
args.internal(tables, tcx),

Diff for: compiler/rustc_smir/src/rustc_internal/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ impl<'tcx> Tables<'tcx> {
107107
stable_mir::ty::CoroutineDef(self.create_def_id(did))
108108
}
109109

110+
pub fn coroutine_closure_def(&mut self, did: DefId) -> stable_mir::ty::CoroutineClosureDef {
111+
stable_mir::ty::CoroutineClosureDef(self.create_def_id(did))
112+
}
113+
110114
pub fn alias_def(&mut self, did: DefId) -> stable_mir::ty::AliasDef {
111115
stable_mir::ty::AliasDef(self.create_def_id(did))
112116
}

Diff for: compiler/rustc_smir/src/rustc_smir/convert/mir.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -565,8 +565,11 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
565565
tables.tcx.coroutine_movability(*def_id).stable(tables),
566566
)
567567
}
568-
mir::AggregateKind::CoroutineClosure(..) => {
569-
todo!("FIXME(async_closures): Lower these to SMIR")
568+
mir::AggregateKind::CoroutineClosure(def_id, generic_args) => {
569+
stable_mir::mir::AggregateKind::CoroutineClosure(
570+
tables.coroutine_closure_def(*def_id),
571+
generic_args.stable(tables),
572+
)
570573
}
571574
mir::AggregateKind::RawPtr(ty, mutability) => {
572575
stable_mir::mir::AggregateKind::RawPtr(ty.stable(tables), mutability.stable(tables))

Diff for: compiler/stable_mir/src/mir/body.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use serde::Serialize;
55
use crate::compiler_interface::with;
66
use crate::mir::pretty::function_body;
77
use crate::ty::{
8-
AdtDef, ClosureDef, CoroutineDef, GenericArgs, MirConst, Movability, Region, RigidTy, Ty,
9-
TyConst, TyKind, VariantIdx,
8+
AdtDef, ClosureDef, CoroutineClosureDef, CoroutineDef, GenericArgs, MirConst, Movability,
9+
Region, RigidTy, Ty, TyConst, TyKind, VariantIdx,
1010
};
1111
use crate::{Error, Opaque, Span, Symbol};
1212

@@ -617,6 +617,9 @@ impl Rvalue {
617617
AggregateKind::Coroutine(def, ref args, mov) => {
618618
Ok(Ty::new_coroutine(def, args.clone(), mov))
619619
}
620+
AggregateKind::CoroutineClosure(def, ref args) => {
621+
Ok(Ty::new_coroutine_closure(def, args.clone()))
622+
}
620623
AggregateKind::RawPtr(ty, mutability) => Ok(Ty::new_ptr(ty, mutability)),
621624
},
622625
Rvalue::ShallowInitBox(_, ty) => Ok(Ty::new_box(*ty)),
@@ -633,6 +636,7 @@ pub enum AggregateKind {
633636
Closure(ClosureDef, GenericArgs),
634637
// FIXME(stable_mir): Movability here is redundant
635638
Coroutine(CoroutineDef, GenericArgs, Movability),
639+
CoroutineClosure(CoroutineClosureDef, GenericArgs),
636640
RawPtr(Ty, Mutability),
637641
}
638642

Diff for: compiler/stable_mir/src/mir/pretty.rs

+4
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,10 @@ fn pretty_aggregate<W: Write>(
410410
write!(writer, "{{coroutine@{}}}(", def.span().diagnostic())?;
411411
")"
412412
}
413+
AggregateKind::CoroutineClosure(def, _) => {
414+
write!(writer, "{{coroutine-closure@{}}}(", def.span().diagnostic())?;
415+
")"
416+
}
413417
AggregateKind::RawPtr(ty, mutability) => {
414418
write!(
415419
writer,

Diff for: compiler/stable_mir/src/ty.rs

+11
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ impl Ty {
6363
Ty::from_rigid_kind(RigidTy::Coroutine(def, args, mov))
6464
}
6565

66+
/// Create a new closure type.
67+
pub fn new_coroutine_closure(def: CoroutineClosureDef, args: GenericArgs) -> Ty {
68+
Ty::from_rigid_kind(RigidTy::CoroutineClosure(def, args))
69+
}
70+
6671
/// Create a new box type that represents `Box<T>`, for the given inner type `T`.
6772
pub fn new_box(inner_ty: Ty) -> Ty {
6873
with(|cx| cx.new_box_ty(inner_ty))
@@ -550,6 +555,7 @@ pub enum RigidTy {
550555
Closure(ClosureDef, GenericArgs),
551556
// FIXME(stable_mir): Movability here is redundant
552557
Coroutine(CoroutineDef, GenericArgs, Movability),
558+
CoroutineClosure(CoroutineClosureDef, GenericArgs),
553559
Dynamic(Vec<Binder<ExistentialPredicate>>, Region, DynKind),
554560
Never,
555561
Tuple(Vec<Ty>),
@@ -740,6 +746,11 @@ crate_def! {
740746
pub CoroutineDef;
741747
}
742748

749+
crate_def! {
750+
#[derive(Serialize)]
751+
pub CoroutineClosureDef;
752+
}
753+
743754
crate_def! {
744755
#[derive(Serialize)]
745756
pub ParamDef;

Diff for: compiler/stable_mir/src/visitor.rs

+1
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ impl Visitable for RigidTy {
168168
| RigidTy::Closure(_, args)
169169
| RigidTy::Coroutine(_, args, _)
170170
| RigidTy::CoroutineWitness(_, args)
171+
| RigidTy::CoroutineClosure(_, args)
171172
| RigidTy::FnDef(_, args) => args.visit(visitor),
172173
RigidTy::FnPtr(sig) => sig.visit(visitor),
173174
RigidTy::Dynamic(pred, r, _) => {

Diff for: tests/ui/stable-mir-print/async-closure.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ compile-flags: -Z unpretty=stable-mir --crate-type lib -C panic=abort
2+
//@ check-pass
3+
//@ only-x86_64
4+
//@ edition: 2024
5+
//@ needs-unwind unwind edges are different with panic=abort
6+
7+
pub fn foo() {
8+
let y = 0;
9+
let x = async || {
10+
let y = y;
11+
};
12+
}

Diff for: tests/ui/stable-mir-print/async-closure.stdout

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// WARNING: This is highly experimental output it's intended for stable-mir developers only.
2+
// If you find a bug or want to improve the output open a issue at https://github.com/rust-lang/project-stable-mir.
3+
fn foo() -> () {
4+
let mut _0: ();
5+
let _1: i32;
6+
let _2: {async closure@$DIR/async-closure.rs:9:13: 9:21};
7+
let mut _3: &i32;
8+
debug y => _1;
9+
debug x => _2;
10+
bb0: {
11+
_1 = 0_i32;
12+
_3 = &_1;
13+
_2 = {coroutine-closure@$DIR/async-closure.rs:9:13: 9:21}(move _3);
14+
return;
15+
}
16+
}
17+
fn foo::{closure#0}(_1: &{async closure@$DIR/async-closure.rs:9:13: 9:21}) -> {async closure body@$DIR/async-closure.rs:9:22: 11:6} {
18+
let mut _0: {async closure body@$DIR/async-closure.rs:9:22: 11:6};
19+
let mut _2: &i32;
20+
debug y => (*((*_1).0: &i32));
21+
bb0: {
22+
_2 = CopyForDeref(((*_1).0: &i32));
23+
_0 = {coroutine@$DIR/async-closure.rs:9:22: 11:6}(_2);
24+
return;
25+
}
26+
}
27+
fn foo::{closure#0}::{closure#0}(_1: Pin<&mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}>, _2: &mut Context<'_>) -> Poll<()> {
28+
let mut _0: Poll<()>;
29+
let _3: i32;
30+
let mut _4: &i32;
31+
let mut _5: u32;
32+
let mut _6: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
33+
let mut _7: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
34+
let mut _8: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
35+
debug _task_context => _2;
36+
debug y => (*((*(_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})).0: &i32));
37+
debug y => _3;
38+
bb0: {
39+
_6 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
40+
_5 = discriminant((*_6));
41+
switchInt(move _5) -> [0: bb1, 1: bb2, otherwise: bb3];
42+
}
43+
bb1: {
44+
_7 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
45+
_4 = CopyForDeref(((*_7).0: &i32));
46+
_3 = (*_4);
47+
_0 = std::task::Poll::Ready(());
48+
_8 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
49+
discriminant((*_8) = 1;
50+
return;
51+
}
52+
bb2: {
53+
assert(false, `async fn` resumed after completion) -> [success: bb2, unwind unreachable];
54+
}
55+
bb3: {
56+
unreachable;
57+
}
58+
}
59+
fn foo::{closure#0}::{closure#1}(_1: Pin<&mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}>, _2: &mut Context<'_>) -> Poll<()> {
60+
let mut _0: Poll<()>;
61+
let _3: i32;
62+
let mut _4: &i32;
63+
let mut _5: u32;
64+
let mut _6: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
65+
let mut _7: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
66+
let mut _8: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6};
67+
debug _task_context => _2;
68+
debug y => (*((*(_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6})).0: &i32));
69+
debug y => _3;
70+
bb0: {
71+
_6 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
72+
_5 = discriminant((*_6));
73+
switchInt(move _5) -> [0: bb1, 1: bb2, otherwise: bb3];
74+
}
75+
bb1: {
76+
_7 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
77+
_4 = CopyForDeref(((*_7).0: &i32));
78+
_3 = (*_4);
79+
_0 = std::task::Poll::Ready(());
80+
_8 = CopyForDeref((_1.0: &mut {async closure body@$DIR/async-closure.rs:9:22: 11:6}));
81+
discriminant((*_8) = 1;
82+
return;
83+
}
84+
bb2: {
85+
assert(false, `async fn` resumed after completion) -> [success: bb2, unwind unreachable];
86+
}
87+
bb3: {
88+
unreachable;
89+
}
90+
}

0 commit comments

Comments
 (0)