Search code examples
rustmutexautomatic-ref-counting

Rust: Cannot borrow data in `Arc` as mutable, but inner data is protected via Mutex


While learning Rust, and trying to work through an example wherein a database Db is required to be shared across threads and functions.

Link To Minimal Example

I have wrapped the database (a struct) in an Arc, and within the struct, protected the member with a Mutex:

pub struct Db{
    pub db: Mutex<BTreeMap<String, String>>,
}

However, I get the error when attempting to update Db via an associated method:

help: trait DerefMut is required to modify through a dereference, but it is not implemented for Arc<Db>

I have seen this SO post, but instead of Arc::new(Mutex::new(Db)), I only pass Arc::new(Db) with the understanding that inner member of the database is mutex-protected.

Question How do I indicate to the compiler that inner data member of Db is access protected in order to successfully build Link To Minimal Example ? If this were possible, would this be a recommended approach?

Other Information rustc 1.65.0 (897e37553 2022-11-02)


Solution

  • Currently, you have

    impl Db {
        pub fn add(&mut self, data: String) -> Option<String> { ... }
    }
    

    But, as you said, you protect the database inside a Mutex. So you don't need mut access:

    impl Db {
        pub fn add(&self, data: String) -> Option<String> { ... }
    }
    

    See, &mut in Rust really means "exclusive" or "unique" access. Rust will enforce that &mut references are unique at compile time, which is why it gives you that error. Mutex only requires a "shared" (immutable) & reference, and enforces the same rules at runtime instead.

    Removing that mut is literally all that's necessary to make your example work