How to fix this `BorrowMutError`

Below is the abstract code structure

/*
[dependencies]

[dependencies.tokio]
features = ["full"]
version = "1.19.2"

*/
use std::{cell::RefCell, rc::Rc};
use std::collections::hash_map::HashMap;

#[derive(Debug)]
struct B {
    m: String
}
struct A {
    pending: Rc<RefCell<HashMap<String, B>>>,
}

impl A {
    pub async fn run(&self) {
        let a = self.pending.clone();
        let b = a.borrow_mut(); // borrow first

        let c = b.get(&"a".to_string());
        
        println!("{c:?}");
       // here already need use `c`

        if self.load(&"b".to_string()).is_some() {
            let  r = b.get(&"b".to_string());

          // here already need use `r`    
            println!("{r:?}");
        }
        
    }
    pub fn load(&self, key: &String) -> Option<()> {

        // 
        let a = self.pending.clone();
        let b = a.clone();
        let mut c = b.borrow_mut();  // borrow error here

            
        if c.get(key).is_none() {

            c.insert(key.clone(), B{
                m: "hello".to_string()
            });
            
        }
        
        return Some(());
        
    }
}

#[tokio::main]
async fn main() {

    let a = A {
        pending: Rc::new(RefCell::new(HashMap::new()))
    };
    a.load(&"a".to_string());
    a.run().await;
    
}

Drop the BorrowMut (b) before you call load and recreate it afterwards.

        println!("{c:?}");
        drop(b);
        if self.load(&"b".to_string()).is_some() {
            let b = a.borrow_mut();
            let r = b.get(&"b".to_string());
            // here already need use `r`
            println!("{r:?}");
        }

Playground.


Incidentally your code is unidiomatic in some other ways. Try running the Clippy linter against it (also available in the playground under Tools).

2 Likes

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.