Description
I'm getting a "temporary value dropped while borrowed" error from code that I otherwise would expect to compile:
use std::fmt::Display;
use std::future::Future;
fn takes_display(d: impl Display) -> impl Future<Output = ()> + 'static {
let s = format!("{}", d);
async move {
()
}
}
async fn calls_takes_display() {
let bar = 0i32;
let fut = takes_display(format_args!("{bar}"));
// fut.await;
}
error[E0716]: temporary value dropped while borrowed
--> src/lib.rs:14:29
|
14 | let fut = takes_display(format_args!("{bar}"));
| ^^^^^^^^^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
| |
| creates a temporary which is freed while still in use
15 | // fut.await;
16 | }
| - borrow might be used here, when `fut` is dropped and runs the destructor for type `impl Future<Output = ()>`
|
= note: consider using a `let` binding to create a longer lived value
= note: this error originates in the macro `format_args` (in Nightly builds, run with -Z macro-backtrace for more info)
For more information about this error, try `rustc --explain E0716`.
error: could not compile `playground` due to previous error
This is a revised version of my original attempt, which fails due to #64477 (comment) (Playground link). After reading through the discussions, I understand why that version doesn't work.
However, I expected the revised version above to work because takes_display()
should be eagerly evaluated, and thus not hold any temporaries longer than necessary. It may be an overly eager application of the deferred drop rules as .await
is not even involved here, the future returned from takes_display()
is explicitly not lifetime-bound to the input, and the return value is bound in a let
statement and is not in return position.
Meta
rustc --version --verbose
:
rustc 1.62.0 (a8314ef7d 2022-06-27)