Skip to content

Temporary values do not outlive a direct await #63778

Description

@Marwes
struct Test(String);

impl Test {
    async fn borrow_async(&self) {}

    fn borrow(&self) {}

    fn with(&mut self, s: &str) -> &mut Self {
        self.0 = s.into();
        self
    }
}

async fn test() {
    // error[E0716]: temporary value dropped while borrowed
    Test("".to_string()).with("123").borrow_async().await;
}

fn main() {
    // Temporary outlives the borrow() call
    Test("".to_string()).with("123").borrow();
}

https://play.rust-lang.org/?version=nightly&mode=release&edition=2018&gist=2649e4f172c54090d759b2f9484b31e1

A fairly common pattern is to use builder functions that takes &mut self and returns &mut Self so that multiple builder methods can be used in a row followed by building/using the final value. With normal, sync functions this works fine since the created temporary lives as long as the enclosing statement but if the final result is awaited on then we instead get an error.

This forces such builders to use moving functions fn (self) -> Self which can limit their use or to always write the builder as

let mut init = Init();
init.modify();
init.build();

Is it possible and/or planned that temporaries can be used in this way with await?

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-async-awaitArea: Async & AwaitA-lifetimesArea: Lifetimes / regionsT-langRelevant to the language team

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions