When is it dropped?

If I wanted to rewrite the following:

  let cmap = self.cmap.lock();
  let cids: Vec<ArcId> = cmap
    .iter()
    .filter_map(|(cid, cdata)| (cdata.lid == lid).then_some(cid.clone()))
    .collect();
  drop(cmap);

.. into the following, when would the MutexGuard be dropped?

  let cids: Vec<ArcId> = self
    .cmap
    .lock()
    .iter()
    .filter_map(|(cid, cdata)| (cdata.lid == lid).then_some(cid.clone()))
    .collect();

Would it be dropped after the collect(), or would it live until the end of its regular scope? How should one reason? Is there some magical hidden scope being introduced by the compiler?

The guard becomes a temporary in your second expression and is dropped at the end of the statement, meaning after collect();.

4 Likes

I noticed an unexpected side-effect of this (at least, it was unexpected to me). The compiler warns about a variable not needing to be mutable. I'm getting these kinds of things:

1  warning: variable does not need to be mutable
    --> src/lib.rs:302:11
     |
 302 |       let cids: Vec<ArcId> = self
     |           ----^^^^
     |           |
     |           help: remove this `mut`
     |
     = note: `#[warn(unused_mut)]` on by default

There's clearly no mut where it thinks I should remove it.

Is this a glitch relating to temporaries?

Edit: Interesting; when I reverted the code to separate the lock, iteration and drop, I still got the warning(!). I ran cargo clean and rebuilt and the warning is gone. Feels .. unintended. :slight_smile:

Yes, my guess would've been that this is an unrelated buggy warning. At least I couldn't reproduce it with a minimal example using a MutexGuard to iterate over a vector. Haven't seen this before, might be interesting for the compiler engineers if you could create an MRE for this. There might already be an issue for this though, I haven't looked.

1 Like

(I meant to say that the warning is gone after the cargo clean).

I'll try to see if I can reproduce this.

1 Like

That's most likely going to be terribly hard to reproduce :sweat_smile:

You're not kidding -- now I can't even get the phantom mut warning by going back to the code I originally wanted.

Not gonna lie; I'm a little confused. I'm just going to pretend that all warnings before the cargo clean never happened. :slight_smile:

Haha, usually what I do as well when cleaning the build cache made the error/warning go away.

2 Likes

Are you using an IDE? Those produce all sorts of bogus crap out of nowhere all the time. (Thankfully, they also sometimes hide diagnostics which are actually useful, so the balance is maintained.)

No IDE; in fact, I probably have one of the more spartan configurations in the rust community. No IDE, no rust-analyzer. Just a plain vim or gvim (where syntax highlighting is the most bling feature I use) and running cargo manually from the command line.

I have ended up in a state where cargo/the compiler is confused before, requiring a cargo clean to make it stop, but it is very rare -- like once every two years or so, which is why I don't immediately catch it when it happens.

Hm.. I should probably zip the build directory up next time I suspect that it is happening.

3 Likes