Unclear "move out of a shared reference"

Hi everyone!

While trying out some Rust code, I ran into this situation where I cannot reason what is the difference between the two commented out lines below.

First one works, but second line, if un-commented, fails compilation with error error[E0507]: cannot move out of a shared reference

Could someone please help me understand this better?

struct A {
    f: String
}

fn main() {
    let a = A{f: String::new()};
     // let works = a.f;  // un-commenting this line is allowed
     // let fails = *&a.f;  // un-commenting this line results in failure
}

You can't move out of a reference, because what would the referred place contain then?

You can only replace values through references, and only through mutable references. That's what std::mem::replace() is for.

Thanks, but I am still not clear why is the first commented line allowed but second not. The reference does not live longer other than being deferenced, nor is there any other use of it. To an amateur, it would appear that a *& sort of cancel out each other completely (and therefore the two commented lines seem equivalent)?

In the first case, the compiler performs a partial destructuring of a, allowing you to take out a.f without putting something else in. This partial destructuring cannot happen through a reference.

3 Likes