Copy and reborrows
Shared references (&T) implement Copy, which makes them very flexible. Once you have one,
you can have as many as you want; once you've exposed one, you can't keep track of how many there are.
Exclusive references (&mut T) do not implement Copy.
Instead, you can use them ergonomically through a mechanism called reborrowing. For example here:
#![allow(unused)] fn main() { fn foo<'v>(v: &'v mut Vec<i32>) { v.push(0); // line 1 println!("{v:?}"); // line 2 } }
You're not moving v: &mut Vec<i32> when you pass it to push on line 1, or you couldn't print it on line 2.
But you're not copying it either, because &mut _ does not implement Copy.
Instead *v is reborrowed for some shorter lifetime than 'v, which ends on line 1.
An explicit reborrow would look like this:
#![allow(unused)] fn main() { Vec::push(&mut *v, 0); }
v can't be used while the reborrow &mut *v exists, but after it "expires", you can use v again.
In this way, both &mut are still exclusive borrows.
Though tragically underdocumented, reborrowing is what makes &mut usable; there's a lot of implicit reborrowing in Rust.
Reborrowing makes &mut T act like the Copy-able &T in some ways. But the necessity that &mut T is exclusive while
it exists leads to it being much less flexible.
Reborrowing is a large topic on its own, but you should at least understand that it exists, and is what enables Rust to be usable and ergonomic while still enforcing memory safety.