Cannot Borrow `self.*` as Mutable because It is also Borrowed as Immutable

I have an error that I cannot really make up what it really means. Firstly, this is the branch where the error persists.

The error is exactly at this line, saying:

cannot borrow `self.auths` as mutable because it is also borrowed as immutable

mutable borrow occurs hererustc(E0502)
auth.rs(306, 26): immutable borrow occurs here
auth.rs(332, 12): mutable borrow occurs here
auth.rs(336, 30): immutable borrow later used here

I seem to not be able to understand some concepts here. It's been, what, a year or so since I've been learning this language and the compiler still finds a way to fight back. I borrow self and as mutable at that, you see at this line (or below):

fn delete(&mut self, name: &str) -> Result<(), AuthError>
// &mut  self

However, it seems the properties of a struct also has mutability/immutability. It says I immutably borrowed self.auths in the method, which I'm not aware of, and I did a mutable operation on it, using remove method on HashSet.

Isn't properties of self if mutable as well when we refer it as &mut self? What do I miss here?

Thanks in advance.


Environment

  • rust 1.42.0

Changing line 309 to a.clone() ought to do it. You're holding a reference to the contents of self.auths, which means you can't mutate self.auths.

1 Like

A mutable reference must have exclusive access to the value it is borrowing; no other references to any part of that value can be alive at the same time. Holding a reference to any part of a struct effectively "locks" that struct; this is how Rust's memory safety works.

In this case auth is a reference into self.auths, so you can't mutate self.auths while this reference is alive. Doing so could cause the contents of self.auths to move or even be destroyed, which would make auth into a dangling pointer!

The simplest solution is to have the auth and path variables store copies of the data from the HashMap and HashSet, rather than references. Use .clone() to get a new copy that isn't borrowed from the container. You'll probably also need to change the paths field to store its keys by value, not by reference.

1 Like

Hmm... Thinking about your and @droundy's suggestion to use clone, it creates a clone thus it allocates more memory. While I was writing this, I was thinking it would be a waste of memory. However, in a practical sense, it is not so much important in this case because I'm not dealing with huge chunks of data. It doesn't kill at least. So, yeah, let me try that. Thank you and @droundy for the explanation.

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