Why does the compiler disallow the first form, while allowing the second form, basically allowing two mutable borrows of a to co-exist at the same time?
One could argue that if we try to use the first mutable borrow of a before the second one, in the second example, it will stop compiling.
But why isn't this applicable to the first example, where it won't compile regardless of the order in which we use the two borrows of a?
fn main() {
{
// This doesn't compile
let mut a = vec![100];
let b = &mut a;
{
let c = &mut a;
c.push(10);
}
b.push(20);
println!("Final {:?}", a)
}
{
// This compiles
let mut a = vec![100];
let b = &mut a;
{
let c = &mut *b;
c.push(1);
}
b.push(20);
println!("Final {:?}", a)
}
}
In the second example, c is a reborrow of *b. While the reborrow is active, b is inactive; once the reborrow expires, b can be active again. Even though the two &mut exist, only one is active at a time, so they still provide exclusivity.
Thus "no two &mut" or "no &mut and &" is an oversimplification of Rust's aliasing requirements. It's closer to "if a &mut is active, no other observer can be active".
Reborrows are actually happening all the time, which is why this works even though &mut is not Copy.
In the first example, there is no reborrowing. You're using something (a) that gets used in a way (borrowing it exclusively to create c) that cancels any active borrows.
You can perhaps think of the allowed reborrows as some tree of delegation. If b is to remain usable after the creation of c, b has to be involved in some chain of reborrows that leads from c back to b. Instead in the first example, c borrowed a, which is above b in the tree.
Yes, if foo takes a &mut _, that's pretty much what happens (or just foo(&mut *x)). Each reborrow lasts only as long as the call to foo.
(Most transformations or things like operator resolution happen at some non-syntactical level, so I always take it with a grain of salt when I read about a Rust "desugaring" or "equivalent to" as I've encountered a number of exceptions, but in this case I can't think of any difference.)