(* Generated by coq-of-rust *)
Require Import CoqOfRust.CoqOfRust.

Module state.
  (*
  Enum VMState
  {
    const_params := [];
    ty_params := [];
    variants :=
      [
        {
          name := "DESERIALIZER";
          item := StructTuple [];
          discriminant := None;
        };
        {
          name := "VERIFIER";
          item := StructTuple [];
          discriminant := None;
        };
        {
          name := "RUNTIME";
          item := StructTuple [];
          discriminant := None;
        };
        {
          name := "OTHER";
          item := StructTuple [];
          discriminant := None;
        }
      ];
  }
  *)
  
  Module Impl_core_clone_Clone_for_move_core_types_state_VMState.
    Definition Self : Ty.t := Ty.path "move_core_types::state::VMState".
    
    (* Clone *)
    Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (| M.read (| self |) |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::clone::Clone"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("clone", InstanceField.Method clone) ].
  End Impl_core_clone_Clone_for_move_core_types_state_VMState.
  
  Module Impl_core_marker_Copy_for_move_core_types_state_VMState.
    Definition Self : Ty.t := Ty.path "move_core_types::state::VMState".
    
    Axiom Implements :
      M.IsTraitInstance
        "core::marker::Copy"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [].
  End Impl_core_marker_Copy_for_move_core_types_state_VMState.
  
  Module Impl_core_fmt_Debug_for_move_core_types_state_VMState.
    Definition Self : Ty.t := Ty.path "move_core_types::state::VMState".
    
    (* Debug *)
    Definition fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; f ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let f := M.alloc (| f |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "core::fmt::Formatter", "write_str", [] |),
            [
              M.read (| f |);
              M.read (|
                M.match_operator (|
                  self,
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let _ :=
                          M.is_struct_tuple (|
                            γ,
                            "move_core_types::state::VMState::DESERIALIZER"
                          |) in
                        M.alloc (| M.read (| Value.String "DESERIALIZER" |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let _ :=
                          M.is_struct_tuple (| γ, "move_core_types::state::VMState::VERIFIER" |) in
                        M.alloc (| M.read (| Value.String "VERIFIER" |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let _ :=
                          M.is_struct_tuple (| γ, "move_core_types::state::VMState::RUNTIME" |) in
                        M.alloc (| M.read (| Value.String "RUNTIME" |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let _ :=
                          M.is_struct_tuple (| γ, "move_core_types::state::VMState::OTHER" |) in
                        M.alloc (| M.read (| Value.String "OTHER" |) |)))
                  ]
                |)
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::fmt::Debug"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("fmt", InstanceField.Method fmt) ].
  End Impl_core_fmt_Debug_for_move_core_types_state_VMState.
  
  Module Impl_core_marker_StructuralPartialEq_for_move_core_types_state_VMState.
    Definition Self : Ty.t := Ty.path "move_core_types::state::VMState".
    
    Axiom Implements :
      M.IsTraitInstance
        "core::marker::StructuralPartialEq"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [].
  End Impl_core_marker_StructuralPartialEq_for_move_core_types_state_VMState.
  
  Module Impl_core_cmp_PartialEq_for_move_core_types_state_VMState.
    Definition Self : Ty.t := Ty.path "move_core_types::state::VMState".
    
    (* PartialEq *)
    Definition eq (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            let~ __self_discr :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (|
                    "core::intrinsics::discriminant_value",
                    [ Ty.path "move_core_types::state::VMState" ]
                  |),
                  [ M.read (| self |) ]
                |)
              |) in
            let~ __arg1_discr :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (|
                    "core::intrinsics::discriminant_value",
                    [ Ty.path "move_core_types::state::VMState" ]
                  |),
                  [ M.read (| other |) ]
                |)
              |) in
            M.alloc (| BinOp.eq (| M.read (| __self_discr |), M.read (| __arg1_discr |) |) |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::cmp::PartialEq"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("eq", InstanceField.Method eq) ].
  End Impl_core_cmp_PartialEq_for_move_core_types_state_VMState.
  
  Module Impl_core_cmp_Eq_for_move_core_types_state_VMState.
    Definition Self : Ty.t := Ty.path "move_core_types::state::VMState".
    
    (* Eq *)
    Definition assert_receiver_is_total_eq
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          Value.Tuple []))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::cmp::Eq"
        Self
        (* Trait polymorphic types *) []
        (* Instance *)
        [ ("assert_receiver_is_total_eq", InstanceField.Method assert_receiver_is_total_eq) ].
  End Impl_core_cmp_Eq_for_move_core_types_state_VMState.
  
  (*
  pub fn set_state(state: VMState) -> VMState {
      STATE.with(|s| s.replace(state))
  }
  *)
  Definition set_state (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ state ] =>
      ltac:(M.monadic
        (let state := M.alloc (| state |) in
        M.call_closure (|
          M.get_associated_function (|
            Ty.apply
              (Ty.path "std::thread::local::LocalKey")
              []
              [
                Ty.apply
                  (Ty.path "core::cell::RefCell")
                  []
                  [ Ty.path "move_core_types::state::VMState" ]
              ],
            "with",
            [
              Ty.function
                [
                  Ty.tuple
                    [
                      Ty.apply
                        (Ty.path "&")
                        []
                        [
                          Ty.apply
                            (Ty.path "core::cell::RefCell")
                            []
                            [ Ty.path "move_core_types::state::VMState" ]
                        ]
                    ]
                ]
                (Ty.path "move_core_types::state::VMState");
              Ty.path "move_core_types::state::VMState"
            ]
          |),
          [
            M.get_constant (| "move_core_types::state::STATE" |);
            M.closure
              (fun γ =>
                ltac:(M.monadic
                  match γ with
                  | [ α0 ] =>
                    ltac:(M.monadic
                      (M.match_operator (|
                        M.alloc (| α0 |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let s := M.copy (| γ |) in
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "core::cell::RefCell")
                                    []
                                    [ Ty.path "move_core_types::state::VMState" ],
                                  "replace",
                                  []
                                |),
                                [ M.read (| s |); M.read (| state |) ]
                              |)))
                        ]
                      |)))
                  | _ => M.impossible "wrong number of arguments"
                  end))
          ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_set_state : M.IsFunction "move_core_types::state::set_state" set_state.
  
  (*
  pub fn get_state() -> VMState {
      STATE.with(|s| *s.borrow())
  }
  *)
  Definition get_state (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [] =>
      ltac:(M.monadic
        (M.call_closure (|
          M.get_associated_function (|
            Ty.apply
              (Ty.path "std::thread::local::LocalKey")
              []
              [
                Ty.apply
                  (Ty.path "core::cell::RefCell")
                  []
                  [ Ty.path "move_core_types::state::VMState" ]
              ],
            "with",
            [
              Ty.function
                [
                  Ty.tuple
                    [
                      Ty.apply
                        (Ty.path "&")
                        []
                        [
                          Ty.apply
                            (Ty.path "core::cell::RefCell")
                            []
                            [ Ty.path "move_core_types::state::VMState" ]
                        ]
                    ]
                ]
                (Ty.path "move_core_types::state::VMState");
              Ty.path "move_core_types::state::VMState"
            ]
          |),
          [
            M.get_constant (| "move_core_types::state::STATE" |);
            M.closure
              (fun γ =>
                ltac:(M.monadic
                  match γ with
                  | [ α0 ] =>
                    ltac:(M.monadic
                      (M.match_operator (|
                        M.alloc (| α0 |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let s := M.copy (| γ |) in
                              M.read (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::ops::deref::Deref",
                                    Ty.apply
                                      (Ty.path "core::cell::Ref")
                                      []
                                      [ Ty.path "move_core_types::state::VMState" ],
                                    [],
                                    "deref",
                                    []
                                  |),
                                  [
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply
                                            (Ty.path "core::cell::RefCell")
                                            []
                                            [ Ty.path "move_core_types::state::VMState" ],
                                          "borrow",
                                          []
                                        |),
                                        [ M.read (| s |) ]
                                      |)
                                    |)
                                  ]
                                |)
                              |)))
                        ]
                      |)))
                  | _ => M.impossible "wrong number of arguments"
                  end))
          ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_get_state : M.IsFunction "move_core_types::state::get_state" get_state.
End state.
