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

Module ptr.
  Module metadata.
    (* Trait *)
    (* Empty module 'Pointee' *)
    
    (* Error TraitAlias *)
    
    (*
    pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
        ptr_metadata(ptr)
    }
    *)
    Definition metadata (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ ptr ] =>
        ltac:(M.monadic
          (let ptr := M.alloc (| ptr |) in
          M.call_closure (|
            M.get_function (| "core::intrinsics::ptr_metadata", [ T; Ty.associated ] |),
            [ M.read (| ptr |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_metadata : M.IsFunction "core::ptr::metadata::metadata" metadata.
    
    (*
    pub const fn from_raw_parts<T: ?Sized>(
        data_pointer: *const impl Thin,
        metadata: <T as Pointee>::Metadata,
    ) -> *const T {
        aggregate_raw_ptr(data_pointer, metadata)
    }
    *)
    Definition from_raw_parts (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T; impl_Thin ], [ data_pointer; metadata ] =>
        ltac:(M.monadic
          (let data_pointer := M.alloc (| data_pointer |) in
          let metadata := M.alloc (| metadata |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::aggregate_raw_ptr",
              [
                Ty.apply (Ty.path "*const") [] [ T ];
                Ty.apply (Ty.path "*const") [] [ impl_Thin ];
                Ty.associated
              ]
            |),
            [ M.read (| data_pointer |); M.read (| metadata |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_from_raw_parts :
      M.IsFunction "core::ptr::metadata::from_raw_parts" from_raw_parts.
    
    (*
    pub const fn from_raw_parts_mut<T: ?Sized>(
        data_pointer: *mut impl Thin,
        metadata: <T as Pointee>::Metadata,
    ) -> *mut T {
        aggregate_raw_ptr(data_pointer, metadata)
    }
    *)
    Definition from_raw_parts_mut (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T; impl_Thin ], [ data_pointer; metadata ] =>
        ltac:(M.monadic
          (let data_pointer := M.alloc (| data_pointer |) in
          let metadata := M.alloc (| metadata |) in
          M.call_closure (|
            M.get_function (|
              "core::intrinsics::aggregate_raw_ptr",
              [
                Ty.apply (Ty.path "*mut") [] [ T ];
                Ty.apply (Ty.path "*mut") [] [ impl_Thin ];
                Ty.associated
              ]
            |),
            [ M.read (| data_pointer |); M.read (| metadata |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_from_raw_parts_mut :
      M.IsFunction "core::ptr::metadata::from_raw_parts_mut" from_raw_parts_mut.
    
    (* StructRecord
      {
        name := "DynMetadata";
        const_params := [];
        ty_params := [ "Dyn" ];
        fields :=
          [
            ("_vtable_ptr",
              Ty.apply
                (Ty.path "core::ptr::non_null::NonNull")
                []
                [ Ty.path "core::ptr::metadata::VTable" ]);
            ("_phantom", Ty.apply (Ty.path "core::marker::PhantomData") [] [ Dyn ])
          ];
      } *)
    
    (* Foreign type 'VTable' *)
    
    Module Impl_core_ptr_metadata_DynMetadata_Dyn.
      Definition Self (Dyn : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ].
      
      (*
          fn vtable_ptr(self) -> *const VTable {
              // SAFETY: this layout assumption is hard-coded into the compiler.
              // If it's somehow not a size match, the transmute will error.
              unsafe { crate::mem::transmute::<Self, *const VTable>(self) }
          }
      *)
      Definition vtable_ptr
          (Dyn : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self Dyn in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_function (|
                "core::intrinsics::transmute",
                [
                  Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ];
                  Ty.apply (Ty.path "*const") [] [ Ty.path "core::ptr::metadata::VTable" ]
                ]
              |),
              [ M.read (| self |) ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_vtable_ptr :
        forall (Dyn : Ty.t),
        M.IsAssociatedFunction (Self Dyn) "vtable_ptr" (vtable_ptr Dyn).
      
      (*
          pub fn size_of(self) -> usize {
              // Note that "size stored in vtable" is *not* the same as "result of size_of_val_raw".
              // Consider a reference like `&(i32, dyn Send)`: the vtable will only store the size of the
              // `Send` part!
              // SAFETY: DynMetadata always contains a valid vtable pointer
              unsafe { crate::intrinsics::vtable_size(self.vtable_ptr() as *const ()) }
          }
      *)
      Definition size_of (Dyn : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self Dyn in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_function (| "core::intrinsics::vtable_size", [] |),
              [
                M.rust_cast
                  (M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ],
                      "vtable_ptr",
                      []
                    |),
                    [ M.read (| self |) ]
                  |))
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_size_of :
        forall (Dyn : Ty.t),
        M.IsAssociatedFunction (Self Dyn) "size_of" (size_of Dyn).
      
      (*
          pub fn align_of(self) -> usize {
              // SAFETY: DynMetadata always contains a valid vtable pointer
              unsafe { crate::intrinsics::vtable_align(self.vtable_ptr() as *const ()) }
          }
      *)
      Definition align_of (Dyn : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self Dyn in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_function (| "core::intrinsics::vtable_align", [] |),
              [
                M.rust_cast
                  (M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ],
                      "vtable_ptr",
                      []
                    |),
                    [ M.read (| self |) ]
                  |))
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_align_of :
        forall (Dyn : Ty.t),
        M.IsAssociatedFunction (Self Dyn) "align_of" (align_of Dyn).
      
      (*
          pub fn layout(self) -> crate::alloc::Layout {
              // SAFETY: the compiler emitted this vtable for a concrete Rust type which
              // is known to have a valid layout. Same rationale as in `Layout::for_value`.
              unsafe { crate::alloc::Layout::from_size_align_unchecked(self.size_of(), self.align_of()) }
          }
      *)
      Definition layout (Dyn : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self Dyn in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "core::alloc::layout::Layout",
                "from_size_align_unchecked",
                []
              |),
              [
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ],
                    "size_of",
                    []
                  |),
                  [ M.read (| self |) ]
                |);
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ],
                    "align_of",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_layout :
        forall (Dyn : Ty.t),
        M.IsAssociatedFunction (Self Dyn) "layout" (layout Dyn).
    End Impl_core_ptr_metadata_DynMetadata_Dyn.
    
    Module Impl_core_marker_Send_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
      Definition Self (Dyn : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ].
      
      Axiom Implements :
        forall (Dyn : Ty.t),
        M.IsTraitInstance
          "core::marker::Send"
          (Self Dyn)
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_marker_Send_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
    
    Module Impl_core_marker_Sync_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
      Definition Self (Dyn : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ].
      
      Axiom Implements :
        forall (Dyn : Ty.t),
        M.IsTraitInstance
          "core::marker::Sync"
          (Self Dyn)
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_marker_Sync_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
    
    Module Impl_core_fmt_Debug_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
      Definition Self (Dyn : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ].
      
      (*
          fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
              f.debug_tuple("DynMetadata").field(&self.vtable_ptr()).finish()
          }
      *)
      Definition fmt (Dyn : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self Dyn 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_associated_function (|
                Ty.path "core::fmt::builders::DebugTuple",
                "finish",
                []
              |),
              [
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path "core::fmt::builders::DebugTuple",
                    "field",
                    []
                  |),
                  [
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path "core::fmt::Formatter",
                          "debug_tuple",
                          []
                        |),
                        [ M.read (| f |); M.read (| Value.String "DynMetadata" |) ]
                      |)
                    |);
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ],
                          "vtable_ptr",
                          []
                        |),
                        [ M.read (| M.read (| self |) |) ]
                      |)
                    |)
                  ]
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (Dyn : Ty.t),
        M.IsTraitInstance
          "core::fmt::Debug"
          (Self Dyn)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method (fmt Dyn)) ].
    End Impl_core_fmt_Debug_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
    
    Module Impl_core_marker_Unpin_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
      Definition Self (Dyn : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ].
      
      Axiom Implements :
        forall (Dyn : Ty.t),
        M.IsTraitInstance
          "core::marker::Unpin"
          (Self Dyn)
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_marker_Unpin_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
    
    Module Impl_core_marker_Copy_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
      Definition Self (Dyn : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ].
      
      Axiom Implements :
        forall (Dyn : Ty.t),
        M.IsTraitInstance
          "core::marker::Copy"
          (Self Dyn)
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_marker_Copy_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
    
    Module Impl_core_clone_Clone_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
      Definition Self (Dyn : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ].
      
      (*
          fn clone(&self) -> Self {
              *self
          }
      *)
      Definition clone (Dyn : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self Dyn 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 (Dyn : Ty.t),
        M.IsTraitInstance
          "core::clone::Clone"
          (Self Dyn)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method (clone Dyn)) ].
    End Impl_core_clone_Clone_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
    
    Module Impl_core_cmp_Eq_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
      Definition Self (Dyn : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ].
      
      Axiom Implements :
        forall (Dyn : Ty.t),
        M.IsTraitInstance
          "core::cmp::Eq"
          (Self Dyn)
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_cmp_Eq_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
    
    Module Impl_core_cmp_PartialEq_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
      Definition Self (Dyn : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ].
      
      (*
          fn eq(&self, other: &Self) -> bool {
              crate::ptr::eq::<VTable>(self.vtable_ptr(), other.vtable_ptr())
          }
      *)
      Definition eq (Dyn : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self Dyn in
        match ε, τ, α with
        | [], [], [ self; other ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let other := M.alloc (| other |) in
            M.call_closure (|
              M.get_function (| "core::ptr::eq", [ Ty.path "core::ptr::metadata::VTable" ] |),
              [
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ],
                    "vtable_ptr",
                    []
                  |),
                  [ M.read (| M.read (| self |) |) ]
                |);
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ],
                    "vtable_ptr",
                    []
                  |),
                  [ M.read (| M.read (| other |) |) ]
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (Dyn : Ty.t),
        M.IsTraitInstance
          "core::cmp::PartialEq"
          (Self Dyn)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("eq", InstanceField.Method (eq Dyn)) ].
    End Impl_core_cmp_PartialEq_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
    
    Module Impl_core_cmp_Ord_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
      Definition Self (Dyn : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ].
      
      (*
          fn cmp(&self, other: &Self) -> crate::cmp::Ordering {
              <*const VTable>::cmp(&self.vtable_ptr(), &other.vtable_ptr())
          }
      *)
      Definition cmp (Dyn : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self Dyn in
        match ε, τ, α with
        | [], [], [ self; other ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let other := M.alloc (| other |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::cmp::Ord",
                Ty.apply (Ty.path "*const") [] [ Ty.path "core::ptr::metadata::VTable" ],
                [],
                "cmp",
                []
              |),
              [
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ],
                      "vtable_ptr",
                      []
                    |),
                    [ M.read (| M.read (| self |) |) ]
                  |)
                |);
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ],
                      "vtable_ptr",
                      []
                    |),
                    [ M.read (| M.read (| other |) |) ]
                  |)
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (Dyn : Ty.t),
        M.IsTraitInstance
          "core::cmp::Ord"
          (Self Dyn)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("cmp", InstanceField.Method (cmp Dyn)) ].
    End Impl_core_cmp_Ord_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
    
    Module Impl_core_cmp_PartialOrd_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
      Definition Self (Dyn : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ].
      
      (*
          fn partial_cmp(&self, other: &Self) -> Option<crate::cmp::Ordering> {
              Some(self.cmp(other))
          }
      *)
      Definition partial_cmp
          (Dyn : Ty.t)
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        let Self : Ty.t := Self Dyn in
        match ε, τ, α with
        | [], [], [ self; other ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let other := M.alloc (| other |) in
            Value.StructTuple
              "core::option::Option::Some"
              [
                M.call_closure (|
                  M.get_trait_method (|
                    "core::cmp::Ord",
                    Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ],
                    [],
                    "cmp",
                    []
                  |),
                  [ M.read (| self |); M.read (| other |) ]
                |)
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (Dyn : Ty.t),
        M.IsTraitInstance
          "core::cmp::PartialOrd"
          (Self Dyn)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("partial_cmp", InstanceField.Method (partial_cmp Dyn)) ].
    End Impl_core_cmp_PartialOrd_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
    
    Module Impl_core_hash_Hash_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
      Definition Self (Dyn : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ].
      
      (*
          fn hash<H: Hasher>(&self, hasher: &mut H) {
              crate::ptr::hash::<VTable, _>(self.vtable_ptr(), hasher)
          }
      *)
      Definition hash (Dyn : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self Dyn in
        match ε, τ, α with
        | [], [ H ], [ self; hasher ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let hasher := M.alloc (| hasher |) in
            M.call_closure (|
              M.get_function (| "core::ptr::hash", [ Ty.path "core::ptr::metadata::VTable"; H ] |),
              [
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "core::ptr::metadata::DynMetadata") [] [ Dyn ],
                    "vtable_ptr",
                    []
                  |),
                  [ M.read (| M.read (| self |) |) ]
                |);
                M.read (| hasher |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (Dyn : Ty.t),
        M.IsTraitInstance
          "core::hash::Hash"
          (Self Dyn)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("hash", InstanceField.Method (hash Dyn)) ].
    End Impl_core_hash_Hash_where_core_marker_Sized_Dyn_for_core_ptr_metadata_DynMetadata_Dyn.
  End metadata.
End ptr.
