Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Temporary values do not outlive a direct await #63778

Closed
Marwes opened this issue Aug 21, 2019 · 4 comments

Comments

@Marwes
Copy link
Contributor

commented Aug 21, 2019

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?

@Centril

This comment has been minimized.

Copy link
Member

commented Aug 21, 2019

@Marwes

This comment has been minimized.

Copy link
Contributor Author

commented Aug 22, 2019

Going with a moving API over &mut only helps if the value is also moved into future

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

For redis, where I encountered this it is possible to avoid capturing &self in the future by avoiding async fn but I may want to change the API in a way that &self needs to be captured. Such an API would only be ergonomic if await were changed in the manner described however.

Changing it would at least change the drop order for temporaries so this might be a stability hazard (maybe not since it doesn't compile?).

@Centril

This comment has been minimized.

Copy link
Member

commented Aug 25, 2019

This seems like the same issue as #63832?

@nikomatsakis

This comment has been minimized.

Copy link
Contributor

commented Aug 27, 2019

Closing as a duplicate of #63832, I'll move the example over there though to be sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.