Closed
Description
The following code works (playground):
use std::future::Future;
use std::pin::Pin;
async fn recurse(i: usize) {
if i == 0 {
println!("Zero!");
return;
}
println!("entering {}", i);
let recursed = Box::pin(recurse(i-1)) as Pin<Box<dyn Future<Output=()>>>;
recursed.await;
println!("exiting {}", i);
}
fn main() {
futures::executor::block_on(recurse(10));
}
but if the trait object is removed, and the construction of recursed
is changed to:
let recursed = Box::pin(recurse(i-1));
then Rust rejects the program:
error[E0733]: recursion in an `async fn` requires boxing
--> src/main.rs:4:28
|
4 | async fn recurse(i: usize) {
| ^ recursive `async fn`
|
= note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
The future is boxed either way, so the use of a trait object shouldn't be required. In a thread on the internals forum, @withoutboats said:
Note that it should be allowed to just use Box::pin, without casting it into a trait object at all, and the fact that it isn't is an implementation limitation of how current rustc calculates the layout of the future type. It doesn't look like there's a bug tracking this limitation though.
Now there is!