Why move occurs when using custom Enum?

enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter(UsState),
}

enum UsState {
    Alabama,
    Alaska,
    Oklahoma,
}

fn main() {
    let quarter: Coin = Coin::Quarter(UsState::Alabama);
    println!("A Quarter is {} cents.", value_in_cents(quarter));

    println!("{:?}", quarter);
}

fn value_in_cents(coin: Coin) -> u8 { 
    // do some stuff and return u8
}

Compiler output:

error[E0382]: borrow of moved value: `quarter`
  --> src/main.rs:38:22
   |
35 |     let quarter: Coin = Coin::Quarter(UsState::Alabama);
   |         ------- move occurs because `quarter` has type `Coin`, which does not implement the `Copy` trait
36 |     println!("A Quarter is {} cents.", value_in_cents(quarter));
   |                                                       ------- value moved here
37 |     
38 |     println!("{:?}", quarter);
   |                      ^^^^^^^ value borrowed here after move

From my point of view, the Enum Coin has a fixed size and is known at compile time, so it should be stored at stack, so it doesn't need to care about ownership.

But why it still "moves"?

Things with a fixed size that are stored on the stack absolutely need to care about ownership. For example, the File type is internally just an integer on Linux, and integers are both stored on the stack and have a fixed size. Ownership of that file is pretty important.

What you are looking for is Copy. You can simply add #[derive(Clone, Copy)] to both enums, and the compiler will copy them instead of moving them.

#[derive(Clone, Copy)]
enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter(UsState),
}

#[derive(Clone, Copy)]
enum UsState {
    Alabama,
    Alaska,
    Oklahoma,
}
2 Likes

Thank you for reminding me that stack type also have ownership.