realwangliqiu
realwangliqiu

Reputation: 409

borrow disjoint fields of a struct

struct C {
    p: String,
    q: String,
}

impl C {
    fn call(&mut self) {}
}

fn main(){
    let mut c = C { p: "p".to_string(), q: "q".to_string() };        
    let p = &mut c.p; // first mutable borrow occurs here
    let q = &mut c.q; // second mutable borrow doesn't occur here, why???
    c.call();         // second mutable borrow occurs here
    p.push('x');
    q.push('y');
}

let q = &mut c.q; second mutable borrow doesn't occur here, why??? second mutable borrow doesn't occur here, why??? second mutable borrow doesn't occur here, why???

Upvotes: 0

Views: 103

Answers (1)

prog-fh
prog-fh

Reputation: 16815

The first borrow p is enough to be in conflict with the usage of r_c.

No need to repeat the same diagnostic with q.

If you swap these two lines, you have the same message about q.

If you reorder this way

    let r_c = &mut c;
    r_c.call();
    let p = &mut r_c.p;
    let q = &mut r_c.q; // ???
    p.push('x');
    q.push('y');

these conflicts disappear since r_c is not used anymore after .call().

These exclusive references don't really hurt as long as you don't use them; i.e. pass them to functions.

I guess you introduced these references for an experimentation purpose (good thing), but in practice we should try to avoid letting them span over long portions of code (between their creation and their last usage) because conflicts with other operations may occur in the middle.

From the edited question:

but why does mutable borrow not occur in let q = &mut r_c.q;?

It does occur. The error is on r_c.call() and the message shows the first reference (p) causing this error; the message is first mutable borrow occurs here. Even if the second reference (q) did not exist, the error would be the same. If twelve references were taken here, the error would still be the same; no need to repeat the same help message many times.

Upvotes: 3

Related Questions