Async fn doubles argument size · Issue #62958 · rust-lang/rust (original) (raw)

Generator optimization in #60187 by @tmandry reused generator locals, but arguments are still duplicated whenever used across yield points.

For example (playground):

#![feature(async_await)]

async fn wait() {}

async fn test(arg: [u8; 8192]) { wait().await; drop(arg); }

fn main() { println!("{}", std::mem::size_of_val(&test([0; 8192]))); }

Expected: 8200
Actual: 16392

When passing in futures, the future size can grow exponentially (playground):

#![feature(async_await)]

async fn test(_arg: [u8; 8192]) {}

async fn use_future(fut: impl std::future::Future<Output = ()>) { fut.await }

fn main() { println!( "{}", std::mem::size_of_val(&use_future(use_future(use_future(use_future(use_future( use_future(use_future(use_future(use_future(use_future(test( [0; 8192] )))))) )))))) ); }

Expected: 8236
Actual: 8396796

I didn't find any note on this. But given how common arguments are used, I think it might be useful if they are included in the optimization.