Consider the following code:
async fn foo() {
let mut x = get_future();
dbg!(std::mem::size_of_val(&x));
x.await
}
Today, having the dbg! line roughly doubles the size of the future returned by foo. More precisely, it causes us to allocate storage for x twice (once for x, and once for the pinned variable that x is moved into inside the await).
This unfortunate state of events is caused by the fact that we cannot "peer into" size_of_val and see that the address of x never escapes the function. Without knowing this, we can't optimize away the storage of x once it has been moved.
This was first discussed here: #59123 (comment). One promising solution (suggested by @RalfJung) is that we inline all occurrences of size_of_val (and possibly some other intrinsics) in a MIR pass, before we get to the generator transform.
Consider the following code:
Today, having the
dbg!line roughly doubles the size of the future returned byfoo. More precisely, it causes us to allocate storage forxtwice (once forx, and once for thepinnedvariable thatxis moved into inside theawait).This unfortunate state of events is caused by the fact that we cannot "peer into"
size_of_valand see that the address ofxnever escapes the function. Without knowing this, we can't optimize away the storage ofxonce it has been moved.This was first discussed here: #59123 (comment). One promising solution (suggested by @RalfJung) is that we inline all occurrences of
size_of_val(and possibly some other intrinsics) in a MIR pass, before we get to the generator transform.