MutexGuard lifetime when I have a reference to the content

So I am struggling what exactly is going on with this code:

fn main() {
    let mutex = Arc::new(Mutex::new(()));
    let _a = &*mutex.lock().unwrap();
    let _b = &*mutex.lock().unwrap();
}

This compiles without an error and then deadlocks, so obviously the MutexGuard is held until the end of the function. But _a and _b both have the type &().

Why does Rust not complain that the temporary gets dropped in this case?

Temporary lifetime extension -- the lock's drop scopes are extended to the end of main as if they were local variables.

1 Like

Thanks that helps a lot!

When I do it like this it does not work and Rust complains about a dropped temporary:

    let a = mutex.lock().unwrap().deref();
    foo(a);

Am I understanding it correctly, that this is basically the same operation, but Rust views this as a function call where the lifetime is not extended. Only when using the operator, Rust will extend?

It's any of the cases spelled out on that page... i.e. somewhat complex. It's the roundtrip through deref that breaks the extension ala the (&temp).use_temp() and Some(&mut 0) examples as far as I understand.

IMO you should use blocks or put your locks into variables you explicitly drop to make things more clear, when it matters.

1 Like

OK thanks a lot :blush:

Yes, being explicit sounds reasonable. Especially in case of a mutex, an implicit lifetime extension of the guard is just not that great.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.