Skip to content

Commit

Permalink
Fix async closures in CTFE
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Feb 11, 2024
1 parent cb024ba commit 8781637
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 2 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_const_eval/src/interpret/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ where
match *ty.kind() {
ty::Param(_) => ControlFlow::Break(FoundParam),
ty::Closure(def_id, args)
| ty::CoroutineClosure(def_id, args, ..)
| ty::Coroutine(def_id, args, ..)
| ty::FnDef(def_id, args) => {
let instance = ty::InstanceDef::Item(def_id);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '

// Now we know we are projecting to a field, so figure out which one.
match layout.ty.kind() {
// coroutines and closures.
ty::Closure(def_id, _) | ty::Coroutine(def_id, _) => {
// coroutines, closures, and coroutine-closures all have upvars that may be named.
ty::Closure(def_id, _) | ty::Coroutine(def_id, _) | ty::CoroutineClosure(def_id, _) => {
let mut name = None;
// FIXME this should be more descriptive i.e. CapturePlace instead of CapturedVar
// https://github.com/rust-lang/project-rfc-2229/issues/46
Expand Down
40 changes: 40 additions & 0 deletions src/tools/miri/tests/pass/async-closure.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#![feature(async_closure, noop_waker, async_fn_traits)]

use std::future::Future;
use std::pin::pin;
use std::task::*;

pub fn block_on<T>(fut: impl Future<Output = T>) -> T {
let mut fut = pin!(fut);
let ctx = &mut Context::from_waker(Waker::noop());

loop {
match fut.as_mut().poll(ctx) {
Poll::Pending => {}
Poll::Ready(t) => break t,
}
}
}

async fn call_once(f: impl async FnOnce(DropMe)) {
f(DropMe("world")).await;
}

#[derive(Debug)]
struct DropMe(&'static str);

impl Drop for DropMe {
fn drop(&mut self) {
println!("{}", self.0);
}
}

pub fn main() {
block_on(async {
let b = DropMe("hello");
let async_closure = async move |a: DropMe| {
println!("{a:?} {b:?}");
};
call_once(async_closure).await;
});
}
3 changes: 3 additions & 0 deletions src/tools/miri/tests/pass/async-closure.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
DropMe("world") DropMe("hello")
world
hello

0 comments on commit 8781637

Please sign in to comment.