1

Here's the code, since a is declared as immutable, we can't obtain a mutable reference from a, right? But this one has compiled, why is that?

struct Foo;

fn main() {
    let a = &mut Foo;
    a.mut_ref();
}

impl Foo {
    fn mut_ref(&mut self) { }
}

code-link

1
  • You don't actually obtain a mutable reference to a in this code, but this is still a good question. I know it is this way but I couldn't explain it mechanically. Commented Aug 19, 2020 at 3:45

1 Answer 1

5

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.