Extending the lifetime of a temporary value: `let x = std::io::stdout().lock();`

Asking here because my expertise of Rust lifetimes is lacking.

// error[E0716]: temporary value dropped while borrowed
let x = std::io::stdout().lock();
        ^^^^^^^^^^^^^^^^^       - temporary value is freed at the end of this statement
        |
        creates a temporary which is freed while still in use

I'm designing a similar lock API and I was wondering if there is a nice way to work around this error at the API design level? Taking ownership with fn lock(stdout: Stdout) -> Locked { ... } works, but feels a bit restrictive by requiring a new Stdout handle for each lock. Something like the following would be perfect if it also supported the let x = std::io::stdout().lock(); usage:

fn lock(stdout: &mut Stdout) -> Locked<...> { ... }

This allows locking Stdout multiple times given that previous locks are dropped (unlocked) before calling .lock() again. However, a straightforward implementation without lifetime wizardry runs into the "temporary value dropped while borrowed" error when locking a temporary Stdout return value. Is it possible to extend the lifetime of a temporary value in this specific use case? In my opinion, an intuitive lifetime bound for the temporary Stdout in std::io::stdout().lock() is the lifetime of the return value of .lock().

Maybe I'm asking for too much. After all, it is just a minor nuisance and the compiler already suggests assigning the return value of std::io::stdout() to a variable, so it cannot hurt the users of the API too much. Nonetheless, I find it a bit ironic that std::io:stdout().lock().write(b"foobar"); compiles but let x = std::io::stdout().lock(); x.write(b"foobar"); does not.

You can simply split your code in two lines:

let stdout = std::io::stdout();
let x = stdout.lock();

This can appear to be weird at first, but the fact is the compiler needs to get the &mut Stdout reference from somewhere. If you simply chain std::io::stdout().lock(), the std::io::stdout() method creates a value that is dropped immediatly.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.