Panther Coder
Panther Coder

Reputation: 1078

Rust Compiler throws error related to moving data out of a shared reference

I have been writing a program in Rust where I encountered an error relating to moving the data of a Shared Reference.

I made some research, but I was unable to find the cause of the error in the program I have written. Here is the simplified version of the program:

enum A {
    Won = 1,
}

struct B {
    result: A,
}

fn print_game(game: &B) {
    println!("{}", game.result as u32);
}

fn main() {
    let game: B = B { result: A::Won };
    print_game(&game);
}

The above program when compiled, throws the below error:

error[E0507]: cannot move out of `game.result` which is behind a shared reference
  --> src/main.rs:10:20
   |
10 |     println!("{}", game.result as u32);
   |                    ^^^^^^^^^^^ move occurs because `game.result` has type `A`, which does not implement the `Copy` trait

From the error I can infer that the data in game.result is moved, but, I am not sure where it is moved and why it's been moved.

Upvotes: 0

Views: 172

Answers (3)

Kaplan
Kaplan

Reputation: 3728

Another option would be to refactor the program to only print what is actually needed:

…
fn main() {
    let game: B = B { result: A::Won };
        print_result(game.result);
}

Playground

Upvotes: 0

mk_dhu
mk_dhu

Reputation: 36

In rust, default behaviour for custom type is 'move' unless you implement Copy trait for the type. If the value bound to a variable moves, the variable can not be used anymore. Developers new to Rust must get used to it.

Move is attempted in 'game.result as i32' portion of your code. Type casting is also counted as move for value of 'move' type.

I agree with the solution already mentioned above, just add the line #[derive(Clone, Copy)]

Rust Playground

Traits like Deref, Into, From etc. could also be relevant, but depends...


By 'move' compiler means just transfer of ownership, not the change of data location in memory.

Suppose we have a variable v bound to a 'move' data. In a type casting like 'v as T' the ownership of data is detached from v and the bytes are reinterpreted as type T.

But why is this casting not allowed in your example? Actual cause of error is that 'game' is a shared reference of type &B and you tried to use it to detach original ownership of data referred by it.

Shared reference can never be used to move referred data or part of it. <<

Upvotes: 2

jq170727
jq170727

Reputation: 14655

In this case I think your enum A just needs a #[derive(Clone, Copy)].

Rust Playground Example

Upvotes: 0

Related Questions