Here there is an image from the interactive book, and their permissions model, which I found very cool but can't get this feature.
The problem is: why does the variable num makes v lose ownership when it's borrowed, and not just read and optionally write permissions (when the reference is mutable.) ?
Note that in the book this happens regardless of the borrowing being mut or not. All cases use the same for O (just changes W)
Correct, the ownership doesn't change when you take a reference. The owning object is just temporarily restricted while it is borrowed. When the scope of the loans ends, the owning object can be moved or destroyed again.
fn main() {
let mut v: Vec<i32> = vec![1, 2, 3];
let vc= &mut v;
vc.push(5);
println!("Vector is now {:?}", v);// 1,2,3,5
}
This isn't just updating v but pushing to it, so if the data has to be moved to a different location in the heap, is v's pointer to the relocated array updated? (and I think both vc and v always use the same pointer, just vc has an extra hop to v)
You only "lose W privileges" so long as borrow is active. Once you stop using y, x can be updated again.
Being borrowed[1] conflicts with being overwrote, moved, or taking a &mut.
The problem with pushing while y is active is that pushing requires a &mut, which is an exclusive reference. If it weren't exclusive, you could say launch a scoped thread to continuously read the length and/or existing data and capacity through y while the push happens, creating a data race (which is UB).
be it a shared & borrow or an exclusive &mut borrow âŠī¸
The "head" v of the Vec is stored separately from its data on the heap. The data on the heap can be reallocated (move) if the individual elements there aren't borrowed.
More precisely, the place where v exists must remain valid and can't be moved or destroyed while its borrowed, but the content of that place (byte values that are in there, and other data reachable from there) can change if something has a mutable access to it.
There is a confusing special case of std::mem::swap that swaps two values, which effectively moves the objects, but doesn't affect the places where they're stored. This is a case where Rust's terminology gets tricky, because swapped values are moved, but they're not moved out of the place they're in. It's a move from perspective of objects changing their location, but not a move from the perspective of the borrow checker!