Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`if` condition remains borrowed in body [duplicate]

Tags:

rust

I just came across some behaviour in Rust (1.12) I cannot explain. I have a struct that implements lazy loading with a RefCell<Option<i32>> and a function to access the data:

struct Foo {
    data: RefCell<Option<i32>>
}

impl Foo {
    fn get_data(&self) -> i32 {
        if self.data.borrow().is_none() { // <--- (a)
            let d = 1337;
            self.data.borrow_mut() = Some(d); // <--- (b)
            d
        } else {
            self.data.borrow().unwrap()
        }
    }
}

This compiles but yields a runtime error: The RefCell complains that a borrow is already active when attempting to borrow_mut on line (b). The issue does not occur, however, if I change the if statement to the following:

let is_none = self.data.borrow().is_none();
if is_none {

Question: Why is the borrow in the if condition on line (a) still active inside the body of the if statement? Shouldn't the call to is_none() cause the borrow to end, since I'm only holding on to a bool afterwards, and not the borrowed value?

like image 531
Fabian Schuiki Avatar asked Nov 08 '16 09:11

Fabian Schuiki


1 Answers

This is due to Rust's lexical borrowing scope.

As you have noticed, borrowing something in the condition also borrows it for the branch. This is discussed in this issue, and has since moved here.

This is a limitation that is currently fixed in the Rust 1.13 Beta and will thus probably be released in the next cycle.

like image 171
Neikos Avatar answered Nov 15 '22 08:11

Neikos