Skip to content

Boxed recursive function should not require trait object #73625

Description

@jimblandy

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!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions