Rust has exciting feature as async/.await !!
But this feature also have issue: recursion !!
Consider the following example:
async fn recursive() {
recursive().await;
recursive().await;
}
This code even does not compile ... To fix it we should do recursion in such way:
use futures::future::{BoxFuture, FutureExt};
fn recursive() -> BoxFuture<'static, ()> {
async move {
recursive().await;
recursive().await;
}.boxed()
}
But what if you want .await on something inside of recursive also ?? It is not possible ... (
It happens, because internally compiler generates the following code for async:
async step_one() -> u8 {
1u8
}
async step_third() -> u32 {
1u32
}
// This function:
async fn foo() {
step_one().await;
step_two().await;
}
// generates a type like this:
enum Foo {
First(u8),
Second(u32),
}
// So this function:
async fn recursive() {
recursive().await;
recursive().await;
}
// generates a type like this:
enum Recursive {
First(Recursive),
Second(Recursive),
}
Recursive enum depends on itself !! But what if compiler will generate the following enumeration for recursion function:
async step_one() -> u8 {
1u8
}
async step_third() -> u32 {
1u32
}
// So this function:
async fn recursive() {
step_one().await;
recursive().await;
step_third().await;
recursive().await;
}
// generates types like this:
enum RecursiveHelper {
First(u8),
Third(u32),
}
enum Recursive {
First(u8),
SecondSelfCall(RecursiveHelper),
Third(u32),
FourthSelfCall(RecursiveHelper),
}
This solution will allow such code to compile:
async fn recursive() {
recursive().await;
recursive().await;
}
Also take a look at discussion https://users.rust-lang.org/t/tokio-reccursion-error/41750/29