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

Module any.
  (* Trait *)
  (* Empty module 'Any' *)
  
  Module Impl_core_any_Any_where_core_marker_Sized_T_for_T.
    Definition Self (T : Ty.t) : Ty.t := T.
    
    (*
        fn type_id(&self) -> TypeId {
            TypeId::of::<T>()
        }
    *)
    Definition type_id (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.path "core::any::TypeId", "of", [ T ] |),
            []
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (T : Ty.t),
      M.IsTraitInstance
        "core::any::Any"
        (Self T)
        (* Trait polymorphic types *) []
        (* Instance *) [ ("type_id", InstanceField.Method (type_id T)) ].
  End Impl_core_any_Any_where_core_marker_Sized_T_for_T.
  
  Module Impl_core_fmt_Debug_for_Dyn_core_any_Any_Trait.
    Definition Self : Ty.t := Ty.dyn [ ("core::any::Any::Trait", []) ].
    
    (*
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("Any").finish_non_exhaustive()
        }
    *)
    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::builders::DebugStruct",
              "finish_non_exhaustive",
              []
            |),
            [
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path "core::fmt::Formatter",
                    "debug_struct",
                    []
                  |),
                  [ M.read (| f |); M.read (| Value.String "Any" |) ]
                |)
              |)
            ]
          |)))
      | _, _, _ => 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_Dyn_core_any_Any_Trait.
  
  Module Impl_core_fmt_Debug_for_Dyn_core_any_Any_Trait_core_marker_Send_AutoTrait.
    Definition Self : Ty.t :=
      Ty.dyn [ ("core::any::Any::Trait", []); ("core::marker::Send::AutoTrait", []) ].
    
    (*
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("Any").finish_non_exhaustive()
        }
    *)
    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::builders::DebugStruct",
              "finish_non_exhaustive",
              []
            |),
            [
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path "core::fmt::Formatter",
                    "debug_struct",
                    []
                  |),
                  [ M.read (| f |); M.read (| Value.String "Any" |) ]
                |)
              |)
            ]
          |)))
      | _, _, _ => 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_Dyn_core_any_Any_Trait_core_marker_Send_AutoTrait.
  
  Module Impl_core_fmt_Debug_for_Dyn_core_any_Any_Trait_core_marker_Send_AutoTrait_core_marker_Sync_AutoTrait.
    Definition Self : Ty.t :=
      Ty.dyn
        [
          ("core::any::Any::Trait", []);
          ("core::marker::Send::AutoTrait", []);
          ("core::marker::Sync::AutoTrait", [])
        ].
    
    (*
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            f.debug_struct("Any").finish_non_exhaustive()
        }
    *)
    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::builders::DebugStruct",
              "finish_non_exhaustive",
              []
            |),
            [
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path "core::fmt::Formatter",
                    "debug_struct",
                    []
                  |),
                  [ M.read (| f |); M.read (| Value.String "Any" |) ]
                |)
              |)
            ]
          |)))
      | _, _, _ => 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_Dyn_core_any_Any_Trait_core_marker_Send_AutoTrait_core_marker_Sync_AutoTrait.
  
  Module Impl_Dyn_core_any_Any_Trait.
    Definition Self : Ty.t := Ty.dyn [ ("core::any::Any::Trait", []) ].
    
    (*
        pub fn is<T: Any>(&self) -> bool {
            // Get `TypeId` of the type this function is instantiated with.
            let t = TypeId::of::<T>();
    
            // Get `TypeId` of the type in the trait object (`self`).
            let concrete = self.type_id();
    
            // Compare both `TypeId`s on equality.
            t == concrete
        }
    *)
    Definition is (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ t :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (| Ty.path "core::any::TypeId", "of", [ T ] |),
                  []
                |)
              |) in
            let~ concrete :=
              M.alloc (|
                M.call_closure (|
                  M.get_trait_method (|
                    "core::any::Any",
                    Ty.dyn [ ("core::any::Any::Trait", []) ],
                    [],
                    "type_id",
                    []
                  |),
                  [ M.read (| self |) ]
                |)
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_trait_method (|
                  "core::cmp::PartialEq",
                  Ty.path "core::any::TypeId",
                  [ Ty.path "core::any::TypeId" ],
                  "eq",
                  []
                |),
                [ t; concrete ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is : M.IsAssociatedFunction Self "is" is.
    
    (*
        pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
            if self.is::<T>() {
                // SAFETY: just checked whether we are pointing to the correct type, and we can rely on
                // that check for memory safety because we have implemented Any for all types; no other
                // impls can exist as they would conflict with our impl.
                unsafe { Some(self.downcast_ref_unchecked()) }
            } else {
                None
            }
        }
    *)
    Definition downcast_ref (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.dyn [ ("core::any::Any::Trait", []) ],
                              "is",
                              [ T ]
                            |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.dyn [ ("core::any::Any::Trait", []) ],
                              "downcast_ref_unchecked",
                              [ T ]
                            |),
                            [ M.read (| self |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_downcast_ref : M.IsAssociatedFunction Self "downcast_ref" downcast_ref.
    
    (*
        pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
            if self.is::<T>() {
                // SAFETY: just checked whether we are pointing to the correct type, and we can rely on
                // that check for memory safety because we have implemented Any for all types; no other
                // impls can exist as they would conflict with our impl.
                unsafe { Some(self.downcast_mut_unchecked()) }
            } else {
                None
            }
        }
    *)
    Definition downcast_mut (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ :=
                      M.use
                        (M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.dyn [ ("core::any::Any::Trait", []) ],
                              "is",
                              [ T ]
                            |),
                            [ M.read (| self |) ]
                          |)
                        |)) in
                    let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                    M.alloc (|
                      Value.StructTuple
                        "core::option::Option::Some"
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.dyn [ ("core::any::Any::Trait", []) ],
                              "downcast_mut_unchecked",
                              [ T ]
                            |),
                            [ M.read (| self |) ]
                          |)
                        ]
                    |)));
                fun γ =>
                  ltac:(M.monadic (M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_downcast_mut : M.IsAssociatedFunction Self "downcast_mut" downcast_mut.
    
    (*
        pub unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T {
            debug_assert!(self.is::<T>());
            // SAFETY: caller guarantees that T is the correct type
            unsafe { &*(self as *const dyn Any as *const T) }
        }
    *)
    Definition downcast_ref_unchecked (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.use (M.alloc (| Value.Bool true |)) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      let~ _ :=
                        M.match_operator (|
                          M.alloc (| Value.Tuple [] |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ :=
                                  M.use
                                    (M.alloc (|
                                      UnOp.not (|
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.dyn [ ("core::any::Any::Trait", []) ],
                                            "is",
                                            [ T ]
                                          |),
                                          [ M.read (| self |) ]
                                        |)
                                      |)
                                    |)) in
                                let _ :=
                                  M.is_constant_or_break_match (|
                                    M.read (| γ |),
                                    Value.Bool true
                                  |) in
                                M.alloc (|
                                  M.never_to_any (|
                                    M.call_closure (|
                                      M.get_function (| "core::panicking::panic", [] |),
                                      [ M.read (| Value.String "assertion failed: self.is::<T>()" |)
                                      ]
                                    |)
                                  |)
                                |)));
                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                          ]
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (| M.rust_cast (M.read (| M.use (M.alloc (| M.read (| self |) |)) |)) |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_downcast_ref_unchecked :
      M.IsAssociatedFunction Self "downcast_ref_unchecked" downcast_ref_unchecked.
    
    (*
        pub unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T {
            debug_assert!(self.is::<T>());
            // SAFETY: caller guarantees that T is the correct type
            unsafe { &mut *(self as *mut dyn Any as *mut T) }
        }
    *)
    Definition downcast_mut_unchecked (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.use (M.alloc (| Value.Bool true |)) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      let~ _ :=
                        M.match_operator (|
                          M.alloc (| Value.Tuple [] |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ :=
                                  M.use
                                    (M.alloc (|
                                      UnOp.not (|
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.dyn [ ("core::any::Any::Trait", []) ],
                                            "is",
                                            [ T ]
                                          |),
                                          [ M.read (| self |) ]
                                        |)
                                      |)
                                    |)) in
                                let _ :=
                                  M.is_constant_or_break_match (|
                                    M.read (| γ |),
                                    Value.Bool true
                                  |) in
                                M.alloc (|
                                  M.never_to_any (|
                                    M.call_closure (|
                                      M.get_function (| "core::panicking::panic", [] |),
                                      [ M.read (| Value.String "assertion failed: self.is::<T>()" |)
                                      ]
                                    |)
                                  |)
                                |)));
                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                          ]
                        |) in
                      M.alloc (| Value.Tuple [] |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            M.alloc (| M.rust_cast (M.read (| M.use (M.alloc (| M.read (| self |) |)) |)) |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_downcast_mut_unchecked :
      M.IsAssociatedFunction Self "downcast_mut_unchecked" downcast_mut_unchecked.
  End Impl_Dyn_core_any_Any_Trait.
  
  Module Impl_Dyn_core_any_Any_Trait_core_marker_Send_AutoTrait.
    Definition Self : Ty.t :=
      Ty.dyn [ ("core::any::Any::Trait", []); ("core::marker::Send::AutoTrait", []) ].
    
    (*
        pub fn is<T: Any>(&self) -> bool {
            <dyn Any>::is::<T>(self)
        }
    *)
    Definition is (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.dyn [ ("core::any::Any::Trait", []) ], "is", [ T ] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is : M.IsAssociatedFunction Self "is" is.
    
    (*
        pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
            <dyn Any>::downcast_ref::<T>(self)
        }
    *)
    Definition downcast_ref (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.dyn [ ("core::any::Any::Trait", []) ],
              "downcast_ref",
              [ T ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_downcast_ref : M.IsAssociatedFunction Self "downcast_ref" downcast_ref.
    
    (*
        pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
            <dyn Any>::downcast_mut::<T>(self)
        }
    *)
    Definition downcast_mut (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.dyn [ ("core::any::Any::Trait", []) ],
              "downcast_mut",
              [ T ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_downcast_mut : M.IsAssociatedFunction Self "downcast_mut" downcast_mut.
    
    (*
        pub unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T {
            // SAFETY: guaranteed by caller
            unsafe { <dyn Any>::downcast_ref_unchecked::<T>(self) }
        }
    *)
    Definition downcast_ref_unchecked (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.dyn [ ("core::any::Any::Trait", []) ],
              "downcast_ref_unchecked",
              [ T ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_downcast_ref_unchecked :
      M.IsAssociatedFunction Self "downcast_ref_unchecked" downcast_ref_unchecked.
    
    (*
        pub unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T {
            // SAFETY: guaranteed by caller
            unsafe { <dyn Any>::downcast_mut_unchecked::<T>(self) }
        }
    *)
    Definition downcast_mut_unchecked (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.dyn [ ("core::any::Any::Trait", []) ],
              "downcast_mut_unchecked",
              [ T ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_downcast_mut_unchecked :
      M.IsAssociatedFunction Self "downcast_mut_unchecked" downcast_mut_unchecked.
  End Impl_Dyn_core_any_Any_Trait_core_marker_Send_AutoTrait.
  
  Module Impl_Dyn_core_any_Any_Trait_core_marker_Send_AutoTrait_core_marker_Sync_AutoTrait.
    Definition Self : Ty.t :=
      Ty.dyn
        [
          ("core::any::Any::Trait", []);
          ("core::marker::Send::AutoTrait", []);
          ("core::marker::Sync::AutoTrait", [])
        ].
    
    (*
        pub fn is<T: Any>(&self) -> bool {
            <dyn Any>::is::<T>(self)
        }
    *)
    Definition is (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (| Ty.dyn [ ("core::any::Any::Trait", []) ], "is", [ T ] |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is : M.IsAssociatedFunction Self "is" is.
    
    (*
        pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
            <dyn Any>::downcast_ref::<T>(self)
        }
    *)
    Definition downcast_ref (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.dyn [ ("core::any::Any::Trait", []) ],
              "downcast_ref",
              [ T ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_downcast_ref : M.IsAssociatedFunction Self "downcast_ref" downcast_ref.
    
    (*
        pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
            <dyn Any>::downcast_mut::<T>(self)
        }
    *)
    Definition downcast_mut (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.dyn [ ("core::any::Any::Trait", []) ],
              "downcast_mut",
              [ T ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_downcast_mut : M.IsAssociatedFunction Self "downcast_mut" downcast_mut.
    
    (*
        pub unsafe fn downcast_ref_unchecked<T: Any>(&self) -> &T {
            // SAFETY: guaranteed by caller
            unsafe { <dyn Any>::downcast_ref_unchecked::<T>(self) }
        }
    *)
    Definition downcast_ref_unchecked (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.dyn [ ("core::any::Any::Trait", []) ],
              "downcast_ref_unchecked",
              [ T ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_downcast_ref_unchecked :
      M.IsAssociatedFunction Self "downcast_ref_unchecked" downcast_ref_unchecked.
    
    (*
        pub unsafe fn downcast_mut_unchecked<T: Any>(&mut self) -> &mut T {
            // SAFETY: guaranteed by caller
            unsafe { <dyn Any>::downcast_mut_unchecked::<T>(self) }
        }
    *)
    Definition downcast_mut_unchecked (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.dyn [ ("core::any::Any::Trait", []) ],
              "downcast_mut_unchecked",
              [ T ]
            |),
            [ M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_downcast_mut_unchecked :
      M.IsAssociatedFunction Self "downcast_mut_unchecked" downcast_mut_unchecked.
  End Impl_Dyn_core_any_Any_Trait_core_marker_Send_AutoTrait_core_marker_Sync_AutoTrait.
  
  (* StructRecord
    {
      name := "TypeId";
      const_params := [];
      ty_params := [];
      fields := [ ("t", Ty.tuple [ Ty.path "u64"; Ty.path "u64" ]) ];
    } *)
  
  Module Impl_core_clone_Clone_for_core_any_TypeId.
    Definition Self : Ty.t := Ty.path "core::any::TypeId".
    
    (* 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.match_operator (|
              Value.DeclaredButUndefined,
              [ fun γ => ltac:(M.monadic (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_core_any_TypeId.
  
  Module Impl_core_marker_Copy_for_core_any_TypeId.
    Definition Self : Ty.t := Ty.path "core::any::TypeId".
    
    Axiom Implements :
      M.IsTraitInstance
        "core::marker::Copy"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [].
  End Impl_core_marker_Copy_for_core_any_TypeId.
  
  Module Impl_core_cmp_Eq_for_core_any_TypeId.
    Definition Self : Ty.t := Ty.path "core::any::TypeId".
    
    (* 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
          M.read (|
            M.match_operator (|
              Value.DeclaredButUndefined,
              [ fun γ => ltac:(M.monadic (M.alloc (| 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_core_any_TypeId.
  
  Module Impl_core_cmp_PartialOrd_for_core_any_TypeId.
    Definition Self : Ty.t := Ty.path "core::any::TypeId".
    
    (* PartialOrd *)
    Definition partial_cmp (ε : 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.call_closure (|
            M.get_trait_method (|
              "core::cmp::PartialOrd",
              Ty.tuple [ Ty.path "u64"; Ty.path "u64" ],
              [ Ty.tuple [ Ty.path "u64"; Ty.path "u64" ] ],
              "partial_cmp",
              []
            |),
            [
              M.SubPointer.get_struct_record_field (|
                M.read (| self |),
                "core::any::TypeId",
                "t"
              |);
              M.SubPointer.get_struct_record_field (|
                M.read (| other |),
                "core::any::TypeId",
                "t"
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::cmp::PartialOrd"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("partial_cmp", InstanceField.Method partial_cmp) ].
  End Impl_core_cmp_PartialOrd_for_core_any_TypeId.
  
  Module Impl_core_cmp_Ord_for_core_any_TypeId.
    Definition Self : Ty.t := Ty.path "core::any::TypeId".
    
    (* Ord *)
    Definition cmp (ε : 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.call_closure (|
            M.get_trait_method (|
              "core::cmp::Ord",
              Ty.tuple [ Ty.path "u64"; Ty.path "u64" ],
              [],
              "cmp",
              []
            |),
            [
              M.SubPointer.get_struct_record_field (|
                M.read (| self |),
                "core::any::TypeId",
                "t"
              |);
              M.SubPointer.get_struct_record_field (|
                M.read (| other |),
                "core::any::TypeId",
                "t"
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::cmp::Ord"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("cmp", InstanceField.Method cmp) ].
  End Impl_core_cmp_Ord_for_core_any_TypeId.
  
  Module Impl_core_cmp_PartialEq_for_core_any_TypeId.
    Definition Self : Ty.t := Ty.path "core::any::TypeId".
    
    (*
        fn eq(&self, other: &Self) -> bool {
            self.t == other.t
        }
    *)
    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.call_closure (|
            M.get_trait_method (|
              "core::cmp::PartialEq",
              Ty.tuple [ Ty.path "u64"; Ty.path "u64" ],
              [ Ty.tuple [ Ty.path "u64"; Ty.path "u64" ] ],
              "eq",
              []
            |),
            [
              M.SubPointer.get_struct_record_field (|
                M.read (| self |),
                "core::any::TypeId",
                "t"
              |);
              M.SubPointer.get_struct_record_field (|
                M.read (| other |),
                "core::any::TypeId",
                "t"
              |)
            ]
          |)))
      | _, _, _ => 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_core_any_TypeId.
  
  Module Impl_core_any_TypeId.
    Definition Self : Ty.t := Ty.path "core::any::TypeId".
    
    (*
        pub const fn of<T: ?Sized + 'static>() -> TypeId {
            let t: u128 = intrinsics::type_id::<T>();
    
            let t1 = (t >> 64) as u64;
            let t2 = t as u64;
            TypeId { t: (t1, t2) }
        }
    *)
    Definition of (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ T ], [] =>
        ltac:(M.monadic
          (M.read (|
            let~ t :=
              M.alloc (|
                M.call_closure (| M.get_function (| "core::intrinsics::type_id", [ T ] |), [] |)
              |) in
            let~ t1 :=
              M.alloc (|
                M.rust_cast (BinOp.Wrap.shr (| M.read (| t |), Value.Integer IntegerKind.I32 64 |))
              |) in
            let~ t2 := M.alloc (| M.rust_cast (M.read (| t |)) |) in
            M.alloc (|
              Value.StructRecord
                "core::any::TypeId"
                [ ("t", Value.Tuple [ M.read (| t1 |); M.read (| t2 |) ]) ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_of : M.IsAssociatedFunction Self "of" of.
    
    (*
        fn as_u128(self) -> u128 {
            u128::from(self.t.0) << 64 | u128::from(self.t.1)
        }
    *)
    Definition as_u128 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.bit_or
            (BinOp.Wrap.shl (|
              M.call_closure (|
                M.get_trait_method (|
                  "core::convert::From",
                  Ty.path "u128",
                  [ Ty.path "u64" ],
                  "from",
                  []
                |),
                [
                  M.read (|
                    M.SubPointer.get_tuple_field (|
                      M.SubPointer.get_struct_record_field (| self, "core::any::TypeId", "t" |),
                      0
                    |)
                  |)
                ]
              |),
              Value.Integer IntegerKind.I32 64
            |))
            (M.call_closure (|
              M.get_trait_method (|
                "core::convert::From",
                Ty.path "u128",
                [ Ty.path "u64" ],
                "from",
                []
              |),
              [
                M.read (|
                  M.SubPointer.get_tuple_field (|
                    M.SubPointer.get_struct_record_field (| self, "core::any::TypeId", "t" |),
                    1
                  |)
                |)
              ]
            |))))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_as_u128 : M.IsAssociatedFunction Self "as_u128" as_u128.
  End Impl_core_any_TypeId.
  
  Module Impl_core_hash_Hash_for_core_any_TypeId.
    Definition Self : Ty.t := Ty.path "core::any::TypeId".
    
    (*
        fn hash<H: hash::Hasher>(&self, state: &mut H) {
            // We only hash the lower 64 bits of our (128 bit) internal numeric ID,
            // because:
            // - The hashing algorithm which backs `TypeId` is expected to be
            //   unbiased and high quality, meaning further mixing would be somewhat
            //   redundant compared to choosing (the lower) 64 bits arbitrarily.
            // - `Hasher::finish` returns a u64 anyway, so the extra entropy we'd
            //   get from hashing the full value would probably not be useful
            //   (especially given the previous point about the lower 64 bits being
            //   high quality on their own).
            // - It is correct to do so -- only hashing a subset of `self` is still
            //   with an `Eq` implementation that considers the entire value, as
            //   ours does.
            self.t.1.hash(state);
        }
    *)
    Definition hash (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H ], [ self; state ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let state := M.alloc (| state |) in
          M.read (|
            let~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_trait_method (| "core::hash::Hash", Ty.path "u64", [], "hash", [ H ] |),
                  [
                    M.SubPointer.get_tuple_field (|
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::any::TypeId",
                        "t"
                      |),
                      1
                    |);
                    M.read (| state |)
                  ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      M.IsTraitInstance
        "core::hash::Hash"
        Self
        (* Trait polymorphic types *) []
        (* Instance *) [ ("hash", InstanceField.Method hash) ].
  End Impl_core_hash_Hash_for_core_any_TypeId.
  
  Module Impl_core_fmt_Debug_for_core_any_TypeId.
    Definition Self : Ty.t := Ty.path "core::any::TypeId".
    
    (*
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
            write!(f, "TypeId({:#034x})", self.as_u128())
        }
    *)
    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_fmt", [] |),
            [
              M.read (| f |);
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "core::fmt::Arguments",
                  "new_v1_formatted",
                  []
                |),
                [
                  M.alloc (|
                    Value.Array
                      [ M.read (| Value.String "TypeId(" |); M.read (| Value.String ")" |) ]
                  |);
                  M.alloc (|
                    Value.Array
                      [
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::rt::Argument",
                            "new_lower_hex",
                            [ Ty.path "u128" ]
                          |),
                          [
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path "core::any::TypeId",
                                  "as_u128",
                                  []
                                |),
                                [ M.read (| M.read (| self |) |) ]
                              |)
                            |)
                          ]
                        |)
                      ]
                  |);
                  M.alloc (|
                    Value.Array
                      [
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::rt::Placeholder",
                            "new",
                            []
                          |),
                          [
                            Value.Integer IntegerKind.Usize 0;
                            Value.UnicodeChar 32;
                            Value.StructTuple "core::fmt::rt::Alignment::Unknown" [];
                            Value.Integer IntegerKind.U32 12;
                            Value.StructTuple "core::fmt::rt::Count::Implied" [];
                            Value.StructTuple
                              "core::fmt::rt::Count::Is"
                              [ Value.Integer IntegerKind.Usize 34 ]
                          ]
                        |)
                      ]
                  |);
                  M.call_closure (|
                    M.get_associated_function (| Ty.path "core::fmt::rt::UnsafeArg", "new", [] |),
                    []
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => 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_core_any_TypeId.
  
  (*
  pub const fn type_name<T: ?Sized>() -> &'static str {
      intrinsics::type_name::<T>()
  }
  *)
  Definition type_name (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [ T ], [] =>
      ltac:(M.monadic
        (M.call_closure (| M.get_function (| "core::intrinsics::type_name", [ T ] |), [] |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_type_name : M.IsFunction "core::any::type_name" type_name.
  
  (*
  pub const fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str {
      type_name::<T>()
  }
  *)
  Definition type_name_of_val (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [ T ], [ _val ] =>
      ltac:(M.monadic
        (let _val := M.alloc (| _val |) in
        M.call_closure (| M.get_function (| "core::any::type_name", [ T ] |), [] |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_type_name_of_val : M.IsFunction "core::any::type_name_of_val" type_name_of_val.
End any.
