Skip to content

False-positive "temporary dropped while borrowed" involving return-position impl Trait #98997

Closed
@abonander

Description

@abonander

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions