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

Module ptr.
  Module unique.
    (* StructRecord
      {
        name := "Unique";
        const_params := [];
        ty_params := [ "T" ];
        fields :=
          [
            ("pointer", Ty.apply (Ty.path "core::ptr::non_null::NonNull") [] [ T ]);
            ("_marker", Ty.apply (Ty.path "core::marker::PhantomData") [] [ T ])
          ];
      } *)
    
    Module Impl_core_marker_Send_where_core_marker_Send_T_where_core_marker_Sized_T_for_core_ptr_unique_Unique_T.
      Definition Self (T : Ty.t) : Ty.t := Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ T ].
      
      Axiom Implements :
        forall (T : Ty.t),
        M.IsTraitInstance
          "core::marker::Send"
          (Self T)
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_marker_Send_where_core_marker_Send_T_where_core_marker_Sized_T_for_core_ptr_unique_Unique_T.
    
    Module Impl_core_marker_Sync_where_core_marker_Sync_T_where_core_marker_Sized_T_for_core_ptr_unique_Unique_T.
      Definition Self (T : Ty.t) : Ty.t := Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ T ].
      
      Axiom Implements :
        forall (T : Ty.t),
        M.IsTraitInstance
          "core::marker::Sync"
          (Self T)
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_marker_Sync_where_core_marker_Sync_T_where_core_marker_Sized_T_for_core_ptr_unique_Unique_T.
    
    Module Impl_core_ptr_unique_Unique_T.
      Definition Self (T : Ty.t) : Ty.t := Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ T ].
      
      (*
          pub const fn dangling() -> Self {
              // FIXME(const-hack) replace with `From`
              Unique { pointer: NonNull::dangling(), _marker: PhantomData }
          }
      *)
      Definition dangling (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self T in
        match ε, τ, α with
        | [], [], [] =>
          ltac:(M.monadic
            (Value.StructRecord
              "core::ptr::unique::Unique"
              [
                ("pointer",
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "core::ptr::non_null::NonNull") [] [ T ],
                      "dangling",
                      []
                    |),
                    []
                  |));
                ("_marker", Value.StructTuple "core::marker::PhantomData" [])
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_dangling :
        forall (T : Ty.t),
        M.IsAssociatedFunction (Self T) "dangling" (dangling T).
      (*
          pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
              // SAFETY: the caller must guarantee that `ptr` is non-null.
              unsafe { Unique { pointer: NonNull::new_unchecked(ptr), _marker: PhantomData } }
          }
      *)
      Definition new_unchecked
          (T : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self T in
        match ε, τ, α with
        | [], [], [ ptr ] =>
          ltac:(M.monadic
            (let ptr := M.alloc (| ptr |) in
            Value.StructRecord
              "core::ptr::unique::Unique"
              [
                ("pointer",
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "core::ptr::non_null::NonNull") [] [ T ],
                      "new_unchecked",
                      []
                    |),
                    [ M.read (| ptr |) ]
                  |));
                ("_marker", Value.StructTuple "core::marker::PhantomData" [])
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_new_unchecked :
        forall (T : Ty.t),
        M.IsAssociatedFunction (Self T) "new_unchecked" (new_unchecked T).
      
      (*
          pub const fn new(ptr: *mut T) -> Option<Self> {
              if let Some(pointer) = NonNull::new(ptr) {
                  Some(Unique { pointer, _marker: PhantomData })
              } else {
                  None
              }
          }
      *)
      Definition new (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self T in
        match ε, τ, α with
        | [], [], [ ptr ] =>
          ltac:(M.monadic
            (let ptr := M.alloc (| ptr |) in
            M.read (|
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "core::ptr::non_null::NonNull") [] [ T ],
                              "new",
                              []
                            |),
                            [ M.read (| ptr |) ]
                          |)
                        |) in
                      let γ0_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "core::option::Option::Some",
                          0
                        |) in
                      let pointer := M.copy (| γ0_0 |) in
                      M.alloc (|
                        Value.StructTuple
                          "core::option::Option::Some"
                          [
                            Value.StructRecord
                              "core::ptr::unique::Unique"
                              [
                                ("pointer", M.read (| pointer |));
                                ("_marker", Value.StructTuple "core::marker::PhantomData" [])
                              ]
                          ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_new :
        forall (T : Ty.t),
        M.IsAssociatedFunction (Self T) "new" (new T).
      
      (*
          pub const fn as_ptr(self) -> *mut T {
              self.pointer.as_ptr()
          }
      *)
      Definition as_ptr (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self T in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply (Ty.path "core::ptr::non_null::NonNull") [] [ T ],
                "as_ptr",
                []
              |),
              [
                M.read (|
                  M.SubPointer.get_struct_record_field (|
                    self,
                    "core::ptr::unique::Unique",
                    "pointer"
                  |)
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_as_ptr :
        forall (T : Ty.t),
        M.IsAssociatedFunction (Self T) "as_ptr" (as_ptr T).
      
      (*
          pub const fn as_non_null_ptr(self) -> NonNull<T> {
              self.pointer
          }
      *)
      Definition as_non_null_ptr
          (T : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self T in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              M.SubPointer.get_struct_record_field (|
                self,
                "core::ptr::unique::Unique",
                "pointer"
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_as_non_null_ptr :
        forall (T : Ty.t),
        M.IsAssociatedFunction (Self T) "as_non_null_ptr" (as_non_null_ptr T).
      
      (*
          pub const unsafe fn as_ref(&self) -> &T {
              // SAFETY: the caller must guarantee that `self` meets all the
              // requirements for a reference.
              unsafe { self.pointer.as_ref() }
          }
      *)
      Definition as_ref (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self T in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply (Ty.path "core::ptr::non_null::NonNull") [] [ T ],
                "as_ref",
                []
              |),
              [
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "core::ptr::unique::Unique",
                  "pointer"
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_as_ref :
        forall (T : Ty.t),
        M.IsAssociatedFunction (Self T) "as_ref" (as_ref T).
      
      (*
          pub const unsafe fn as_mut(&mut self) -> &mut T {
              // SAFETY: the caller must guarantee that `self` meets all the
              // requirements for a mutable reference.
              unsafe { self.pointer.as_mut() }
          }
      *)
      Definition as_mut (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self T in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply (Ty.path "core::ptr::non_null::NonNull") [] [ T ],
                "as_mut",
                []
              |),
              [
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "core::ptr::unique::Unique",
                  "pointer"
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_as_mut :
        forall (T : Ty.t),
        M.IsAssociatedFunction (Self T) "as_mut" (as_mut T).
      
      (*
          pub const fn cast<U>(self) -> Unique<U> {
              // FIXME(const-hack): replace with `From`
              // SAFETY: is `NonNull`
              Unique { pointer: self.pointer.cast(), _marker: PhantomData }
          }
      *)
      Definition cast (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self T in
        match ε, τ, α with
        | [], [ U ], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            Value.StructRecord
              "core::ptr::unique::Unique"
              [
                ("pointer",
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "core::ptr::non_null::NonNull") [] [ T ],
                      "cast",
                      [ U ]
                    |),
                    [
                      M.read (|
                        M.SubPointer.get_struct_record_field (|
                          self,
                          "core::ptr::unique::Unique",
                          "pointer"
                        |)
                      |)
                    ]
                  |));
                ("_marker", Value.StructTuple "core::marker::PhantomData" [])
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_cast :
        forall (T : Ty.t),
        M.IsAssociatedFunction (Self T) "cast" (cast T).
    End Impl_core_ptr_unique_Unique_T.
    
    
    Module Impl_core_clone_Clone_where_core_marker_Sized_T_for_core_ptr_unique_Unique_T.
      Definition Self (T : Ty.t) : Ty.t := Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ T ].
      
      (*
          fn clone(&self) -> Self {
              *self
          }
      *)
      Definition clone (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self T in
        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 :
        forall (T : Ty.t),
        M.IsTraitInstance
          "core::clone::Clone"
          (Self T)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method (clone T)) ].
    End Impl_core_clone_Clone_where_core_marker_Sized_T_for_core_ptr_unique_Unique_T.
    
    Module Impl_core_marker_Copy_where_core_marker_Sized_T_for_core_ptr_unique_Unique_T.
      Definition Self (T : Ty.t) : Ty.t := Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ T ].
      
      Axiom Implements :
        forall (T : Ty.t),
        M.IsTraitInstance
          "core::marker::Copy"
          (Self T)
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_marker_Copy_where_core_marker_Sized_T_for_core_ptr_unique_Unique_T.
    
    Module Impl_core_ops_unsize_CoerceUnsized_where_core_marker_Sized_T_where_core_marker_Sized_U_where_core_marker_Unsize_T_U_core_ptr_unique_Unique_U_for_core_ptr_unique_Unique_T.
      Definition Self (T U : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ T ].
      
      Axiom Implements :
        forall (T U : Ty.t),
        M.IsTraitInstance
          "core::ops::unsize::CoerceUnsized"
          (Self T U)
          (* Trait polymorphic types *)
          [ (* T *) Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ U ] ]
          (* Instance *) [].
    End Impl_core_ops_unsize_CoerceUnsized_where_core_marker_Sized_T_where_core_marker_Sized_U_where_core_marker_Unsize_T_U_core_ptr_unique_Unique_U_for_core_ptr_unique_Unique_T.
    
    Module Impl_core_ops_unsize_DispatchFromDyn_where_core_marker_Sized_T_where_core_marker_Sized_U_where_core_marker_Unsize_T_U_core_ptr_unique_Unique_U_for_core_ptr_unique_Unique_T.
      Definition Self (T U : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ T ].
      
      Axiom Implements :
        forall (T U : Ty.t),
        M.IsTraitInstance
          "core::ops::unsize::DispatchFromDyn"
          (Self T U)
          (* Trait polymorphic types *)
          [ (* T *) Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ U ] ]
          (* Instance *) [].
    End Impl_core_ops_unsize_DispatchFromDyn_where_core_marker_Sized_T_where_core_marker_Sized_U_where_core_marker_Unsize_T_U_core_ptr_unique_Unique_U_for_core_ptr_unique_Unique_T.
    
    Module Impl_core_pin_PinCoerceUnsized_where_core_marker_Sized_T_for_core_ptr_unique_Unique_T.
      Definition Self (T : Ty.t) : Ty.t := Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ T ].
      
      Axiom Implements :
        forall (T : Ty.t),
        M.IsTraitInstance
          "core::pin::PinCoerceUnsized"
          (Self T)
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_pin_PinCoerceUnsized_where_core_marker_Sized_T_for_core_ptr_unique_Unique_T.
    
    Module Impl_core_fmt_Debug_where_core_marker_Sized_T_for_core_ptr_unique_Unique_T.
      Definition Self (T : Ty.t) : Ty.t := Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ T ].
      
      (*
          fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
              fmt::Pointer::fmt(&self.as_ptr(), f)
          }
      *)
      Definition fmt (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self T in
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::fmt::Pointer",
                Ty.apply (Ty.path "*mut") [] [ T ],
                [],
                "fmt",
                []
              |),
              [
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ T ],
                      "as_ptr",
                      []
                    |),
                    [ M.read (| M.read (| self |) |) ]
                  |)
                |);
                M.read (| f |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (T : Ty.t),
        M.IsTraitInstance
          "core::fmt::Debug"
          (Self T)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method (fmt T)) ].
    End Impl_core_fmt_Debug_where_core_marker_Sized_T_for_core_ptr_unique_Unique_T.
    
    Module Impl_core_fmt_Pointer_where_core_marker_Sized_T_for_core_ptr_unique_Unique_T.
      Definition Self (T : Ty.t) : Ty.t := Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ T ].
      
      (*
          fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
              fmt::Pointer::fmt(&self.as_ptr(), f)
          }
      *)
      Definition fmt (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self T in
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::fmt::Pointer",
                Ty.apply (Ty.path "*mut") [] [ T ],
                [],
                "fmt",
                []
              |),
              [
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ T ],
                      "as_ptr",
                      []
                    |),
                    [ M.read (| M.read (| self |) |) ]
                  |)
                |);
                M.read (| f |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (T : Ty.t),
        M.IsTraitInstance
          "core::fmt::Pointer"
          (Self T)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method (fmt T)) ].
    End Impl_core_fmt_Pointer_where_core_marker_Sized_T_for_core_ptr_unique_Unique_T.
    
    Module Impl_core_convert_From_where_core_marker_Sized_T_ref_mut_T_for_core_ptr_unique_Unique_T.
      Definition Self (T : Ty.t) : Ty.t := Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ T ].
      
      (*
          fn from(reference: &mut T) -> Self {
              Self::from(NonNull::from(reference))
          }
      *)
      Definition from (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self T in
        match ε, τ, α with
        | [], [], [ reference ] =>
          ltac:(M.monadic
            (let reference := M.alloc (| reference |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::convert::From",
                Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ T ],
                [ Ty.apply (Ty.path "core::ptr::non_null::NonNull") [] [ T ] ],
                "from",
                []
              |),
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::convert::From",
                    Ty.apply (Ty.path "core::ptr::non_null::NonNull") [] [ T ],
                    [ Ty.apply (Ty.path "&mut") [] [ T ] ],
                    "from",
                    []
                  |),
                  [ M.read (| reference |) ]
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (T : Ty.t),
        M.IsTraitInstance
          "core::convert::From"
          (Self T)
          (* Trait polymorphic types *) [ (* T *) Ty.apply (Ty.path "&mut") [] [ T ] ]
          (* Instance *) [ ("from", InstanceField.Method (from T)) ].
    End Impl_core_convert_From_where_core_marker_Sized_T_ref_mut_T_for_core_ptr_unique_Unique_T.
    
    Module Impl_core_convert_From_where_core_marker_Sized_T_core_ptr_non_null_NonNull_T_for_core_ptr_unique_Unique_T.
      Definition Self (T : Ty.t) : Ty.t := Ty.apply (Ty.path "core::ptr::unique::Unique") [] [ T ].
      
      (*
          fn from(pointer: NonNull<T>) -> Self {
              Unique { pointer, _marker: PhantomData }
          }
      *)
      Definition from (T : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self T in
        match ε, τ, α with
        | [], [], [ pointer ] =>
          ltac:(M.monadic
            (let pointer := M.alloc (| pointer |) in
            Value.StructRecord
              "core::ptr::unique::Unique"
              [
                ("pointer", M.read (| pointer |));
                ("_marker", Value.StructTuple "core::marker::PhantomData" [])
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (T : Ty.t),
        M.IsTraitInstance
          "core::convert::From"
          (Self T)
          (* Trait polymorphic types *)
          [ (* T *) Ty.apply (Ty.path "core::ptr::non_null::NonNull") [] [ T ] ]
          (* Instance *) [ ("from", InstanceField.Method (from T)) ].
    End Impl_core_convert_From_where_core_marker_Sized_T_core_ptr_non_null_NonNull_T_for_core_ptr_unique_Unique_T.
  End unique.
End ptr.
