Problem with RefCell and multiple borrows


#1

Dear friends of Rust,

I started diving into Cell and RefCell because I have a struct which has a single mutable Option field. I don’t know how to change this field after checking for Some() and None, because in the way I did it, it calls for the borrow checker who complains that I cannot borrow mutable variables more than once. This Rust Playground boils it down to the issue.

Every help is appreciated! Thanks in advance!


#2

The issue here is that the borrow checker isn’t currently sophisticated enough to tell that the borrow in if let Some... doesn’t carry on to the else branch. You can manually break the dependency like this.


#3

I wanted to fix two things. The first is the signature:

(one: &'a mut One<'a>, num: &'a f64)
// should be:
(one: &mut One<'a>, num: &'a f64)

The 'a on the mutable borrow of the One is extra. You don’t want to add extra constraints to lifetime parameters you use, that can only give you more borrow errors.

The issue with the if let is that the right hand side value is borrowed for the whole statement, including until the end of the else block. In this case we can fix this easily by using match:

fn test<'a>(one: &mut One<'a>, num: &'a f64) {
    let mut o = one.foo.borrow_mut();
    match *o {
        Some(ref mut o_) => o_.push(&num),
        // get a mutable reference to that None.
        ref mut none @ None => *none = Some(vec![num]),
    }
}

#4

Bluss has good tips, also you don’t need refcell checkout:
https://is.gd/I4ceJh


#5

Thanks to minno and bluss. This is was a great help.


#6

True, I also figured this. Thx.