Skip to content

async block occupies twice the size of its captures (causing explosion in size). #108906

Open
@nolanderc

Description

@nolanderc

I tried this code (playground link) which wraps a future in a trivial async block:

let foo = async move { ... };
dbg!(std::mem::size_of_val(&foo));

let bar = async move { foo.await };
dbg!(std::mem::size_of_val(&bar));

I expected to see that size_of(bar) == size_of(foo) (plus some bytes for a tag). Instead, I found that size_of(bar) > 2 * size_of(foo).

I discovered this while nesting a couple of futures which largely had the following form:

let future = function_returning_future(...);
async move { 
    let result = future.await;
    let output = /* ...do something with result... */;
    output
}

The final future occupied a few kilobytes. I was able work around this by using a map combinator, but it is not ideal.

This could possibly be related to #62958, but I'm not familiar enough with the compiler internals to say with certainty if async-block captures are implemented the same way as async fn arguments.

Meta

This happens in stable 1.67.1, beta 1.70.0, and the latest nightly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.WG-asyncWorking group: Async & await

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions