The type of the variable a
is &mut Foo
, i.e. a
itself is a mutable reference to a Foo
object. Mutating a
would mean to make it point to a different Foo
object. Since a
itself is immutable, you can't change what a
is pointing to, and your code does not disprove this in any way.
Your code simply passes the &mut Foo
as the self
parameter to mut_ref()
– note that the type of self
is also &mut Foo
. No auto-dereferencing is happening – a
already has exactly the type that is epxected for the self
parameter. However, we are triggering an implicit reborrow here, so the call is equivalent to Foo::mut_ref(&mut *a)
. This implicit reborrow isn't what's making the code work, though – moving the mutable reference out of a
would also be perfectly allowed.
While a
is immutable as a variable, it's still a mutable reference, so you can mutate the Foo
object it's pointing to (assuming Foo
had any state to mutate). You can't obtain a mutable reference to a
, which would need to have the type &mut &mut Foo
.