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

Module vec.
  Module splice.
    (* StructRecord
      {
        name := "Splice";
        const_params := [];
        ty_params := [ "I"; "A" ];
        fields :=
          [
            ("drain", Ty.apply (Ty.path "alloc::vec::drain::Drain") [] [ Ty.associated; A ]);
            ("replace_with", I)
          ];
      } *)
    
    Module Impl_core_fmt_Debug_where_core_fmt_Debug_I_where_core_iter_traits_iterator_Iterator_I_where_core_fmt_Debug_A_where_core_alloc_Allocator_A_where_core_fmt_Debug_associated_type_for_alloc_vec_splice_Splice_I_A.
      Definition Self (I A : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "alloc::vec::splice::Splice") [] [ I; A ].
      
      (* Debug *)
      Definition fmt (I A : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self I A in
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "core::fmt::Formatter",
                "debug_struct_field2_finish",
                []
              |),
              [
                M.read (| f |);
                M.read (| Value.String "Splice" |);
                M.read (| Value.String "drain" |);
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "alloc::vec::splice::Splice",
                  "drain"
                |);
                M.read (| Value.String "replace_with" |);
                M.alloc (|
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "alloc::vec::splice::Splice",
                    "replace_with"
                  |)
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (I A : Ty.t),
        M.IsTraitInstance
          "core::fmt::Debug"
          (Self I A)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method (fmt I A)) ].
    End Impl_core_fmt_Debug_where_core_fmt_Debug_I_where_core_iter_traits_iterator_Iterator_I_where_core_fmt_Debug_A_where_core_alloc_Allocator_A_where_core_fmt_Debug_associated_type_for_alloc_vec_splice_Splice_I_A.
    
    Module Impl_core_iter_traits_iterator_Iterator_where_core_iter_traits_iterator_Iterator_I_where_core_alloc_Allocator_A_for_alloc_vec_splice_Splice_I_A.
      Definition Self (I A : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "alloc::vec::splice::Splice") [] [ I; A ].
      
      (*     type Item = I::Item; *)
      Definition _Item (I A : Ty.t) : Ty.t := Ty.associated.
      
      (*
          fn next(&mut self) -> Option<Self::Item> {
              self.drain.next()
          }
      *)
      Definition next (I A : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self I A in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::iter::traits::iterator::Iterator",
                Ty.apply (Ty.path "alloc::vec::drain::Drain") [] [ Ty.associated; A ],
                [],
                "next",
                []
              |),
              [
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "alloc::vec::splice::Splice",
                  "drain"
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      (*
          fn size_hint(&self) -> (usize, Option<usize>) {
              self.drain.size_hint()
          }
      *)
      Definition size_hint (I A : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self I A in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::iter::traits::iterator::Iterator",
                Ty.apply (Ty.path "alloc::vec::drain::Drain") [] [ Ty.associated; A ],
                [],
                "size_hint",
                []
              |),
              [
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "alloc::vec::splice::Splice",
                  "drain"
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (I A : Ty.t),
        M.IsTraitInstance
          "core::iter::traits::iterator::Iterator"
          (Self I A)
          (* Trait polymorphic types *) []
          (* Instance *)
          [
            ("Item", InstanceField.Ty (_Item I A));
            ("next", InstanceField.Method (next I A));
            ("size_hint", InstanceField.Method (size_hint I A))
          ].
    End Impl_core_iter_traits_iterator_Iterator_where_core_iter_traits_iterator_Iterator_I_where_core_alloc_Allocator_A_for_alloc_vec_splice_Splice_I_A.
    
    Module Impl_core_iter_traits_double_ended_DoubleEndedIterator_where_core_iter_traits_iterator_Iterator_I_where_core_alloc_Allocator_A_for_alloc_vec_splice_Splice_I_A.
      Definition Self (I A : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "alloc::vec::splice::Splice") [] [ I; A ].
      
      (*
          fn next_back(&mut self) -> Option<Self::Item> {
              self.drain.next_back()
          }
      *)
      Definition next_back (I A : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self I A in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_trait_method (|
                "core::iter::traits::double_ended::DoubleEndedIterator",
                Ty.apply (Ty.path "alloc::vec::drain::Drain") [] [ Ty.associated; A ],
                [],
                "next_back",
                []
              |),
              [
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "alloc::vec::splice::Splice",
                  "drain"
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (I A : Ty.t),
        M.IsTraitInstance
          "core::iter::traits::double_ended::DoubleEndedIterator"
          (Self I A)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("next_back", InstanceField.Method (next_back I A)) ].
    End Impl_core_iter_traits_double_ended_DoubleEndedIterator_where_core_iter_traits_iterator_Iterator_I_where_core_alloc_Allocator_A_for_alloc_vec_splice_Splice_I_A.
    
    Module Impl_core_iter_traits_exact_size_ExactSizeIterator_where_core_iter_traits_iterator_Iterator_I_where_core_alloc_Allocator_A_for_alloc_vec_splice_Splice_I_A.
      Definition Self (I A : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "alloc::vec::splice::Splice") [] [ I; A ].
      
      Axiom Implements :
        forall (I A : Ty.t),
        M.IsTraitInstance
          "core::iter::traits::exact_size::ExactSizeIterator"
          (Self I A)
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_iter_traits_exact_size_ExactSizeIterator_where_core_iter_traits_iterator_Iterator_I_where_core_alloc_Allocator_A_for_alloc_vec_splice_Splice_I_A.
    
    Module Impl_core_ops_drop_Drop_where_core_iter_traits_iterator_Iterator_I_where_core_alloc_Allocator_A_for_alloc_vec_splice_Splice_I_A.
      Definition Self (I A : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "alloc::vec::splice::Splice") [] [ I; A ].
      
      (*
          fn drop(&mut self) {
              self.drain.by_ref().for_each(drop);
              // At this point draining is done and the only remaining tasks are splicing
              // and moving things into the final place.
              // Which means we can replace the slice::Iter with pointers that won't point to deallocated
              // memory, so that Drain::drop is still allowed to call iter.len(), otherwise it would break
              // the ptr.sub_ptr contract.
              self.drain.iter = (&[]).iter();
      
              unsafe {
                  if self.drain.tail_len == 0 {
                      self.drain.vec.as_mut().extend(self.replace_with.by_ref());
                      return;
                  }
      
                  // First fill the range left by drain().
                  if !self.drain.fill(&mut self.replace_with) {
                      return;
                  }
      
                  // There may be more elements. Use the lower bound as an estimate.
                  // FIXME: Is the upper bound a better guess? Or something else?
                  let (lower_bound, _upper_bound) = self.replace_with.size_hint();
                  if lower_bound > 0 {
                      self.drain.move_tail(lower_bound);
                      if !self.drain.fill(&mut self.replace_with) {
                          return;
                      }
                  }
      
                  // Collect any remaining elements.
                  // This is a zero-length vector which does not allocate if `lower_bound` was exact.
                  let mut collected = self.replace_with.by_ref().collect::<Vec<I::Item>>().into_iter();
                  // Now we have an exact count.
                  if collected.len() > 0 {
                      self.drain.move_tail(collected.len());
                      let filled = self.drain.fill(&mut collected);
                      debug_assert!(filled);
                      debug_assert_eq!(collected.len(), 0);
                  }
              }
              // Let `Drain::drop` move the tail back if necessary and restore `vec.len`.
          }
      *)
      Definition drop (I A : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self I A in
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::iter::traits::iterator::Iterator",
                          Ty.apply
                            (Ty.path "&mut")
                            []
                            [ Ty.apply (Ty.path "alloc::vec::drain::Drain") [] [ Ty.associated; A ]
                            ],
                          [],
                          "for_each",
                          [ Ty.function [ Ty.associated ] (Ty.tuple []) ]
                        |),
                        [
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::iterator::Iterator",
                              Ty.apply (Ty.path "alloc::vec::drain::Drain") [] [ Ty.associated; A ],
                              [],
                              "by_ref",
                              []
                            |),
                            [
                              M.SubPointer.get_struct_record_field (|
                                M.read (| self |),
                                "alloc::vec::splice::Splice",
                                "drain"
                              |)
                            ]
                          |);
                          M.get_function (| "core::mem::drop", [ Ty.associated ] |)
                        ]
                      |)
                    |) in
                  let~ _ :=
                    M.write (|
                      M.SubPointer.get_struct_record_field (|
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "alloc::vec::splice::Splice",
                          "drain"
                        |),
                        "alloc::vec::drain::Drain",
                        "iter"
                      |),
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "slice") [] [ Ty.associated ],
                          "iter",
                          []
                        |),
                        [ M.alloc (| Value.Array [] |) ]
                      |)
                    |) in
                  let~ _ :=
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    M.read (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "alloc::vec::splice::Splice",
                                          "drain"
                                        |),
                                        "alloc::vec::drain::Drain",
                                        "tail_len"
                                      |)
                                    |),
                                    Value.Integer IntegerKind.Usize 0
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  let~ _ :=
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::iter::traits::collect::Extend",
                                          Ty.apply
                                            (Ty.path "alloc::vec::Vec")
                                            []
                                            [ Ty.associated; A ],
                                          [ Ty.associated ],
                                          "extend",
                                          [ Ty.apply (Ty.path "&mut") [] [ I ] ]
                                        |),
                                        [
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply
                                                (Ty.path "core::ptr::non_null::NonNull")
                                                []
                                                [
                                                  Ty.apply
                                                    (Ty.path "alloc::vec::Vec")
                                                    []
                                                    [ Ty.associated; A ]
                                                ],
                                              "as_mut",
                                              []
                                            |),
                                            [
                                              M.SubPointer.get_struct_record_field (|
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "alloc::vec::splice::Splice",
                                                  "drain"
                                                |),
                                                "alloc::vec::drain::Drain",
                                                "vec"
                                              |)
                                            ]
                                          |);
                                          M.call_closure (|
                                            M.get_trait_method (|
                                              "core::iter::traits::iterator::Iterator",
                                              I,
                                              [],
                                              "by_ref",
                                              []
                                            |),
                                            [
                                              M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "alloc::vec::splice::Splice",
                                                "replace_with"
                                              |)
                                            ]
                                          |)
                                        ]
                                      |)
                                    |) in
                                  M.return_ (| Value.Tuple [] |)
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) 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.apply
                                          (Ty.path "alloc::vec::drain::Drain")
                                          []
                                          [ Ty.associated; A ],
                                        "fill",
                                        [ I ]
                                      |),
                                      [
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "alloc::vec::splice::Splice",
                                          "drain"
                                        |);
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "alloc::vec::splice::Splice",
                                          "replace_with"
                                        |)
                                      ]
                                    |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (| M.read (| M.return_ (| Value.Tuple [] |) |) |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  M.match_operator (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::iter::traits::iterator::Iterator",
                          I,
                          [],
                          "size_hint",
                          []
                        |),
                        [
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "alloc::vec::splice::Splice",
                            "replace_with"
                          |)
                        ]
                      |)
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                          let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                          let lower_bound := M.copy (| γ0_0 |) in
                          let _upper_bound := M.copy (| γ0_1 |) in
                          let~ _ :=
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ :=
                                      M.use
                                        (M.alloc (|
                                          BinOp.gt (|
                                            M.read (| lower_bound |),
                                            Value.Integer IntegerKind.Usize 0
                                          |)
                                        |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    let~ _ :=
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.apply
                                              (Ty.path "alloc::vec::drain::Drain")
                                              []
                                              [ Ty.associated; A ],
                                            "move_tail",
                                            []
                                          |),
                                          [
                                            M.SubPointer.get_struct_record_field (|
                                              M.read (| self |),
                                              "alloc::vec::splice::Splice",
                                              "drain"
                                            |);
                                            M.read (| lower_bound |)
                                          ]
                                        |)
                                      |) in
                                    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.apply
                                                          (Ty.path "alloc::vec::drain::Drain")
                                                          []
                                                          [ Ty.associated; A ],
                                                        "fill",
                                                        [ I ]
                                                      |),
                                                      [
                                                        M.SubPointer.get_struct_record_field (|
                                                          M.read (| self |),
                                                          "alloc::vec::splice::Splice",
                                                          "drain"
                                                        |);
                                                        M.SubPointer.get_struct_record_field (|
                                                          M.read (| self |),
                                                          "alloc::vec::splice::Splice",
                                                          "replace_with"
                                                        |)
                                                      ]
                                                    |)
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.alloc (|
                                              M.never_to_any (|
                                                M.read (| M.return_ (| Value.Tuple [] |) |)
                                              |)
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |)));
                                fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                              ]
                            |) in
                          let~ collected :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::iter::traits::collect::IntoIterator",
                                  Ty.apply
                                    (Ty.path "alloc::vec::Vec")
                                    []
                                    [ Ty.associated; Ty.path "alloc::alloc::Global" ],
                                  [],
                                  "into_iter",
                                  []
                                |),
                                [
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::iter::traits::iterator::Iterator",
                                      Ty.apply (Ty.path "&mut") [] [ I ],
                                      [],
                                      "collect",
                                      [
                                        Ty.apply
                                          (Ty.path "alloc::vec::Vec")
                                          []
                                          [ Ty.associated; Ty.path "alloc::alloc::Global" ]
                                      ]
                                    |),
                                    [
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::iter::traits::iterator::Iterator",
                                          I,
                                          [],
                                          "by_ref",
                                          []
                                        |),
                                        [
                                          M.SubPointer.get_struct_record_field (|
                                            M.read (| self |),
                                            "alloc::vec::splice::Splice",
                                            "replace_with"
                                          |)
                                        ]
                                      |)
                                    ]
                                  |)
                                ]
                              |)
                            |) in
                          M.match_operator (|
                            M.alloc (| Value.Tuple [] |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ :=
                                    M.use
                                      (M.alloc (|
                                        BinOp.gt (|
                                          M.call_closure (|
                                            M.get_trait_method (|
                                              "core::iter::traits::exact_size::ExactSizeIterator",
                                              Ty.apply
                                                (Ty.path "alloc::vec::into_iter::IntoIter")
                                                []
                                                [ Ty.associated; Ty.path "alloc::alloc::Global" ],
                                              [],
                                              "len",
                                              []
                                            |),
                                            [ collected ]
                                          |),
                                          Value.Integer IntegerKind.Usize 0
                                        |)
                                      |)) in
                                  let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Bool true
                                    |) in
                                  let~ _ :=
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply
                                            (Ty.path "alloc::vec::drain::Drain")
                                            []
                                            [ Ty.associated; A ],
                                          "move_tail",
                                          []
                                        |),
                                        [
                                          M.SubPointer.get_struct_record_field (|
                                            M.read (| self |),
                                            "alloc::vec::splice::Splice",
                                            "drain"
                                          |);
                                          M.call_closure (|
                                            M.get_trait_method (|
                                              "core::iter::traits::exact_size::ExactSizeIterator",
                                              Ty.apply
                                                (Ty.path "alloc::vec::into_iter::IntoIter")
                                                []
                                                [ Ty.associated; Ty.path "alloc::alloc::Global" ],
                                              [],
                                              "len",
                                              []
                                            |),
                                            [ collected ]
                                          |)
                                        ]
                                      |)
                                    |) in
                                  let~ filled :=
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply
                                            (Ty.path "alloc::vec::drain::Drain")
                                            []
                                            [ Ty.associated; A ],
                                          "fill",
                                          [
                                            Ty.apply
                                              (Ty.path "alloc::vec::into_iter::IntoIter")
                                              []
                                              [ Ty.associated; Ty.path "alloc::alloc::Global" ]
                                          ]
                                        |),
                                        [
                                          M.SubPointer.get_struct_record_field (|
                                            M.read (| self |),
                                            "alloc::vec::splice::Splice",
                                            "drain"
                                          |);
                                          collected
                                        ]
                                      |)
                                    |) in
                                  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.read (| filled |) |)
                                                          |)) 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: filled"
                                                              |)
                                                            ]
                                                          |)
                                                        |)
                                                      |)));
                                                  fun γ =>
                                                    ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                                ]
                                              |) in
                                            M.alloc (| Value.Tuple [] |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  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
                                                    [
                                                      M.alloc (|
                                                        M.call_closure (|
                                                          M.get_trait_method (|
                                                            "core::iter::traits::exact_size::ExactSizeIterator",
                                                            Ty.apply
                                                              (Ty.path
                                                                "alloc::vec::into_iter::IntoIter")
                                                              []
                                                              [
                                                                Ty.associated;
                                                                Ty.path "alloc::alloc::Global"
                                                              ],
                                                            [],
                                                            "len",
                                                            []
                                                          |),
                                                          [ collected ]
                                                        |)
                                                      |);
                                                      M.alloc (|
                                                        Value.Integer IntegerKind.Usize 0
                                                      |)
                                                    ]
                                                |),
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ0_0 :=
                                                        M.SubPointer.get_tuple_field (| γ, 0 |) in
                                                      let γ0_1 :=
                                                        M.SubPointer.get_tuple_field (| γ, 1 |) in
                                                      let left_val := M.copy (| γ0_0 |) in
                                                      let right_val := M.copy (| γ0_1 |) in
                                                      M.match_operator (|
                                                        M.alloc (| Value.Tuple [] |),
                                                        [
                                                          fun γ =>
                                                            ltac:(M.monadic
                                                              (let γ :=
                                                                M.use
                                                                  (M.alloc (|
                                                                    UnOp.not (|
                                                                      BinOp.eq (|
                                                                        M.read (|
                                                                          M.read (| left_val |)
                                                                        |),
                                                                        M.read (|
                                                                          M.read (| right_val |)
                                                                        |)
                                                                      |)
                                                                    |)
                                                                  |)) in
                                                              let _ :=
                                                                M.is_constant_or_break_match (|
                                                                  M.read (| γ |),
                                                                  Value.Bool true
                                                                |) in
                                                              M.alloc (|
                                                                M.never_to_any (|
                                                                  M.read (|
                                                                    let~ kind :=
                                                                      M.alloc (|
                                                                        Value.StructTuple
                                                                          "core::panicking::AssertKind::Eq"
                                                                          []
                                                                      |) in
                                                                    M.alloc (|
                                                                      M.call_closure (|
                                                                        M.get_function (|
                                                                          "core::panicking::assert_failed",
                                                                          [
                                                                            Ty.path "usize";
                                                                            Ty.path "usize"
                                                                          ]
                                                                        |),
                                                                        [
                                                                          M.read (| kind |);
                                                                          M.read (| left_val |);
                                                                          M.read (| right_val |);
                                                                          Value.StructTuple
                                                                            "core::option::Option::None"
                                                                            []
                                                                        ]
                                                                      |)
                                                                    |)
                                                                  |)
                                                                |)
                                                              |)));
                                                          fun γ =>
                                                            ltac:(M.monadic
                                                              (M.alloc (| Value.Tuple [] |)))
                                                        ]
                                                      |)))
                                                ]
                                              |) in
                                            M.alloc (| Value.Tuple [] |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  M.alloc (| Value.Tuple [] |)));
                              fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                            ]
                          |)))
                    ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (I A : Ty.t),
        M.IsTraitInstance
          "core::ops::drop::Drop"
          (Self I A)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("drop", InstanceField.Method (drop I A)) ].
    End Impl_core_ops_drop_Drop_where_core_iter_traits_iterator_Iterator_I_where_core_alloc_Allocator_A_for_alloc_vec_splice_Splice_I_A.
    
    Module Impl_alloc_vec_drain_Drain_T_A.
      Definition Self (T A : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "alloc::vec::drain::Drain") [] [ T; A ].
      
      (*
          unsafe fn fill<I: Iterator<Item = T>>(&mut self, replace_with: &mut I) -> bool {
              let vec = unsafe { self.vec.as_mut() };
              let range_start = vec.len;
              let range_end = self.tail_start;
              let range_slice = unsafe {
                  slice::from_raw_parts_mut(vec.as_mut_ptr().add(range_start), range_end - range_start)
              };
      
              for place in range_slice {
                  if let Some(new_item) = replace_with.next() {
                      unsafe { ptr::write(place, new_item) };
                      vec.len += 1;
                  } else {
                      return false;
                  }
              }
              true
          }
      *)
      Definition fill (T A : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self T A in
        match ε, τ, α with
        | [], [ _ as I ], [ self; replace_with ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let replace_with := M.alloc (| replace_with |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ vec :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "core::ptr::non_null::NonNull")
                            []
                            [ Ty.apply (Ty.path "alloc::vec::Vec") [] [ T; A ] ],
                          "as_mut",
                          []
                        |),
                        [
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "alloc::vec::drain::Drain",
                            "vec"
                          |)
                        ]
                      |)
                    |) in
                  let~ range_start :=
                    M.copy (|
                      M.SubPointer.get_struct_record_field (|
                        M.read (| vec |),
                        "alloc::vec::Vec",
                        "len"
                      |)
                    |) in
                  let~ range_end :=
                    M.copy (|
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "alloc::vec::drain::Drain",
                        "tail_start"
                      |)
                    |) in
                  let~ range_slice :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_function (| "core::slice::raw::from_raw_parts_mut", [ T ] |),
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply (Ty.path "*mut") [] [ T ],
                              "add",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "alloc::vec::Vec") [] [ T; A ],
                                  "as_mut_ptr",
                                  []
                                |),
                                [ M.read (| vec |) ]
                              |);
                              M.read (| range_start |)
                            ]
                          |);
                          BinOp.Wrap.sub (| M.read (| range_end |), M.read (| range_start |) |)
                        ]
                      |)
                    |) in
                  let~ _ :=
                    M.use
                      (M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::collect::IntoIterator",
                              Ty.apply (Ty.path "&mut") [] [ Ty.apply (Ty.path "slice") [] [ T ] ],
                              [],
                              "into_iter",
                              []
                            |),
                            [ M.read (| range_slice |) ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let iter := M.copy (| γ |) in
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path "core::slice::iter::IterMut")
                                              []
                                              [ T ],
                                            [],
                                            "next",
                                            []
                                          |),
                                          [ iter ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_struct_tuple (|
                                                γ,
                                                "core::option::Option::None"
                                              |) in
                                            M.alloc (|
                                              M.never_to_any (| M.read (| M.break (||) |) |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::option::Option::Some",
                                                0
                                              |) in
                                            let place := M.copy (| γ0_0 |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.alloc (|
                                                        M.call_closure (|
                                                          M.get_trait_method (|
                                                            "core::iter::traits::iterator::Iterator",
                                                            I,
                                                            [],
                                                            "next",
                                                            []
                                                          |),
                                                          [ M.read (| replace_with |) ]
                                                        |)
                                                      |) in
                                                    let γ0_0 :=
                                                      M.SubPointer.get_struct_tuple_field (|
                                                        γ,
                                                        "core::option::Option::Some",
                                                        0
                                                      |) in
                                                    let new_item := M.copy (| γ0_0 |) in
                                                    let~ _ :=
                                                      M.alloc (|
                                                        M.call_closure (|
                                                          M.get_function (|
                                                            "core::ptr::write",
                                                            [ T ]
                                                          |),
                                                          [
                                                            M.read (| place |);
                                                            M.read (| new_item |)
                                                          ]
                                                        |)
                                                      |) in
                                                    let~ _ :=
                                                      let β :=
                                                        M.SubPointer.get_struct_record_field (|
                                                          M.read (| vec |),
                                                          "alloc::vec::Vec",
                                                          "len"
                                                        |) in
                                                      M.write (|
                                                        β,
                                                        BinOp.Wrap.add (|
                                                          M.read (| β |),
                                                          Value.Integer IntegerKind.Usize 1
                                                        |)
                                                      |) in
                                                    M.alloc (| Value.Tuple [] |)));
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (M.alloc (|
                                                      M.never_to_any (|
                                                        M.read (|
                                                          M.return_ (| Value.Bool false |)
                                                        |)
                                                      |)
                                                    |)))
                                              ]
                                            |)))
                                      ]
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)))
                        ]
                      |)) in
                  M.alloc (| Value.Bool true |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_fill :
        forall (T A : Ty.t),
        M.IsAssociatedFunction (Self T A) "fill" (fill T A).
      
      (*
          unsafe fn move_tail(&mut self, additional: usize) {
              let vec = unsafe { self.vec.as_mut() };
              let len = self.tail_start + self.tail_len;
              vec.buf.reserve(len, additional);
      
              let new_tail_start = self.tail_start + additional;
              unsafe {
                  let src = vec.as_ptr().add(self.tail_start);
                  let dst = vec.as_mut_ptr().add(new_tail_start);
                  ptr::copy(src, dst, self.tail_len);
              }
              self.tail_start = new_tail_start;
          }
      *)
      Definition move_tail (T A : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self T A in
        match ε, τ, α with
        | [], [], [ self; additional ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let additional := M.alloc (| additional |) in
            M.read (|
              let~ vec :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "core::ptr::non_null::NonNull")
                        []
                        [ Ty.apply (Ty.path "alloc::vec::Vec") [] [ T; A ] ],
                      "as_mut",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "alloc::vec::drain::Drain",
                        "vec"
                      |)
                    ]
                  |)
                |) in
              let~ len :=
                M.alloc (|
                  BinOp.Wrap.add (|
                    M.read (|
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "alloc::vec::drain::Drain",
                        "tail_start"
                      |)
                    |),
                    M.read (|
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "alloc::vec::drain::Drain",
                        "tail_len"
                      |)
                    |)
                  |)
                |) in
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "alloc::raw_vec::RawVec") [] [ T; A ],
                      "reserve",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| vec |),
                        "alloc::vec::Vec",
                        "buf"
                      |);
                      M.read (| len |);
                      M.read (| additional |)
                    ]
                  |)
                |) in
              let~ new_tail_start :=
                M.alloc (|
                  BinOp.Wrap.add (|
                    M.read (|
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "alloc::vec::drain::Drain",
                        "tail_start"
                      |)
                    |),
                    M.read (| additional |)
                  |)
                |) in
              let~ _ :=
                let~ src :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "*const") [] [ T ],
                        "add",
                        []
                      |),
                      [
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "alloc::vec::Vec") [] [ T; A ],
                            "as_ptr",
                            []
                          |),
                          [ M.read (| vec |) ]
                        |);
                        M.read (|
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "alloc::vec::drain::Drain",
                            "tail_start"
                          |)
                        |)
                      ]
                    |)
                  |) in
                let~ dst :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (| Ty.apply (Ty.path "*mut") [] [ T ], "add", [] |),
                      [
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "alloc::vec::Vec") [] [ T; A ],
                            "as_mut_ptr",
                            []
                          |),
                          [ M.read (| vec |) ]
                        |);
                        M.read (| new_tail_start |)
                      ]
                    |)
                  |) in
                let~ _ :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (| "core::intrinsics::copy", [ T ] |),
                      [
                        M.read (| src |);
                        M.read (| dst |);
                        M.read (|
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "alloc::vec::drain::Drain",
                            "tail_len"
                          |)
                        |)
                      ]
                    |)
                  |) in
                M.alloc (| Value.Tuple [] |) in
              let~ _ :=
                M.write (|
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "alloc::vec::drain::Drain",
                    "tail_start"
                  |),
                  M.read (| new_tail_start |)
                |) in
              M.alloc (| Value.Tuple [] |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_move_tail :
        forall (T A : Ty.t),
        M.IsAssociatedFunction (Self T A) "move_tail" (move_tail T A).
    End Impl_alloc_vec_drain_Drain_T_A.
  End splice.
End vec.
