Borrowing self as mutable and a member of self not possible?

Viewed 683
struct State {
    x: i32
}

trait A {
    fn a(&mut self, b: &i32);
}

impl A for State {
    fn a(&mut self, b: &i32) {
        
    }
}

fn main() {
    let mut a = State{x: 0};
    a.a(&a.x);
}

Error:

error[E0502]: cannot borrow `a` as mutable because it is also borrowed as immutable
  --> src/main.rs:17:5
   |
17 |     a.a(&a.x);
   |     ^^-^----^
   |     | | |
   |     | | immutable borrow occurs here
   |     | immutable borrow later used by call
   |     mutable borrow occurs here

It looks like the error talks about borrowing self, but I'm borrowing self only once, the second b should be a borrow of a member of the struct.

When I borrow a member of the struct, does Rust borrow the struct entirely?

I took a read at https://doc.rust-lang.org/nomicon/borrow-splitting.html but it says that it's possible to borrow just an element of the struct as long as it's not a slice.

1 Answers

When you call your A::a method, it borrows a whole variable it implemented for. So you can't have immutable references to the same object (or it's content) at the same time.

struct State {
    x: i32,
    y: i32,
}

trait A {
    fn a(&mut self, b: &i32); // borrow a whole `Self` always
}

impl A for State {
    fn a(&mut self, b: &i32) {
        // consider next code
        self.x *= 2 + *b;
        // if you provide `b` as `&a.x`, then it becomes unclear what result should be
    } // borrow a whole `Self` always
}

fn swap(first: &mut i32, second: &mut i32) {} // borrow only provided `i32`s

fn main() {
    let mut a = State{x: 0, y: 0};
    // a.a(&a.x); // you can't, as long as `a.a` borrows whole `State` 
    swap(&mut a.x, &mut a.y); // but you can borrow partially if the parts are separate
}
Related