0
struct Abc {
    a: i32,
}

fn main() {
    let mut abc = Abc { a: 30 };
    let xyz = &abc;
    let q = *xyz;
}

Compiling the code gives following error:

error[E0507]: cannot move out of borrowed content
  --> src/main.rs:11:13
   |
11 |     let q = *xyz;
   |             ^^^^
   |             |
   |             cannot move out of borrowed content
   |             help: consider using a reference instead: `&*xyz`

Please help me understand what is going wrong here.

Peter Hall
  • 36,534
  • 10
  • 79
  • 144
user8070445
  • 33
  • 1
  • 7
  • Possible duplicate of [Cannot move out of borrowed content](https://stackoverflow.com/questions/28158738/cannot-move-out-of-borrowed-content) – Boiethios Sep 25 '18 at 09:09
  • Can you further describe what is confusing you in this particular example? [This section](https://doc.rust-lang.org/stable/book/second-edition/ch04-00-understanding-ownership.html) of the book on ownership may help you understand what is happening. Moreover, there are [dozens of other questions with that exact same error message](https://stackoverflow.com/search?q=%5Brust%5D+cannot+move+out+of+borrowed+content). – SE_net4 the downvoter Sep 25 '18 at 09:11
  • The below code compiles but whats wrong with the code in question "fn main() { let mut abc = 10; let xyz = &abc; let q = *xyz; }" – user8070445 Sep 25 '18 at 09:13
  • 8
    @user8070445 Numbers are `Copy` types, so they don't get moved. Your struct will be moved when it is assigned to a variable because it is not `Copy`. – Peter Hall Sep 25 '18 at 09:23

1 Answers1

1

When you write let a = b; in Rust, the value of b is moved to a, and the variable b is no longer usable.

In your case, xyz is a reference to abc, so *xyz is the same thing as abc. Moving abc is an error because the reference xyz still exists, but now is pointing at invalid memory.

If you are confused why this didn't happen with a numeric type like i32, that's because most simple primitives implement the Copy trait. This is marker trait which tells the compiler to copy the value in memory, rather than move it. For small types, this can be the same performance as (or sometimes even better than) passing by reference.

See:

Peter Hall
  • 36,534
  • 10
  • 79
  • 144