Why is compiler reporting partial move in error and not move?

Viewed 357

In the below program why does the compiler error mention partially moved and not just moved? How is partial move happening here from x to z? If &mut T doesn't implement Copy trait, it should be moved and not partial move?

fn main() {
    let mut y = 2;
    let x = Some(&mut y);
    match x {
        None => (),
        Some(z) => {
        *z = 3; 
        println!("{}", z)},
    };
    println!("{:?}",x);
}

Below is the error from the playground

Compiling playground v0.0.1 (/playground)
error[E0382]: borrow of partially moved value: `x`
  --> src/main.rs:10:21
   |
6  |         Some(z) => {
   |              - value partially moved here
...
10 |     println!("{:?}",x);
   |                     ^ value borrowed here after partial move
   |
   = note: partial move occurs because value has type `&mut i32`, which does not implement the `Copy` trait
help: borrow this field in the pattern to avoid moving `x.0`
   |
6  |         Some(ref z) => {
   |              ^^^

For more information about this error, try `rustc --explain E0382`.
error: could not compile `playground` due to previous error
1 Answers

Consider the Option enum:

enum Option<T> {
    Some(T),
    None
}

Within that enum, Some(T) is actually a tuple struct, containing one field.

When you use pattern matching to extract the value of the inner T, that would be a partial move of one field of the single field tuple struct Some.

A partial move of a field from a struct that only has one field might not seem useful, but more generally there could be any number of fields in the struct.

See also:

Related