Skip to content

rebinding values in an async function can double the memory usage #96084

Description

@jkarneges

Rebinding a value within an async function can cause the generated future to require twice the memory for the value. This seems to only happen if the value was borrowed earlier:

use std::mem;

async fn foo() {
    let x = [0u8; 100];
    async {}.await;
    println!("{}", x.len());
}

async fn a() {
    let fut = foo();
    let fut = fut;
    fut.await;
}

async fn b() {
    let fut = foo();
    println!("{}", mem::size_of_val(&fut));
    let fut = fut;
    fut.await;
}

fn main() {
    assert_eq!(mem::size_of_val(&foo()), 102);

    // 1 + sizeof(foo)
    assert_eq!(mem::size_of_val(&a()), 103);

    // 1 + (sizeof(foo) * 2)
    assert_eq!(mem::size_of_val(&b()), 205);
}

Playground link.

I don't know if this counts as a bug but the behavior is a bit surprising.

The effect is present in both debug and release modes with rustc 1.60.0.

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-PolishAsync-await issues that are part of the "polish" areaAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-bugCategory: This is a bug.I-heavyIssue: Problems and improvements with respect to binary size of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions