Why does this code have an error?

use std::convert::From;

mod lib {
    pub enum TicTacToeCharacter {
        X,
        O,
    }
    type OptionalTicTacToeCharacter = Option<TicTacToeCharacter>;
    type OptionalRowOfOptionalTicTacToeCharacters = Option<(
        OptionalTicTacToeCharacter,
        OptionalTicTacToeCharacter,
        OptionalTicTacToeCharacter,
    )>;
    type TicTacToeBoard = Option<(
        OptionalRowOfOptionalTicTacToeCharacters,
        OptionalRowOfOptionalTicTacToeCharacters,
        OptionalRowOfOptionalTicTacToeCharacters,
    )>;
    pub struct TicTacToe {
        state: TicTacToeBoard,
        turn: TicTacToeCharacter,
    }
    impl TicTacToe {
        fn new(state: TicTacToeBoard, turn: TicTacToeCharacter) -> Option<Self> {
            match (state, turn) {
                (None, TicTacToeCharacter::X) => Some(TicTacToe {
                    state: None,
                    turn: TicTacToeCharacter::X,
                }),
                (None, TicTacToeCharacter::O) => None,
                _ => Some(TicTacToe { state, turn }),
            }
        }
    }
}

fn main() {
    println!("Hello world!");
}

#[cfg(test)]
mod tests {
    use super::lib::*;
    #[test]
    fn new_empty_with_o_turn_should_not_be_ok() {}
}

Gives the error on line 31: use of moved value state, and the same with turn.

This is because there is no #[derive(Copy)] on the TicTacToeCharacter enum, which means that the compiler must treat it as if values of that type are consumed on uses that are not by reference. Matching on it directly is such a use.

One option is to match by reference.

match (&state, &turn) {
    (None, TicTacToeCharacter::X) => Some(TicTacToe {
        state: None,
        turn: TicTacToeCharacter::X,
    }),
    (None, TicTacToeCharacter::O) => None,
    _ => Some(TicTacToe { state, turn }),
}

Of course, in this case you probably just want to derive the Copy trait.

Because by doing this:

you're taking the values of state and turn (the arguments that you've passed to the function) and plugging them into the match statement's patterns. They belong to match 's patterns now.

Then, however, you're telling the compiler to take those same arguments again and plug them into a completely new Option:

But those values no longer exist, in the traditional sense of the word - the function gave them up to the patterns of the match statement and trying to 'grab' them again produces an error:

   |
24 |         fn new(state: TicTacToeBoard, turn: TicTacToeCharacter) -> Option<Self> {
   |                ----- move occurs because `state` has type `std::option::Option<(std::option::Option<(std::option::Option<lib::TicTacToeCharacter>, std::option::Option<lib::TicTacToeCharacter>, std::option::Option<lib::TicTacToeCharacter>)>, std::option::Option<(std::option::Option<lib::TicTacToeCharacter>, std::option::Option<lib::TicTacToeCharacter>, std::option::Option<lib::TicTacToeCharacter>)>, std::option::Option<(std::option::Option<lib::TicTacToeCharacter>, std::option::Option<lib::TicTacToeCharacter>, std::option::Option<lib::TicTacToeCharacter>)>)>`, which does not implement the `Copy` trait
25 |             match (state, turn) {
   |                    ----- value moved here
...
31 |                 _ => Some(TicTacToe { state, turn }),
   |                                       ^^^^^ value used here after move

error[E0382]: use of moved value: `turn`
  --> src/lib.rs:31:46
   |
24 |         fn new(state: TicTacToeBoard, turn: TicTacToeCharacter) -> Option<Self> {
   |                                       ---- move occurs because `turn` has type `lib::TicTacToeCharacter`, which does not implement the `Copy` trait
25 |             match (state, turn) {
   |                           ---- value moved here
...
31 |                 _ => Some(TicTacToe { state, turn }),
   |                                              ^^^^ value used here after move

The solution is trivial: simply take an immutable reference to state and to value while passing them to the match statement, instead of giving them up. That will 'set them free' and let you use them when you're creating your new Option on line 31.

match (&state, &turn) { // line 25

The move happens because of the tuple (state, turn), not because of the match. It's possible to match on a value without moving it as long as there are no bindings in the pattern. You can even move the value in one branch and not in another branch.

Aside: The prefix naming scheme -- TicTacToeCharacter, TicTacToeBoard, etc. -- is a cargo cult practice that originated from languages without namespaces. In a modern language like Rust, you know the Board is a tic-tac-toe board and not a diving board or a supervisory board because it's in a crate or a module named tictactoe. You don't need to repeat the context every time you use the name.