Description
With the current design of async functions, it doesn't seem to be able to call them recursively.
The most straightforward way:
async fn foo() -> u32 {
await!(foo()) + 1
}
fails apparently, because the size of the future type is indefinite, and thus the compiler complains:
error[E0275]: overflow evaluating the requirement `impl std::future::Future`
|
= help: consider adding a `#![recursion_limit="128"]` attribute to your crate
Another idea would be to put the recursive future into another heap-allocated object:
async fn foo() -> u32 {
let x = Box::new(foo());
await!(x) + 1
}
However this doesn't work either, because resolving the return type of foo
requires the return type of foo
, which forms a cycle dependency, and compiler complains:
error[E0391]: cycle detected when processing `foo`
--> src/main.rs:7:1
|
7 | async fn foo() -> u32 {
| ^^^^^^^^^^^^^^^^^^^^^
|
note: ...which requires evaluating trait selection obligation `std::boxed::Box<impl std::future::Future>: std::future::Future`...
note: ...which requires processing `foo::{{impl-Trait}}`...
If the type is a problem, maybe we can use trait object?
async fn foo() -> u32 {
let x: Box<dyn Future<Output = u32>> = Box::new(foo());
await!(x) + 1
}
But it still doesn't work, because Future
isn't object-safe due to the poll
method, which is correctly reported by the compiler:
error[E0038]: the trait `std::future::Future` cannot be made into an object
--> src/main.rs:10:12
|
10 | let x: Box<dyn Future<Output = u32>> = Box::new(foo());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::future::Future` cannot be made into an object
|
= note: method `poll` has a non-standard `self` type
So it seems that there is no way an async function can be called recursively.
I'm not sure how much problematic it would be, but it seems this limitation wasn't mentioned in the RFC nor any introduction of async, so maybe it's worth considering.
Recursion without additional allocation may be very challenging, but we should probably allow opt-in async recursion with some explicit cost.