What's the difference between lifetimes of immutable and mutable references?

Viewed 84

There is a struct definition as follows.

struct Test<'a> {
    t: &'a str,
}
impl<'a> Test<'a> {
    pub fn shared_borrow(&'a self) {
        println!("{}", self.t);
    }
    pub fn mutable_borrow(&'a mut self) {
        println!("{}", self.t);
    }
}

Case 1. It can pass through the borrowing check, if shared_borrow() is called before mutable_borrow().

fn main() {
    let mut x = Test { t: "test" };
    x.shared_borrow();
    x.mutable_borrow();
}

Case 2. It fails if I exchange the order of the method calls as follows.

fn main() {
    let mut x = Test { t: "test" };
    x.mutable_borrow();
    x.shared_borrow();
}

compiler's output:

error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
  --> src/main.rs:16:5
   |
15 |     x.mutable_borrow();
   |     - mutable borrow occurs here
16 |     x.shared_borrow();
   |     ^
   |     |
   |     immutable borrow occurs here
   |     mutable borrow later used here

error: aborting due to previous error

As I know, shared_borrow() and mutable_borrow() both borrow x for the entire lifetime of x, because the lifetimes are explicitly declared as 'a, which is the lifetime of x.

In Case 1, x.shared_borrow() will borrow x for the entire lifetime of x. So It shouldn't be allowed to call x.mutable_borrow() after that. I'm confused why the compiler doesn't report an error as what it does in Case 2.

0 Answers
Related