Skip to content

Commit 0039eee

Browse files
committed
Auto merge of rust-lang#120361 - compiler-errors:async-closures, r=oli-obk
Rework support for async closures; allow them to return futures that borrow from the closure's captures This PR implements a new lowering for async closures via `TyKind::CoroutineClosure` which handles the curious relationship between the closure and the coroutine that it returns. I wrote up a bunch in [this hackmd](https://hackmd.io/`@compiler-errors/S1HvqQxca)` which will be copied to the dev guide after this PR lands, and hopefully left sufficient comments in the source code explaining why this change is as large as it is. This also necessitates that they begin implementing the `AsyncFn`-family of traits, rather than the `Fn`-family of traits -- if you need `Fn` implementations, you should probably use the non-sugar `|| async {}` syntax instead. Notably this PR does not yet implement `async Fn()` syntax sugar for bounds, but I expect to add those soon (**edit:** rust-lang#120392). For now, users must use `AsyncFn()` traits directly, which necessitates adding the `async_fn_traits` feature gate as well. I will add this as a follow-up very soon. r? oli-obk This is based on top of rust-lang#120322, but that PR is minimal.
2 parents 26abc53 + 04ebdf5 commit 0039eee

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

core/src/ops/async_function.rs

+25
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,28 @@ mod impls {
106106
}
107107
}
108108
}
109+
110+
mod internal_implementation_detail {
111+
/// A helper trait that is used to enforce that the `ClosureKind` of a goal
112+
/// is within the capabilities of a `CoroutineClosure`, and which allows us
113+
/// to delay the projection of the tupled upvar types until after upvar
114+
/// analysis is complete.
115+
///
116+
/// The `Self` type is expected to be the `kind_ty` of the coroutine-closure,
117+
/// and thus either `?0` or `i8`/`i16`/`i32` (see docs for `ClosureKind`
118+
/// for an explanation of that). The `GoalKind` is also the same type, but
119+
/// representing the kind of the trait that the closure is being called with.
120+
#[cfg_attr(not(bootstrap), lang = "async_fn_kind_helper")]
121+
trait AsyncFnKindHelper<GoalKind> {
122+
// Projects a set of closure inputs (arguments), a region, and a set of upvars
123+
// (by move and by ref) to the upvars that we expect the coroutine to have
124+
// according to the `GoalKind` parameter above.
125+
//
126+
// The `Upvars` parameter should be the upvars of the parent coroutine-closure,
127+
// and the `BorrowedUpvarsAsFnPtr` will be a function pointer that has the shape
128+
// `for<'env> fn() -> (&'env T, ...)`. This allows us to represent the binder
129+
// of the closure's self-capture, and these upvar types will be instantiated with
130+
// the `'closure_env` region provided to the associated type.
131+
type Upvars<'closure_env, Inputs, Upvars, BorrowedUpvarsAsFnPtr>;
132+
}
133+
}

0 commit comments

Comments
 (0)