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

Module panicking.
  (*
  pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
      if cfg!(feature = "panic_immediate_abort") {
          super::intrinsics::abort()
      }
  
      // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
      // that gets resolved to the `#[panic_handler]` function.
      extern "Rust" {
          #[lang = "panic_impl"]
          fn panic_impl(pi: &PanicInfo<'_>) -> !;
      }
  
      let pi = PanicInfo::new(
          &fmt,
          Location::caller(),
          /* can_unwind */ true,
          /* force_no_backtrace */ false,
      );
  
      // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
      unsafe { panic_impl(&pi) }
  }
  *)
  Definition panic_fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ fmt ] =>
      ltac:(M.monadic
        (let fmt := M.alloc (| fmt |) in
        M.read (|
          let~ _ :=
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := M.use (M.alloc (| Value.Bool false |)) 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::intrinsics::abort", [] |), [] |)
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
              ]
            |) in
          let~ pi :=
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "core::panic::panic_info::PanicInfo",
                  "new",
                  []
                |),
                [
                  fmt;
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path "core::panic::location::Location",
                      "caller",
                      []
                    |),
                    []
                  |);
                  Value.Bool true;
                  Value.Bool false
                ]
              |)
            |) in
          M.alloc (|
            M.call_closure (|
              M.get_function (| "core::panicking::panic_fmt::panic_impl", [] |),
              [ pi ]
            |)
          |)
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_panic_fmt : M.IsFunction "core::panicking::panic_fmt" panic_fmt.
  
  Module panic_fmt.
    Parameter panic_impl : (list Value.t) -> (list Ty.t) -> (list Value.t) -> M.
    
    Axiom Function_panic_impl : M.IsFunction "core::panicking::panic_fmt::panic_impl" panic_impl.
  End panic_fmt.
  
  (*
  pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: bool) -> ! {
      #[inline] // this should always be inlined into `panic_nounwind_fmt`
      #[track_caller]
      fn runtime(fmt: fmt::Arguments<'_>, force_no_backtrace: bool) -> ! {
          if cfg!(feature = "panic_immediate_abort") {
              super::intrinsics::abort()
          }
  
          // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
          // that gets resolved to the `#[panic_handler]` function.
          extern "Rust" {
              #[lang = "panic_impl"]
              fn panic_impl(pi: &PanicInfo<'_>) -> !;
          }
  
          // PanicInfo with the `can_unwind` flag set to false forces an abort.
          let pi = PanicInfo::new(
              &fmt,
              Location::caller(),
              /* can_unwind */ false,
              force_no_backtrace,
          );
  
          // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
          unsafe { panic_impl(&pi) }
      }
  
      #[inline]
      #[track_caller]
      const fn comptime(fmt: fmt::Arguments<'_>, _force_no_backtrace: bool) -> ! {
          // We don't unwind anyway at compile-time so we can call the regular `panic_fmt`.
          panic_fmt(fmt);
      }
  
      super::intrinsics::const_eval_select((fmt, force_no_backtrace), comptime, runtime);
  }
  *)
  Definition panic_nounwind_fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ fmt; force_no_backtrace ] =>
      ltac:(M.monadic
        (let fmt := M.alloc (| fmt |) in
        let force_no_backtrace := M.alloc (| force_no_backtrace |) in
        M.call_closure (|
          M.get_function (|
            "core::intrinsics::const_eval_select",
            [
              Ty.tuple [ Ty.path "core::fmt::Arguments"; Ty.path "bool" ];
              Ty.function [ Ty.path "core::fmt::Arguments"; Ty.path "bool" ] (Ty.path "never");
              Ty.function [ Ty.path "core::fmt::Arguments"; Ty.path "bool" ] (Ty.path "never");
              Ty.path "never"
            ]
          |),
          [
            Value.Tuple [ M.read (| fmt |); M.read (| force_no_backtrace |) ];
            M.get_function (| "core::panicking::panic_nounwind_fmt.comptime", [] |);
            M.get_function (| "core::panicking::panic_nounwind_fmt.runtime", [] |)
          ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_panic_nounwind_fmt :
    M.IsFunction "core::panicking::panic_nounwind_fmt" panic_nounwind_fmt.
  
  Module panic_nounwind_fmt.
    (*
        fn runtime(fmt: fmt::Arguments<'_>, force_no_backtrace: bool) -> ! {
            if cfg!(feature = "panic_immediate_abort") {
                super::intrinsics::abort()
            }
    
            // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
            // that gets resolved to the `#[panic_handler]` function.
            extern "Rust" {
                #[lang = "panic_impl"]
                fn panic_impl(pi: &PanicInfo<'_>) -> !;
            }
    
            // PanicInfo with the `can_unwind` flag set to false forces an abort.
            let pi = PanicInfo::new(
                &fmt,
                Location::caller(),
                /* can_unwind */ false,
                force_no_backtrace,
            );
    
            // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
            unsafe { panic_impl(&pi) }
        }
    *)
    Definition runtime (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ fmt; force_no_backtrace ] =>
        ltac:(M.monadic
          (let fmt := M.alloc (| fmt |) in
          let force_no_backtrace := M.alloc (| force_no_backtrace |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.use (M.alloc (| Value.Bool false |)) 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::intrinsics::abort", [] |),
                            []
                          |)
                        |)
                      |)));
                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                ]
              |) in
            let~ pi :=
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path "core::panic::panic_info::PanicInfo",
                    "new",
                    []
                  |),
                  [
                    fmt;
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "core::panic::location::Location",
                        "caller",
                        []
                      |),
                      []
                    |);
                    Value.Bool false;
                    M.read (| force_no_backtrace |)
                  ]
                |)
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_function (| "core::panicking::panic_nounwind_fmt::runtime::panic_impl", [] |),
                [ pi ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_runtime : M.IsFunction "core::panicking::panic_nounwind_fmt::runtime" runtime.
    
    Module runtime.
      Parameter panic_impl : (list Value.t) -> (list Ty.t) -> (list Value.t) -> M.
      
      Axiom Function_panic_impl :
        M.IsFunction "core::panicking::panic_nounwind_fmt::runtime::panic_impl" panic_impl.
    End runtime.
    
    (*
        const fn comptime(fmt: fmt::Arguments<'_>, _force_no_backtrace: bool) -> ! {
            // We don't unwind anyway at compile-time so we can call the regular `panic_fmt`.
            panic_fmt(fmt);
        }
    *)
    Definition comptime (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ fmt; _force_no_backtrace ] =>
        ltac:(M.monadic
          (let fmt := M.alloc (| fmt |) in
          let _force_no_backtrace := M.alloc (| _force_no_backtrace |) in
          M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [ M.read (| fmt |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_comptime : M.IsFunction "core::panicking::panic_nounwind_fmt::comptime" comptime.
  End panic_nounwind_fmt.
  
  (*
  pub const fn panic(expr: &'static str) -> ! {
      // Use Arguments::new_const instead of format_args!("{expr}") to potentially
      // reduce size overhead. The format_args! macro uses str's Display trait to
      // write expr, which calls Formatter::pad, which must accommodate string
      // truncation and padding (even though none is used here). Using
      // Arguments::new_const may allow the compiler to omit Formatter::pad from the
      // output binary, saving up to a few kilobytes.
      // However, this optimization only works for `'static` strings: `new_const` also makes this
      // message return `Some` from `Arguments::as_str`, which means it can become part of the panic
      // payload without any allocation or copying. Shorter-lived strings would become invalid as
      // stack frames get popped during unwinding, and couldn't be directly referenced from the
      // payload.
      panic_fmt(fmt::Arguments::new_const(&[expr]));
  }
  *)
  Definition panic (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ expr ] =>
      ltac:(M.monadic
        (let expr := M.alloc (| expr |) in
        M.call_closure (|
          M.get_function (| "core::panicking::panic_fmt", [] |),
          [
            M.call_closure (|
              M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
              [ M.alloc (| Value.Array [ M.read (| expr |) ] |) ]
            |)
          ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_panic : M.IsFunction "core::panicking::panic" panic.
  
  Module panic_const.
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_add_overflow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array [ M.read (| Value.String "attempt to add with overflow" |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_add_overflow :
      M.IsFunction
        "core::panicking::panic_const::panic_const_add_overflow"
        panic_const_add_overflow.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_sub_overflow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array [ M.read (| Value.String "attempt to subtract with overflow" |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_sub_overflow :
      M.IsFunction
        "core::panicking::panic_const::panic_const_sub_overflow"
        panic_const_sub_overflow.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_mul_overflow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array [ M.read (| Value.String "attempt to multiply with overflow" |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_mul_overflow :
      M.IsFunction
        "core::panicking::panic_const::panic_const_mul_overflow"
        panic_const_mul_overflow.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_div_overflow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array [ M.read (| Value.String "attempt to divide with overflow" |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_div_overflow :
      M.IsFunction
        "core::panicking::panic_const::panic_const_div_overflow"
        panic_const_div_overflow.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_rem_overflow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array
                      [ M.read (| Value.String "attempt to calculate the remainder with overflow" |)
                      ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_rem_overflow :
      M.IsFunction
        "core::panicking::panic_const::panic_const_rem_overflow"
        panic_const_rem_overflow.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_neg_overflow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array [ M.read (| Value.String "attempt to negate with overflow" |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_neg_overflow :
      M.IsFunction
        "core::panicking::panic_const::panic_const_neg_overflow"
        panic_const_neg_overflow.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_shr_overflow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array [ M.read (| Value.String "attempt to shift right with overflow" |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_shr_overflow :
      M.IsFunction
        "core::panicking::panic_const::panic_const_shr_overflow"
        panic_const_shr_overflow.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_shl_overflow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array [ M.read (| Value.String "attempt to shift left with overflow" |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_shl_overflow :
      M.IsFunction
        "core::panicking::panic_const::panic_const_shl_overflow"
        panic_const_shl_overflow.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_div_by_zero (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array [ M.read (| Value.String "attempt to divide by zero" |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_div_by_zero :
      M.IsFunction "core::panicking::panic_const::panic_const_div_by_zero" panic_const_div_by_zero.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_rem_by_zero (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array
                      [
                        M.read (|
                          Value.String "attempt to calculate the remainder with a divisor of zero"
                        |)
                      ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_rem_by_zero :
      M.IsFunction "core::panicking::panic_const::panic_const_rem_by_zero" panic_const_rem_by_zero.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_coroutine_resumed
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array [ M.read (| Value.String "coroutine resumed after completion" |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_coroutine_resumed :
      M.IsFunction
        "core::panicking::panic_const::panic_const_coroutine_resumed"
        panic_const_coroutine_resumed.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_async_fn_resumed
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array [ M.read (| Value.String "`async fn` resumed after completion" |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_async_fn_resumed :
      M.IsFunction
        "core::panicking::panic_const::panic_const_async_fn_resumed"
        panic_const_async_fn_resumed.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_async_gen_fn_resumed
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array
                      [ M.read (| Value.String "`async gen fn` resumed after completion" |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_async_gen_fn_resumed :
      M.IsFunction
        "core::panicking::panic_const::panic_const_async_gen_fn_resumed"
        panic_const_async_gen_fn_resumed.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_gen_fn_none (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array
                      [
                        M.read (|
                          Value.String "`gen fn` should just keep returning `None` after completion"
                        |)
                      ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_gen_fn_none :
      M.IsFunction "core::panicking::panic_const::panic_const_gen_fn_none" panic_const_gen_fn_none.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_coroutine_resumed_panic
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array [ M.read (| Value.String "coroutine resumed after panicking" |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_coroutine_resumed_panic :
      M.IsFunction
        "core::panicking::panic_const::panic_const_coroutine_resumed_panic"
        panic_const_coroutine_resumed_panic.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_async_fn_resumed_panic
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array [ M.read (| Value.String "`async fn` resumed after panicking" |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_async_fn_resumed_panic :
      M.IsFunction
        "core::panicking::panic_const::panic_const_async_fn_resumed_panic"
        panic_const_async_fn_resumed_panic.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_async_gen_fn_resumed_panic
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array
                      [ M.read (| Value.String "`async gen fn` resumed after panicking" |) ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_async_gen_fn_resumed_panic :
      M.IsFunction
        "core::panicking::panic_const::panic_const_async_gen_fn_resumed_panic"
        panic_const_async_gen_fn_resumed_panic.
    
    (*
                    pub const fn $lang() -> ! {
                        // Use Arguments::new_const instead of format_args!("{expr}") to potentially
                        // reduce size overhead. The format_args! macro uses str's Display trait to
                        // write expr, which calls Formatter::pad, which must accommodate string
                        // truncation and padding (even though none is used here). Using
                        // Arguments::new_const may allow the compiler to omit Formatter::pad from the
                        // output binary, saving up to a few kilobytes.
                        panic_fmt(fmt::Arguments::new_const(&[$message]));
                    }
    *)
    Definition panic_const_gen_fn_none_panic
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_function (| "core::panicking::panic_fmt", [] |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
                [
                  M.alloc (|
                    Value.Array
                      [
                        M.read (|
                          Value.String "`gen fn` should just keep returning `None` after panicking"
                        |)
                      ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_panic_const_gen_fn_none_panic :
      M.IsFunction
        "core::panicking::panic_const::panic_const_gen_fn_none_panic"
        panic_const_gen_fn_none_panic.
  End panic_const.
  
  (*
  pub const fn panic_nounwind(expr: &'static str) -> ! {
      panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]), /* force_no_backtrace */ false);
  }
  *)
  Definition panic_nounwind (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ expr ] =>
      ltac:(M.monadic
        (let expr := M.alloc (| expr |) in
        M.call_closure (|
          M.get_function (| "core::panicking::panic_nounwind_fmt", [] |),
          [
            M.call_closure (|
              M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
              [ M.alloc (| Value.Array [ M.read (| expr |) ] |) ]
            |);
            Value.Bool false
          ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_panic_nounwind : M.IsFunction "core::panicking::panic_nounwind" panic_nounwind.
  
  (*
  pub fn panic_nounwind_nobacktrace(expr: &'static str) -> ! {
      panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]), /* force_no_backtrace */ true);
  }
  *)
  Definition panic_nounwind_nobacktrace (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ expr ] =>
      ltac:(M.monadic
        (let expr := M.alloc (| expr |) in
        M.call_closure (|
          M.get_function (| "core::panicking::panic_nounwind_fmt", [] |),
          [
            M.call_closure (|
              M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_const", [] |),
              [ M.alloc (| Value.Array [ M.read (| expr |) ] |) ]
            |);
            Value.Bool true
          ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_panic_nounwind_nobacktrace :
    M.IsFunction "core::panicking::panic_nounwind_nobacktrace" panic_nounwind_nobacktrace.
  
  (*
  pub const fn panic_explicit() -> ! {
      panic_display(&"explicit panic");
  }
  *)
  Definition panic_explicit (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [] =>
      ltac:(M.monadic
        (M.call_closure (|
          M.get_function (|
            "core::panicking::panic_display",
            [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
          |),
          [ Value.String "explicit panic" ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_panic_explicit : M.IsFunction "core::panicking::panic_explicit" panic_explicit.
  
  (*
  pub fn unreachable_display<T: fmt::Display>(x: &T) -> ! {
      panic_fmt(format_args!("internal error: entered unreachable code: {}", *x));
  }
  *)
  Definition unreachable_display (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [ T ], [ x ] =>
      ltac:(M.monadic
        (let x := M.alloc (| x |) in
        M.call_closure (|
          M.get_function (| "core::panicking::panic_fmt", [] |),
          [
            M.call_closure (|
              M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_v1", [] |),
              [
                M.alloc (|
                  Value.Array
                    [ M.read (| Value.String "internal error: entered unreachable code: " |) ]
                |);
                M.alloc (|
                  Value.Array
                    [
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path "core::fmt::rt::Argument",
                          "new_display",
                          [ T ]
                        |),
                        [ M.read (| x |) ]
                      |)
                    ]
                |)
              ]
            |)
          ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_unreachable_display :
    M.IsFunction "core::panicking::unreachable_display" unreachable_display.
  
  (*
  pub const fn panic_str_2015(expr: &str) -> ! {
      panic_display(&expr);
  }
  *)
  Definition panic_str_2015 (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ expr ] =>
      ltac:(M.monadic
        (let expr := M.alloc (| expr |) in
        M.call_closure (|
          M.get_function (|
            "core::panicking::panic_display",
            [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
          |),
          [ expr ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_panic_str_2015 : M.IsFunction "core::panicking::panic_str_2015" panic_str_2015.
  
  (*
  pub const fn panic_display<T: fmt::Display>(x: &T) -> ! {
      panic_fmt(format_args!("{}", *x));
  }
  *)
  Definition panic_display (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [ T ], [ x ] =>
      ltac:(M.monadic
        (let x := M.alloc (| x |) in
        M.call_closure (|
          M.get_function (| "core::panicking::panic_fmt", [] |),
          [
            M.call_closure (|
              M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_v1", [] |),
              [
                M.alloc (| Value.Array [ M.read (| Value.String "" |) ] |);
                M.alloc (|
                  Value.Array
                    [
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path "core::fmt::rt::Argument",
                          "new_display",
                          [ T ]
                        |),
                        [ M.read (| x |) ]
                      |)
                    ]
                |)
              ]
            |)
          ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_panic_display : M.IsFunction "core::panicking::panic_display" panic_display.
  
  (*
  fn panic_bounds_check(index: usize, len: usize) -> ! {
      if cfg!(feature = "panic_immediate_abort") {
          super::intrinsics::abort()
      }
  
      panic!("index out of bounds: the len is {len} but the index is {index}")
  }
  *)
  Definition panic_bounds_check (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ index; len ] =>
      ltac:(M.monadic
        (let index := M.alloc (| index |) in
        let len := M.alloc (| len |) in
        M.read (|
          let~ _ :=
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := M.use (M.alloc (| Value.Bool false |)) 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::intrinsics::abort", [] |), [] |)
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
              ]
            |) in
          M.alloc (|
            M.call_closure (|
              M.get_function (| "core::panicking::panic_fmt", [] |),
              [
                M.call_closure (|
                  M.get_associated_function (| Ty.path "core::fmt::Arguments", "new_v1", [] |),
                  [
                    M.alloc (|
                      Value.Array
                        [
                          M.read (| Value.String "index out of bounds: the len is " |);
                          M.read (| Value.String " but the index is " |)
                        ]
                    |);
                    M.alloc (|
                      Value.Array
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::rt::Argument",
                              "new_display",
                              [ Ty.path "usize" ]
                            |),
                            [ len ]
                          |);
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::rt::Argument",
                              "new_display",
                              [ Ty.path "usize" ]
                            |),
                            [ index ]
                          |)
                        ]
                    |)
                  ]
                |)
              ]
            |)
          |)
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_panic_bounds_check :
    M.IsFunction "core::panicking::panic_bounds_check" panic_bounds_check.
  
  (*
  fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! {
      if cfg!(feature = "panic_immediate_abort") {
          super::intrinsics::abort()
      }
  
      panic_nounwind_fmt(
          format_args!(
              "misaligned pointer dereference: address must be a multiple of {required:#x} but is {found:#x}"
          ),
          /* force_no_backtrace */ false,
      )
  }
  *)
  Definition panic_misaligned_pointer_dereference
      (ε : list Value.t)
      (τ : list Ty.t)
      (α : list Value.t)
      : M :=
    match ε, τ, α with
    | [], [], [ required; found ] =>
      ltac:(M.monadic
        (let required := M.alloc (| required |) in
        let found := M.alloc (| found |) in
        M.read (|
          let~ _ :=
            M.match_operator (|
              M.alloc (| Value.Tuple [] |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ := M.use (M.alloc (| Value.Bool false |)) 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::intrinsics::abort", [] |), [] |)
                      |)
                    |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
              ]
            |) in
          M.alloc (|
            M.call_closure (|
              M.get_function (| "core::panicking::panic_nounwind_fmt", [] |),
              [
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path "core::fmt::Arguments",
                    "new_v1_formatted",
                    []
                  |),
                  [
                    M.alloc (|
                      Value.Array
                        [
                          M.read (|
                            Value.String
                              "misaligned pointer dereference: address must be a multiple of "
                          |);
                          M.read (| Value.String " but is " |)
                        ]
                    |);
                    M.alloc (|
                      Value.Array
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::rt::Argument",
                              "new_lower_hex",
                              [ Ty.path "usize" ]
                            |),
                            [ required ]
                          |);
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::rt::Argument",
                              "new_lower_hex",
                              [ Ty.path "usize" ]
                            |),
                            [ found ]
                          |)
                        ]
                    |);
                    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 4;
                              Value.StructTuple "core::fmt::rt::Count::Implied" [];
                              Value.StructTuple "core::fmt::rt::Count::Implied" []
                            ]
                          |);
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "core::fmt::rt::Placeholder",
                              "new",
                              []
                            |),
                            [
                              Value.Integer IntegerKind.Usize 1;
                              Value.UnicodeChar 32;
                              Value.StructTuple "core::fmt::rt::Alignment::Unknown" [];
                              Value.Integer IntegerKind.U32 4;
                              Value.StructTuple "core::fmt::rt::Count::Implied" [];
                              Value.StructTuple "core::fmt::rt::Count::Implied" []
                            ]
                          |)
                        ]
                    |);
                    M.call_closure (|
                      M.get_associated_function (| Ty.path "core::fmt::rt::UnsafeArg", "new", [] |),
                      []
                    |)
                  ]
                |);
                Value.Bool false
              ]
            |)
          |)
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_panic_misaligned_pointer_dereference :
    M.IsFunction
      "core::panicking::panic_misaligned_pointer_dereference"
      panic_misaligned_pointer_dereference.
  
  (*
  fn panic_cannot_unwind() -> ! {
      // Keep the text in sync with `UnwindTerminateReason::as_str` in `rustc_middle`.
      panic_nounwind("panic in a function that cannot unwind")
  }
  *)
  Definition panic_cannot_unwind (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [] =>
      ltac:(M.monadic
        (M.call_closure (|
          M.get_function (| "core::panicking::panic_nounwind", [] |),
          [ M.read (| Value.String "panic in a function that cannot unwind" |) ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_panic_cannot_unwind :
    M.IsFunction "core::panicking::panic_cannot_unwind" panic_cannot_unwind.
  
  (*
  fn panic_in_cleanup() -> ! {
      // Keep the text in sync with `UnwindTerminateReason::as_str` in `rustc_middle`.
      panic_nounwind_nobacktrace("panic in a destructor during cleanup")
  }
  *)
  Definition panic_in_cleanup (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [] =>
      ltac:(M.monadic
        (M.call_closure (|
          M.get_function (| "core::panicking::panic_nounwind_nobacktrace", [] |),
          [ M.read (| Value.String "panic in a destructor during cleanup" |) ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_panic_in_cleanup :
    M.IsFunction "core::panicking::panic_in_cleanup" panic_in_cleanup.
  
  (*
  pub const fn const_panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
      if let Some(msg) = fmt.as_str() {
          // The panic_display function is hooked by const eval.
          panic_display(&msg);
      } else {
          // SAFETY: This is only evaluated at compile time, which reliably
          // handles this UB (in case this branch turns out to be reachable
          // somehow).
          unsafe { crate::hint::unreachable_unchecked() };
      }
  }
  *)
  Definition const_panic_fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ fmt ] =>
      ltac:(M.monadic
        (let fmt := M.alloc (| fmt |) 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.path "core::fmt::Arguments",
                          "as_str",
                          []
                        |),
                        [ fmt ]
                      |)
                    |) in
                  let γ0_0 :=
                    M.SubPointer.get_struct_tuple_field (| γ, "core::option::Option::Some", 0 |) in
                  let msg := M.copy (| γ0_0 |) in
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (|
                        "core::panicking::panic_display",
                        [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                      |),
                      [ msg ]
                    |)
                  |)));
              fun γ =>
                ltac:(M.monadic
                  (let~ _ :=
                    M.alloc (|
                      M.never_to_any (|
                        M.call_closure (|
                          M.get_function (| "core::hint::unreachable_unchecked", [] |),
                          []
                        |)
                      |)
                    |) in
                  M.alloc (| Value.Tuple [] |)))
            ]
          |)
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_const_panic_fmt : M.IsFunction "core::panicking::const_panic_fmt" const_panic_fmt.
  
  (*
  Enum AssertKind
  {
    const_params := [];
    ty_params := [];
    variants :=
      [
        {
          name := "Eq";
          item := StructTuple [];
          discriminant := None;
        };
        {
          name := "Ne";
          item := StructTuple [];
          discriminant := None;
        };
        {
          name := "Match";
          item := StructTuple [];
          discriminant := None;
        }
      ];
  }
  *)
  
  Module Impl_core_fmt_Debug_for_core_panicking_AssertKind.
    Definition Self : Ty.t := Ty.path "core::panicking::AssertKind".
    
    (* 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 (| γ, "core::panicking::AssertKind::Eq" |) in
                        M.alloc (| M.read (| Value.String "Eq" |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let _ := M.is_struct_tuple (| γ, "core::panicking::AssertKind::Ne" |) in
                        M.alloc (| M.read (| Value.String "Ne" |) |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ := M.read (| γ |) in
                        let _ := M.is_struct_tuple (| γ, "core::panicking::AssertKind::Match" |) in
                        M.alloc (| M.read (| Value.String "Match" |) |)))
                  ]
                |)
              |)
            ]
          |)))
      | _, _, _ => 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_panicking_AssertKind.
  
  (*
  pub fn assert_failed<T, U>(
      kind: AssertKind,
      left: &T,
      right: &U,
      args: Option<fmt::Arguments<'_>>,
  ) -> !
  where
      T: fmt::Debug + ?Sized,
      U: fmt::Debug + ?Sized,
  {
      assert_failed_inner(kind, &left, &right, args)
  }
  *)
  Definition assert_failed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [ T; U ], [ kind; _ as left; _ as right; args ] =>
      ltac:(M.monadic
        (let kind := M.alloc (| kind |) in
        let left := M.alloc (| left |) in
        let right := M.alloc (| right |) in
        let args := M.alloc (| args |) in
        M.call_closure (|
          M.get_function (| "core::panicking::assert_failed_inner", [] |),
          [ M.read (| kind |); left; right; M.read (| args |) ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_assert_failed : M.IsFunction "core::panicking::assert_failed" assert_failed.
  
  (*
  pub fn assert_matches_failed<T: fmt::Debug + ?Sized>(
      left: &T,
      right: &str,
      args: Option<fmt::Arguments<'_>>,
  ) -> ! {
      // The pattern is a string so it can be displayed directly.
      struct Pattern<'a>(&'a str);
      impl fmt::Debug for Pattern<'_> {
          fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
              f.write_str(self.0)
          }
      }
      assert_failed_inner(AssertKind::Match, &left, &Pattern(right), args);
  }
  *)
  Definition assert_matches_failed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [ T ], [ _ as left; _ as right; args ] =>
      ltac:(M.monadic
        (let left := M.alloc (| left |) in
        let right := M.alloc (| right |) in
        let args := M.alloc (| args |) in
        M.call_closure (|
          M.get_function (| "core::panicking::assert_failed_inner", [] |),
          [
            Value.StructTuple "core::panicking::AssertKind::Match" [];
            left;
            M.alloc (|
              Value.StructTuple
                "core::panicking::assert_matches_failed::Pattern"
                [ M.read (| right |) ]
            |);
            M.read (| args |)
          ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_assert_matches_failed :
    M.IsFunction "core::panicking::assert_matches_failed" assert_matches_failed.
  
  Module assert_matches_failed.
    (* StructTuple
      {
        name := "Pattern";
        const_params := [];
        ty_params := [];
        fields := [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ];
      } *)
    
    Module Impl_core_fmt_Debug_for_core_panicking_assert_matches_failed_Pattern.
      Definition Self : Ty.t := Ty.path "core::panicking::assert_matches_failed::Pattern".
      
      (*
              fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                  f.write_str(self.0)
              }
      *)
      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.SubPointer.get_struct_tuple_field (|
                    M.read (| self |),
                    "core::panicking::assert_matches_failed::Pattern",
                    0
                  |)
                |)
              ]
            |)))
        | _, _, _ => 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_panicking_assert_matches_failed_Pattern.
  End assert_matches_failed.
  
  (*
  fn assert_failed_inner(
      kind: AssertKind,
      left: &dyn fmt::Debug,
      right: &dyn fmt::Debug,
      args: Option<fmt::Arguments<'_>>,
  ) -> ! {
      let op = match kind {
          AssertKind::Eq => "==",
          AssertKind::Ne => "!=",
          AssertKind::Match => "matches",
      };
  
      match args {
          Some(args) => panic!(
              r#"assertion `left {op} right` failed: {args}
    left: {left:?}
   right: {right:?}"#
          ),
          None => panic!(
              r#"assertion `left {op} right` failed
    left: {left:?}
   right: {right:?}"#
          ),
      }
  }
  *)
  Definition assert_failed_inner (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ kind; _ as left; _ as right; args ] =>
      ltac:(M.monadic
        (let kind := M.alloc (| kind |) in
        let left := M.alloc (| left |) in
        let right := M.alloc (| right |) in
        let args := M.alloc (| args |) in
        M.read (|
          let~ op :=
            M.copy (|
              M.match_operator (|
                kind,
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let _ := M.is_struct_tuple (| γ, "core::panicking::AssertKind::Eq" |) in
                      Value.String "=="));
                  fun γ =>
                    ltac:(M.monadic
                      (let _ := M.is_struct_tuple (| γ, "core::panicking::AssertKind::Ne" |) in
                      M.alloc (| M.read (| Value.String "!=" |) |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let _ := M.is_struct_tuple (| γ, "core::panicking::AssertKind::Match" |) in
                      M.alloc (| M.read (| Value.String "matches" |) |)))
                ]
              |)
            |) in
          M.match_operator (|
            args,
            [
              fun γ =>
                ltac:(M.monadic
                  (let γ0_0 :=
                    M.SubPointer.get_struct_tuple_field (| γ, "core::option::Option::Some", 0 |) in
                  let args := M.copy (| γ0_0 |) in
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::panicking::panic_fmt", [] |),
                      [
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Arguments",
                            "new_v1",
                            []
                          |),
                          [
                            M.alloc (|
                              Value.Array
                                [
                                  M.read (| Value.String "assertion `left " |);
                                  M.read (| Value.String " right` failed: " |);
                                  M.read (| Value.String "
  left: " |);
                                  M.read (| Value.String "
 right: " |)
                                ]
                            |);
                            M.alloc (|
                              Value.Array
                                [
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "core::fmt::rt::Argument",
                                      "new_display",
                                      [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                                    |),
                                    [ op ]
                                  |);
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "core::fmt::rt::Argument",
                                      "new_display",
                                      [ Ty.path "core::fmt::Arguments" ]
                                    |),
                                    [ args ]
                                  |);
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "core::fmt::rt::Argument",
                                      "new_debug",
                                      [
                                        Ty.apply
                                          (Ty.path "&")
                                          []
                                          [ Ty.dyn [ ("core::fmt::Debug::Trait", []) ] ]
                                      ]
                                    |),
                                    [ left ]
                                  |);
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "core::fmt::rt::Argument",
                                      "new_debug",
                                      [
                                        Ty.apply
                                          (Ty.path "&")
                                          []
                                          [ Ty.dyn [ ("core::fmt::Debug::Trait", []) ] ]
                                      ]
                                    |),
                                    [ right ]
                                  |)
                                ]
                            |)
                          ]
                        |)
                      ]
                    |)
                  |)));
              fun γ =>
                ltac:(M.monadic
                  (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::panicking::panic_fmt", [] |),
                      [
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Arguments",
                            "new_v1",
                            []
                          |),
                          [
                            M.alloc (|
                              Value.Array
                                [
                                  M.read (| Value.String "assertion `left " |);
                                  M.read (| Value.String " right` failed
  left: " |);
                                  M.read (| Value.String "
 right: " |)
                                ]
                            |);
                            M.alloc (|
                              Value.Array
                                [
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "core::fmt::rt::Argument",
                                      "new_display",
                                      [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                                    |),
                                    [ op ]
                                  |);
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "core::fmt::rt::Argument",
                                      "new_debug",
                                      [
                                        Ty.apply
                                          (Ty.path "&")
                                          []
                                          [ Ty.dyn [ ("core::fmt::Debug::Trait", []) ] ]
                                      ]
                                    |),
                                    [ left ]
                                  |);
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "core::fmt::rt::Argument",
                                      "new_debug",
                                      [
                                        Ty.apply
                                          (Ty.path "&")
                                          []
                                          [ Ty.dyn [ ("core::fmt::Debug::Trait", []) ] ]
                                      ]
                                    |),
                                    [ right ]
                                  |)
                                ]
                            |)
                          ]
                        |)
                      ]
                    |)
                  |)))
            ]
          |)
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_assert_failed_inner :
    M.IsFunction "core::panicking::assert_failed_inner" assert_failed_inner.
End panicking.
