Reputation: 1278
In my understanding gaining a lock on a mutex and then immediately calling a function on the guarded structure without declaring a separate variable for the MutexGuard releases this guard once the function call is done.
My question is whether this is also the case when getting a lock within a loop declaration like so:
for ele in mtx.lock().await.clone() {
// do something requiring lock on mtx
}
The expectation here would be that once the clone
call completes, the lock on mtx is released and can be reacquired inside the loop. Is this the case? If not, why is this not the case?
Upvotes: 4
Views: 1054
Reputation: 601391
No, this is not the case. Temporaries created in the iterator expression will live until the end of the for loop, and the mutex guard will only be dropped after the loop.
Temporaries are generally dropped at the end of the statement. You can see the full rules in the documentation on temporary scopes:
Apart from lifetime extension, the temporary scope of an expression is the smallest scope that contains the expression and is one of the following:
- The entire function body.
- A statement.
- The body of a
if
,while
orloop
expression.- The
else
block of anif
expression.- The condition expression of an
if
orwhile
expression, or amatch
guard.- The expression for a match arm.
- The second operand of a lazy boolean expression.
These rules cover a lot of subtle corner cases, so it's not easy to give a short summary why the language is designed this way. For for loops in particular, it would be very annoying if temporaries created inside the iterator expression would get immediately dropped, since then things like this would cause a borrow checker error:
for x in my_vec.iter().filter(|&&y| y != 0) {
...
}
If the compiler would only keep the result of the iterator expression, the iterator returned by my_vec.iter()
would be immediately dropped, which of course isn't desired.
Upvotes: 6