Skip to content

Commit 8781637

Browse files
Fix async closures in CTFE
1 parent cb024ba commit 8781637

File tree

4 files changed

+46
-2
lines changed

4 files changed

+46
-2
lines changed

compiler/rustc_const_eval/src/interpret/util.rs

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ where
3434
match *ty.kind() {
3535
ty::Param(_) => ControlFlow::Break(FoundParam),
3636
ty::Closure(def_id, args)
37+
| ty::CoroutineClosure(def_id, args, ..)
3738
| ty::Coroutine(def_id, args, ..)
3839
| ty::FnDef(def_id, args) => {
3940
let instance = ty::InstanceDef::Item(def_id);

compiler/rustc_const_eval/src/interpret/validity.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
236236

237237
// Now we know we are projecting to a field, so figure out which one.
238238
match layout.ty.kind() {
239-
// coroutines and closures.
240-
ty::Closure(def_id, _) | ty::Coroutine(def_id, _) => {
239+
// coroutines, closures, and coroutine-closures all have upvars that may be named.
240+
ty::Closure(def_id, _) | ty::Coroutine(def_id, _) | ty::CoroutineClosure(def_id, _) => {
241241
let mut name = None;
242242
// FIXME this should be more descriptive i.e. CapturePlace instead of CapturedVar
243243
// https://github.com/rust-lang/project-rfc-2229/issues/46
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#![feature(async_closure, noop_waker, async_fn_traits)]
2+
3+
use std::future::Future;
4+
use std::pin::pin;
5+
use std::task::*;
6+
7+
pub fn block_on<T>(fut: impl Future<Output = T>) -> T {
8+
let mut fut = pin!(fut);
9+
let ctx = &mut Context::from_waker(Waker::noop());
10+
11+
loop {
12+
match fut.as_mut().poll(ctx) {
13+
Poll::Pending => {}
14+
Poll::Ready(t) => break t,
15+
}
16+
}
17+
}
18+
19+
async fn call_once(f: impl async FnOnce(DropMe)) {
20+
f(DropMe("world")).await;
21+
}
22+
23+
#[derive(Debug)]
24+
struct DropMe(&'static str);
25+
26+
impl Drop for DropMe {
27+
fn drop(&mut self) {
28+
println!("{}", self.0);
29+
}
30+
}
31+
32+
pub fn main() {
33+
block_on(async {
34+
let b = DropMe("hello");
35+
let async_closure = async move |a: DropMe| {
36+
println!("{a:?} {b:?}");
37+
};
38+
call_once(async_closure).await;
39+
});
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
DropMe("world") DropMe("hello")
2+
world
3+
hello

0 commit comments

Comments
 (0)