Boxable async fn
Impact
- Able to easily cause some async functions, blocks, or closures to allocate their stack space lazilly when called (by 'boxing' it)
- Combined with profiler or other tooling support, this can help to tune the size of futures
- Boxed async blocks allows particular portions of a function to be boxed, e.g. cold paths
Milestones
| Milestone | State | Key participants |
|---|---|---|
| Author evaluation doc | 💤 | |
| Feature complete implementation | 💤 |
Design notes
Example might be to use a decorator:
#![allow(unused)] fn main() { #[boxed] async fn foo() { } }
This does not have to desugar to -> Box<dyn Future<...>>; it can instead desugar to Box<impl Future>, or perhaps a nominal type to permit recursion.
Another approach is the box keyword:
#![allow(unused)] fn main() { box async fn foo() { } }
We can apply the keyword modifier to async blocks and closures:
#![allow(unused)] fn main() { fn foo() -> BoxFuture<Output = ()> { box async { ... } } }
#![allow(unused)] fn main() { async fn stuff(s: impl AsyncIterator) { s.map(box async |x| { ... }) } }
This is useful for breaking up future types to make them more shallow.