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

Module iter.
  Module adapters.
    Module filter_map.
      (* StructRecord
        {
          name := "FilterMap";
          const_params := [];
          ty_params := [ "I"; "F" ];
          fields := [ ("iter", I); ("f", F) ];
        } *)
      
      Module Impl_core_clone_Clone_where_core_clone_Clone_I_where_core_clone_Clone_F_for_core_iter_adapters_filter_map_FilterMap_I_F.
        Definition Self (I F : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::filter_map::FilterMap") [] [ I; F ].
        
        (* Clone *)
        Definition clone (I F : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I F in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              Value.StructRecord
                "core::iter::adapters::filter_map::FilterMap"
                [
                  ("iter",
                    M.call_closure (|
                      M.get_trait_method (| "core::clone::Clone", I, [], "clone", [] |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::iter::adapters::filter_map::FilterMap",
                          "iter"
                        |)
                      ]
                    |));
                  ("f",
                    M.call_closure (|
                      M.get_trait_method (| "core::clone::Clone", F, [], "clone", [] |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::iter::adapters::filter_map::FilterMap",
                          "f"
                        |)
                      ]
                    |))
                ]))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (I F : Ty.t),
          M.IsTraitInstance
            "core::clone::Clone"
            (Self I F)
            (* Trait polymorphic types *) []
            (* Instance *) [ ("clone", InstanceField.Method (clone I F)) ].
      End Impl_core_clone_Clone_where_core_clone_Clone_I_where_core_clone_Clone_F_for_core_iter_adapters_filter_map_FilterMap_I_F.
      
      Module Impl_core_iter_adapters_filter_map_FilterMap_I_F.
        Definition Self (I F : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::filter_map::FilterMap") [] [ I; F ].
        
        (*
            pub(in crate::iter) fn new(iter: I, f: F) -> FilterMap<I, F> {
                FilterMap { iter, f }
            }
        *)
        Definition new (I F : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I F in
          match ε, τ, α with
          | [], [], [ iter; f ] =>
            ltac:(M.monadic
              (let iter := M.alloc (| iter |) in
              let f := M.alloc (| f |) in
              Value.StructRecord
                "core::iter::adapters::filter_map::FilterMap"
                [ ("iter", M.read (| iter |)); ("f", M.read (| f |)) ]))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom AssociatedFunction_new :
          forall (I F : Ty.t),
          M.IsAssociatedFunction (Self I F) "new" (new I F).
      End Impl_core_iter_adapters_filter_map_FilterMap_I_F.
      
      Module Impl_core_fmt_Debug_where_core_fmt_Debug_I_for_core_iter_adapters_filter_map_FilterMap_I_F.
        Definition Self (I F : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::filter_map::FilterMap") [] [ I; F ].
        
        (*
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                f.debug_struct("FilterMap").field("iter", &self.iter).finish()
            }
        *)
        Definition fmt (I F : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self I F in
          match ε, τ, α with
          | [], [], [ self; f ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let f := M.alloc (| f |) in
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "core::fmt::builders::DebugStruct",
                  "finish",
                  []
                |),
                [
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path "core::fmt::builders::DebugStruct",
                      "field",
                      []
                    |),
                    [
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Formatter",
                            "debug_struct",
                            []
                          |),
                          [ M.read (| f |); M.read (| Value.String "FilterMap" |) ]
                        |)
                      |);
                      M.read (| Value.String "iter" |);
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::iter::adapters::filter_map::FilterMap",
                        "iter"
                      |)
                    ]
                  |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (I F : Ty.t),
          M.IsTraitInstance
            "core::fmt::Debug"
            (Self I F)
            (* Trait polymorphic types *) []
            (* Instance *) [ ("fmt", InstanceField.Method (fmt I F)) ].
      End Impl_core_fmt_Debug_where_core_fmt_Debug_I_for_core_iter_adapters_filter_map_FilterMap_I_F.
      
      (*
      fn filter_map_fold<T, B, Acc>(
          mut f: impl FnMut(T) -> Option<B>,
          mut fold: impl FnMut(Acc, B) -> Acc,
      ) -> impl FnMut(Acc, T) -> Acc {
          move |acc, item| match f(item) {
              Some(x) => fold(acc, x),
              None => acc,
          }
      }
      *)
      Definition filter_map_fold (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [],
            [ T; B; Acc; impl_FnMut_T__arrow_Option_B_; impl_FnMut_Acc__B__arrow_Acc ],
            [ f; fold ] =>
          ltac:(M.monadic
            (let f := M.alloc (| f |) in
            let fold := M.alloc (| fold |) in
            M.closure
              (fun γ =>
                ltac:(M.monadic
                  match γ with
                  | [ α0; α1 ] =>
                    ltac:(M.monadic
                      (M.match_operator (|
                        M.alloc (| α0 |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let acc := M.copy (| γ |) in
                              M.match_operator (|
                                M.alloc (| α1 |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let item := M.copy (| γ |) in
                                      M.read (|
                                        M.match_operator (|
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_trait_method (|
                                                "core::ops::function::FnMut",
                                                impl_FnMut_T__arrow_Option_B_,
                                                [ Ty.tuple [ T ] ],
                                                "call_mut",
                                                []
                                              |),
                                              [ f; Value.Tuple [ M.read (| item |) ] ]
                                            |)
                                          |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let γ0_0 :=
                                                  M.SubPointer.get_struct_tuple_field (|
                                                    γ,
                                                    "core::option::Option::Some",
                                                    0
                                                  |) in
                                                let x := M.copy (| γ0_0 |) in
                                                M.alloc (|
                                                  M.call_closure (|
                                                    M.get_trait_method (|
                                                      "core::ops::function::FnMut",
                                                      impl_FnMut_Acc__B__arrow_Acc,
                                                      [ Ty.tuple [ Acc; B ] ],
                                                      "call_mut",
                                                      []
                                                    |),
                                                    [
                                                      fold;
                                                      Value.Tuple
                                                        [ M.read (| acc |); M.read (| x |) ]
                                                    ]
                                                  |)
                                                |)));
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let _ :=
                                                  M.is_struct_tuple (|
                                                    γ,
                                                    "core::option::Option::None"
                                                  |) in
                                                acc))
                                          ]
                                        |)
                                      |)))
                                ]
                              |)))
                        ]
                      |)))
                  | _ => M.impossible "wrong number of arguments"
                  end))))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Function_filter_map_fold :
        M.IsFunction "core::iter::adapters::filter_map::filter_map_fold" filter_map_fold.
      
      Module filter_map_fold.
        (* Error OpaqueTy *)
      End filter_map_fold.
      
      (*
      fn filter_map_try_fold<'a, T, B, Acc, R: Try<Output = Acc>>(
          f: &'a mut impl FnMut(T) -> Option<B>,
          mut fold: impl FnMut(Acc, B) -> R + 'a,
      ) -> impl FnMut(Acc, T) -> R + 'a {
          move |acc, item| match f(item) {
              Some(x) => fold(acc, x),
              None => try { acc },
          }
      }
      *)
      Definition filter_map_try_fold (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [],
            [ T; B; Acc; R; impl_FnMut_T__arrow_Option_B_; impl_FnMut_Acc__B__arrow_R__plus__'a ],
            [ f; fold ] =>
          ltac:(M.monadic
            (let f := M.alloc (| f |) in
            let fold := M.alloc (| fold |) in
            M.closure
              (fun γ =>
                ltac:(M.monadic
                  match γ with
                  | [ α0; α1 ] =>
                    ltac:(M.monadic
                      (M.match_operator (|
                        M.alloc (| α0 |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let acc := M.copy (| γ |) in
                              M.match_operator (|
                                M.alloc (| α1 |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let item := M.copy (| γ |) in
                                      M.read (|
                                        M.match_operator (|
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_trait_method (|
                                                "core::ops::function::FnMut",
                                                impl_FnMut_T__arrow_Option_B_,
                                                [ Ty.tuple [ T ] ],
                                                "call_mut",
                                                []
                                              |),
                                              [ M.read (| f |); Value.Tuple [ M.read (| item |) ] ]
                                            |)
                                          |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let γ0_0 :=
                                                  M.SubPointer.get_struct_tuple_field (|
                                                    γ,
                                                    "core::option::Option::Some",
                                                    0
                                                  |) in
                                                let x := M.copy (| γ0_0 |) in
                                                M.alloc (|
                                                  M.call_closure (|
                                                    M.get_trait_method (|
                                                      "core::ops::function::FnMut",
                                                      impl_FnMut_Acc__B__arrow_R__plus__'a,
                                                      [ Ty.tuple [ Acc; B ] ],
                                                      "call_mut",
                                                      []
                                                    |),
                                                    [
                                                      fold;
                                                      Value.Tuple
                                                        [ M.read (| acc |); M.read (| x |) ]
                                                    ]
                                                  |)
                                                |)));
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let _ :=
                                                  M.is_struct_tuple (|
                                                    γ,
                                                    "core::option::Option::None"
                                                  |) in
                                                M.alloc (|
                                                  M.call_closure (|
                                                    M.get_trait_method (|
                                                      "core::ops::try_trait::Try",
                                                      R,
                                                      [],
                                                      "from_output",
                                                      []
                                                    |),
                                                    [ M.read (| acc |) ]
                                                  |)
                                                |)))
                                          ]
                                        |)
                                      |)))
                                ]
                              |)))
                        ]
                      |)))
                  | _ => M.impossible "wrong number of arguments"
                  end))))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Function_filter_map_try_fold :
        M.IsFunction "core::iter::adapters::filter_map::filter_map_try_fold" filter_map_try_fold.
      
      Module filter_map_try_fold.
        (* Error OpaqueTy *)
      End filter_map_try_fold.
      
      Module Impl_core_iter_traits_iterator_Iterator_where_core_iter_traits_iterator_Iterator_I_where_core_ops_function_FnMut_F_Tuple_associated_type__for_core_iter_adapters_filter_map_FilterMap_I_F.
        Definition Self (B I F : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::filter_map::FilterMap") [] [ I; F ].
        
        (*     type Item = B; *)
        Definition _Item (B I F : Ty.t) : Ty.t := B.
        
        (*
            fn next(&mut self) -> Option<B> {
                self.iter.find_map(&mut self.f)
            }
        *)
        Definition next (B I F : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self B I F 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",
                  I,
                  [],
                  "find_map",
                  [ B; Ty.apply (Ty.path "&mut") [] [ F ] ]
                |),
                [
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "core::iter::adapters::filter_map::FilterMap",
                    "iter"
                  |);
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "core::iter::adapters::filter_map::FilterMap",
                    "f"
                  |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn next_chunk<const N: usize>(
                &mut self,
            ) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>> {
                let mut array: [MaybeUninit<Self::Item>; N] = [const { MaybeUninit::uninit() }; N];
        
                struct Guard<'a, T> {
                    array: &'a mut [MaybeUninit<T>],
                    initialized: usize,
                }
        
                impl<T> Drop for Guard<'_, T> {
                    #[inline]
                    fn drop(&mut self) {
                        if const { crate::mem::needs_drop::<T>() } {
                            // SAFETY: self.initialized is always <= N, which also is the length of the array.
                            unsafe {
                                core::ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(
                                    self.array.get_unchecked_mut(..self.initialized),
                                ));
                            }
                        }
                    }
                }
        
                let mut guard = Guard { array: &mut array, initialized: 0 };
        
                let result = self.iter.try_for_each(|element| {
                    let idx = guard.initialized;
                    let val = (self.f)(element);
                    guard.initialized = idx + val.is_some() as usize;
        
                    // SAFETY: Loop conditions ensure the index is in bounds.
        
                    unsafe {
                        let opt_payload_at: *const MaybeUninit<B> =
                            (&raw const val).byte_add(core::mem::offset_of!(Option<B>, Some.0)).cast();
                        let dst = guard.array.as_mut_ptr().add(idx);
                        crate::ptr::copy_nonoverlapping(opt_payload_at, dst, 1);
                        crate::mem::forget(val);
                    };
        
                    if guard.initialized < N { ControlFlow::Continue(()) } else { ControlFlow::Break(()) }
                });
        
                let guard = ManuallyDrop::new(guard);
        
                match result {
                    ControlFlow::Break(()) => {
                        // SAFETY: The loop above is only explicitly broken when the array has been fully initialized
                        Ok(unsafe { MaybeUninit::array_assume_init(array) })
                    }
                    ControlFlow::Continue(()) => {
                        let initialized = guard.initialized;
                        // SAFETY: The range is in bounds since the loop breaks when reaching N elements.
                        Err(unsafe { array::IntoIter::new_unchecked(array, 0..initialized) })
                    }
                }
            }
        *)
        Definition next_chunk
            (B I F : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self B I F in
          match ε, τ, α with
          | [ N ], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.read (|
                let~ array :=
                  M.alloc (|
                    repeat (|
                      M.read (|
                        M.get_constant (|
                          "core::iter::adapters::filter_map::next_chunk_discriminant"
                        |)
                      |),
                      N
                    |)
                  |) in
                let~ guard :=
                  M.alloc (|
                    Value.StructRecord
                      "core::iter::adapters::filter_map::next_chunk::Guard"
                      [ ("array", array); ("initialized", Value.Integer IntegerKind.Usize 0) ]
                  |) in
                let~ result :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_trait_method (|
                        "core::iter::traits::iterator::Iterator",
                        I,
                        [],
                        "try_for_each",
                        [
                          Ty.function
                            [ Ty.tuple [ Ty.associated ] ]
                            (Ty.apply
                              (Ty.path "core::ops::control_flow::ControlFlow")
                              []
                              [ Ty.tuple []; Ty.tuple [] ]);
                          Ty.apply
                            (Ty.path "core::ops::control_flow::ControlFlow")
                            []
                            [ Ty.tuple []; Ty.tuple [] ]
                        ]
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "core::iter::adapters::filter_map::FilterMap",
                          "iter"
                        |);
                        M.closure
                          (fun γ =>
                            ltac:(M.monadic
                              match γ with
                              | [ α0 ] =>
                                ltac:(M.monadic
                                  (M.match_operator (|
                                    M.alloc (| α0 |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let element := M.copy (| γ |) in
                                          M.read (|
                                            let~ idx :=
                                              M.copy (|
                                                M.SubPointer.get_struct_record_field (|
                                                  guard,
                                                  "core::iter::adapters::filter_map::next_chunk::Guard",
                                                  "initialized"
                                                |)
                                              |) in
                                            let~ val :=
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_trait_method (|
                                                    "core::ops::function::FnMut",
                                                    F,
                                                    [ Ty.tuple [ Ty.associated ] ],
                                                    "call_mut",
                                                    []
                                                  |),
                                                  [
                                                    M.SubPointer.get_struct_record_field (|
                                                      M.read (| self |),
                                                      "core::iter::adapters::filter_map::FilterMap",
                                                      "f"
                                                    |);
                                                    Value.Tuple [ M.read (| element |) ]
                                                  ]
                                                |)
                                              |) in
                                            let~ _ :=
                                              M.write (|
                                                M.SubPointer.get_struct_record_field (|
                                                  guard,
                                                  "core::iter::adapters::filter_map::next_chunk::Guard",
                                                  "initialized"
                                                |),
                                                BinOp.Wrap.add (|
                                                  M.read (| idx |),
                                                  M.rust_cast
                                                    (M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.apply
                                                          (Ty.path "core::option::Option")
                                                          []
                                                          [ B ],
                                                        "is_some",
                                                        []
                                                      |),
                                                      [ val ]
                                                    |))
                                                |)
                                              |) in
                                            let~ _ :=
                                              let~ opt_payload_at :=
                                                M.alloc (|
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply
                                                        (Ty.path "*const")
                                                        []
                                                        [
                                                          Ty.apply
                                                            (Ty.path "core::option::Option")
                                                            []
                                                            [ B ]
                                                        ],
                                                      "cast",
                                                      [
                                                        Ty.apply
                                                          (Ty.path
                                                            "core::mem::maybe_uninit::MaybeUninit")
                                                          []
                                                          [ B ]
                                                      ]
                                                    |),
                                                    [
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.apply
                                                            (Ty.path "*const")
                                                            []
                                                            [
                                                              Ty.apply
                                                                (Ty.path "core::option::Option")
                                                                []
                                                                [ B ]
                                                            ],
                                                          "byte_add",
                                                          []
                                                        |),
                                                        [
                                                          val;
                                                          M.read (|
                                                            (* `OffsetOf` expression are not handled yet *)
                                                            M.alloc (| Value.Tuple [] |)
                                                          |)
                                                        ]
                                                      |)
                                                    ]
                                                  |)
                                                |) in
                                              let~ dst :=
                                                M.alloc (|
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply
                                                        (Ty.path "*mut")
                                                        []
                                                        [
                                                          Ty.apply
                                                            (Ty.path
                                                              "core::mem::maybe_uninit::MaybeUninit")
                                                            []
                                                            [ B ]
                                                        ],
                                                      "add",
                                                      []
                                                    |),
                                                    [
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.apply
                                                            (Ty.path "slice")
                                                            []
                                                            [
                                                              Ty.apply
                                                                (Ty.path
                                                                  "core::mem::maybe_uninit::MaybeUninit")
                                                                []
                                                                [ B ]
                                                            ],
                                                          "as_mut_ptr",
                                                          []
                                                        |),
                                                        [
                                                          M.read (|
                                                            M.SubPointer.get_struct_record_field (|
                                                              guard,
                                                              "core::iter::adapters::filter_map::next_chunk::Guard",
                                                              "array"
                                                            |)
                                                          |)
                                                        ]
                                                      |);
                                                      M.read (| idx |)
                                                    ]
                                                  |)
                                                |) in
                                              let~ _ :=
                                                M.alloc (|
                                                  M.call_closure (|
                                                    M.get_function (|
                                                      "core::intrinsics::copy_nonoverlapping",
                                                      [
                                                        Ty.apply
                                                          (Ty.path
                                                            "core::mem::maybe_uninit::MaybeUninit")
                                                          []
                                                          [ B ]
                                                      ]
                                                    |),
                                                    [
                                                      M.read (| opt_payload_at |);
                                                      M.read (| dst |);
                                                      Value.Integer IntegerKind.Usize 1
                                                    ]
                                                  |)
                                                |) in
                                              let~ _ :=
                                                M.alloc (|
                                                  M.call_closure (|
                                                    M.get_function (|
                                                      "core::mem::forget",
                                                      [
                                                        Ty.apply
                                                          (Ty.path "core::option::Option")
                                                          []
                                                          [ B ]
                                                      ]
                                                    |),
                                                    [ M.read (| val |) ]
                                                  |)
                                                |) in
                                              M.alloc (| Value.Tuple [] |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          BinOp.lt (|
                                                            M.read (|
                                                              M.SubPointer.get_struct_record_field (|
                                                                guard,
                                                                "core::iter::adapters::filter_map::next_chunk::Guard",
                                                                "initialized"
                                                              |)
                                                            |),
                                                            M.read (|
                                                              M.get_constant (|
                                                                "core::iter::adapters::filter_map::next_chunk::N"
                                                              |)
                                                            |)
                                                          |)
                                                        |)) in
                                                    let _ :=
                                                      M.is_constant_or_break_match (|
                                                        M.read (| γ |),
                                                        Value.Bool true
                                                      |) in
                                                    M.alloc (|
                                                      Value.StructTuple
                                                        "core::ops::control_flow::ControlFlow::Continue"
                                                        [ Value.Tuple [] ]
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (M.alloc (|
                                                      Value.StructTuple
                                                        "core::ops::control_flow::ControlFlow::Break"
                                                        [ Value.Tuple [] ]
                                                    |)))
                                              ]
                                            |)
                                          |)))
                                    ]
                                  |)))
                              | _ => M.impossible "wrong number of arguments"
                              end))
                      ]
                    |)
                  |) in
                let~ guard :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply
                          (Ty.path "core::mem::manually_drop::ManuallyDrop")
                          []
                          [
                            Ty.apply
                              (Ty.path "core::iter::adapters::filter_map::next_chunk::Guard")
                              []
                              [ B ]
                          ],
                        "new",
                        []
                      |),
                      [ M.read (| guard |) ]
                    |)
                  |) in
                M.match_operator (|
                  result,
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ0_0 :=
                          M.SubPointer.get_struct_tuple_field (|
                            γ,
                            "core::ops::control_flow::ControlFlow::Break",
                            0
                          |) in
                        M.alloc (|
                          Value.StructTuple
                            "core::result::Result::Ok"
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "core::mem::maybe_uninit::MaybeUninit")
                                    []
                                    [ B ],
                                  "array_assume_init",
                                  []
                                |),
                                [ M.read (| array |) ]
                              |)
                            ]
                        |)));
                    fun γ =>
                      ltac:(M.monadic
                        (let γ0_0 :=
                          M.SubPointer.get_struct_tuple_field (|
                            γ,
                            "core::ops::control_flow::ControlFlow::Continue",
                            0
                          |) in
                        let~ initialized :=
                          M.copy (|
                            M.SubPointer.get_struct_record_field (|
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::ops::deref::Deref",
                                  Ty.apply
                                    (Ty.path "core::mem::manually_drop::ManuallyDrop")
                                    []
                                    [
                                      Ty.apply
                                        (Ty.path
                                          "core::iter::adapters::filter_map::next_chunk::Guard")
                                        []
                                        [ B ]
                                    ],
                                  [],
                                  "deref",
                                  []
                                |),
                                [ guard ]
                              |),
                              "core::iter::adapters::filter_map::next_chunk::Guard",
                              "initialized"
                            |)
                          |) in
                        M.alloc (|
                          Value.StructTuple
                            "core::result::Result::Err"
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply (Ty.path "core::array::iter::IntoIter") [ N ] [ B ],
                                  "new_unchecked",
                                  []
                                |),
                                [
                                  M.read (| array |);
                                  Value.StructRecord
                                    "core::ops::range::Range"
                                    [
                                      ("start", Value.Integer IntegerKind.Usize 0);
                                      ("end_", M.read (| initialized |))
                                    ]
                                ]
                              |)
                            ]
                        |)))
                  ]
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn size_hint(&self) -> (usize, Option<usize>) {
                let (_, upper) = self.iter.size_hint();
                (0, upper) // can't know a lower bound, due to the predicate
            }
        *)
        Definition size_hint
            (B I F : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self B I F in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.read (|
                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 |),
                          "core::iter::adapters::filter_map::FilterMap",
                          "iter"
                        |)
                      ]
                    |)
                  |),
                  [
                    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 upper := M.copy (| γ0_1 |) in
                        M.alloc (|
                          Value.Tuple [ Value.Integer IntegerKind.Usize 0; M.read (| upper |) ]
                        |)))
                  ]
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
            where
                Self: Sized,
                Fold: FnMut(Acc, Self::Item) -> R,
                R: Try<Output = Acc>,
            {
                self.iter.try_fold(init, filter_map_try_fold(&mut self.f, fold))
            }
        *)
        Definition try_fold
            (B I F : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self B I F in
          match ε, τ, α with
          | [], [ Acc; Fold; R ], [ self; init; fold ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let init := M.alloc (| init |) in
              let fold := M.alloc (| fold |) in
              M.call_closure (|
                M.get_trait_method (|
                  "core::iter::traits::iterator::Iterator",
                  I,
                  [],
                  "try_fold",
                  [ Acc; Ty.associated; R ]
                |),
                [
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "core::iter::adapters::filter_map::FilterMap",
                    "iter"
                  |);
                  M.read (| init |);
                  M.call_closure (|
                    M.get_function (|
                      "core::iter::adapters::filter_map::filter_map_try_fold",
                      [ Ty.associated; B; Acc; R; F; Fold ]
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::iter::adapters::filter_map::FilterMap",
                        "f"
                      |);
                      M.read (| fold |)
                    ]
                  |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn fold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
            where
                Fold: FnMut(Acc, Self::Item) -> Acc,
            {
                self.iter.fold(init, filter_map_fold(self.f, fold))
            }
        *)
        Definition fold (B I F : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self B I F in
          match ε, τ, α with
          | [], [ Acc; Fold ], [ self; init; fold ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let init := M.alloc (| init |) in
              let fold := M.alloc (| fold |) in
              M.call_closure (|
                M.get_trait_method (|
                  "core::iter::traits::iterator::Iterator",
                  I,
                  [],
                  "fold",
                  [ Acc; Ty.associated ]
                |),
                [
                  M.read (|
                    M.SubPointer.get_struct_record_field (|
                      self,
                      "core::iter::adapters::filter_map::FilterMap",
                      "iter"
                    |)
                  |);
                  M.read (| init |);
                  M.call_closure (|
                    M.get_function (|
                      "core::iter::adapters::filter_map::filter_map_fold",
                      [ Ty.associated; B; Acc; F; Fold ]
                    |),
                    [
                      M.read (|
                        M.SubPointer.get_struct_record_field (|
                          self,
                          "core::iter::adapters::filter_map::FilterMap",
                          "f"
                        |)
                      |);
                      M.read (| fold |)
                    ]
                  |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (B I F : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::iterator::Iterator"
            (Self B I F)
            (* Trait polymorphic types *) []
            (* Instance *)
            [
              ("Item", InstanceField.Ty (_Item B I F));
              ("next", InstanceField.Method (next B I F));
              ("next_chunk", InstanceField.Method (next_chunk B I F));
              ("size_hint", InstanceField.Method (size_hint B I F));
              ("try_fold", InstanceField.Method (try_fold B I F));
              ("fold", InstanceField.Method (fold B I F))
            ].
      End Impl_core_iter_traits_iterator_Iterator_where_core_iter_traits_iterator_Iterator_I_where_core_ops_function_FnMut_F_Tuple_associated_type__for_core_iter_adapters_filter_map_FilterMap_I_F.
      
      Module Impl_core_iter_traits_double_ended_DoubleEndedIterator_where_core_iter_traits_double_ended_DoubleEndedIterator_I_where_core_ops_function_FnMut_F_Tuple_associated_type__for_core_iter_adapters_filter_map_FilterMap_I_F.
        Definition Self (B I F : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::filter_map::FilterMap") [] [ I; F ].
        
        (*
            fn next_back(&mut self) -> Option<B> {
                #[inline]
                fn find<T, B>(
                    f: &mut impl FnMut(T) -> Option<B>,
                ) -> impl FnMut((), T) -> ControlFlow<B> + '_ {
                    move |(), x| match f(x) {
                        Some(x) => ControlFlow::Break(x),
                        None => ControlFlow::Continue(()),
                    }
                }
        
                self.iter.try_rfold((), find(&mut self.f)).break_value()
            }
        *)
        Definition next_back
            (B I F : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self B I F in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "core::ops::control_flow::ControlFlow") [] [ B; Ty.tuple [] ],
                  "break_value",
                  []
                |),
                [
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::iter::traits::double_ended::DoubleEndedIterator",
                      I,
                      [],
                      "try_rfold",
                      [
                        Ty.tuple [];
                        Ty.associated;
                        Ty.apply
                          (Ty.path "core::ops::control_flow::ControlFlow")
                          []
                          [ B; Ty.tuple [] ]
                      ]
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::iter::adapters::filter_map::FilterMap",
                        "iter"
                      |);
                      Value.Tuple [];
                      M.call_closure (|
                        M.get_associated_function (| Self, "find.next_back", [] |),
                        [
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "core::iter::adapters::filter_map::FilterMap",
                            "f"
                          |)
                        ]
                      |)
                    ]
                  |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
            where
                Self: Sized,
                Fold: FnMut(Acc, Self::Item) -> R,
                R: Try<Output = Acc>,
            {
                self.iter.try_rfold(init, filter_map_try_fold(&mut self.f, fold))
            }
        *)
        Definition try_rfold
            (B I F : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self B I F in
          match ε, τ, α with
          | [], [ Acc; Fold; R ], [ self; init; fold ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let init := M.alloc (| init |) in
              let fold := M.alloc (| fold |) in
              M.call_closure (|
                M.get_trait_method (|
                  "core::iter::traits::double_ended::DoubleEndedIterator",
                  I,
                  [],
                  "try_rfold",
                  [ Acc; Ty.associated; R ]
                |),
                [
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "core::iter::adapters::filter_map::FilterMap",
                    "iter"
                  |);
                  M.read (| init |);
                  M.call_closure (|
                    M.get_function (|
                      "core::iter::adapters::filter_map::filter_map_try_fold",
                      [ Ty.associated; B; Acc; R; F; Fold ]
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "core::iter::adapters::filter_map::FilterMap",
                        "f"
                      |);
                      M.read (| fold |)
                    ]
                  |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn rfold<Acc, Fold>(self, init: Acc, fold: Fold) -> Acc
            where
                Fold: FnMut(Acc, Self::Item) -> Acc,
            {
                self.iter.rfold(init, filter_map_fold(self.f, fold))
            }
        *)
        Definition rfold (B I F : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self B I F in
          match ε, τ, α with
          | [], [ Acc; Fold ], [ self; init; fold ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let init := M.alloc (| init |) in
              let fold := M.alloc (| fold |) in
              M.call_closure (|
                M.get_trait_method (|
                  "core::iter::traits::double_ended::DoubleEndedIterator",
                  I,
                  [],
                  "rfold",
                  [ Acc; Ty.associated ]
                |),
                [
                  M.read (|
                    M.SubPointer.get_struct_record_field (|
                      self,
                      "core::iter::adapters::filter_map::FilterMap",
                      "iter"
                    |)
                  |);
                  M.read (| init |);
                  M.call_closure (|
                    M.get_function (|
                      "core::iter::adapters::filter_map::filter_map_fold",
                      [ Ty.associated; B; Acc; F; Fold ]
                    |),
                    [
                      M.read (|
                        M.SubPointer.get_struct_record_field (|
                          self,
                          "core::iter::adapters::filter_map::FilterMap",
                          "f"
                        |)
                      |);
                      M.read (| fold |)
                    ]
                  |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (B I F : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::double_ended::DoubleEndedIterator"
            (Self B I F)
            (* Trait polymorphic types *) []
            (* Instance *)
            [
              ("next_back", InstanceField.Method (next_back B I F));
              ("try_rfold", InstanceField.Method (try_rfold B I F));
              ("rfold", InstanceField.Method (rfold B I F))
            ].
      End Impl_core_iter_traits_double_ended_DoubleEndedIterator_where_core_iter_traits_double_ended_DoubleEndedIterator_I_where_core_ops_function_FnMut_F_Tuple_associated_type__for_core_iter_adapters_filter_map_FilterMap_I_F.
      
      Module Impl_core_iter_traits_marker_FusedIterator_where_core_iter_traits_marker_FusedIterator_I_where_core_ops_function_FnMut_F_Tuple_associated_type__for_core_iter_adapters_filter_map_FilterMap_I_F.
        Definition Self (B I F : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::filter_map::FilterMap") [] [ I; F ].
        
        Axiom Implements :
          forall (B I F : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::marker::FusedIterator"
            (Self B I F)
            (* Trait polymorphic types *) []
            (* Instance *) [].
      End Impl_core_iter_traits_marker_FusedIterator_where_core_iter_traits_marker_FusedIterator_I_where_core_ops_function_FnMut_F_Tuple_associated_type__for_core_iter_adapters_filter_map_FilterMap_I_F.
      
      Module Impl_core_iter_traits_marker_TrustedFused_where_core_iter_traits_marker_TrustedFused_I_for_core_iter_adapters_filter_map_FilterMap_I_F.
        Definition Self (I F : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::filter_map::FilterMap") [] [ I; F ].
        
        Axiom Implements :
          forall (I F : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::marker::TrustedFused"
            (Self I F)
            (* Trait polymorphic types *) []
            (* Instance *) [].
      End Impl_core_iter_traits_marker_TrustedFused_where_core_iter_traits_marker_TrustedFused_I_for_core_iter_adapters_filter_map_FilterMap_I_F.
      
      Module Impl_core_iter_adapters_SourceIter_where_core_iter_adapters_SourceIter_I_for_core_iter_adapters_filter_map_FilterMap_I_F.
        Definition Self (I F : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::filter_map::FilterMap") [] [ I; F ].
        
        (*     type Source = I::Source; *)
        Definition _Source (I F : Ty.t) : Ty.t := Ty.associated.
        
        (*
            unsafe fn as_inner(&mut self) -> &mut I::Source {
                // SAFETY: unsafe function forwarding to unsafe function with the same requirements
                unsafe { SourceIter::as_inner(&mut self.iter) }
            }
        *)
        Definition as_inner
            (I F : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self I F in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.call_closure (|
                M.get_trait_method (| "core::iter::adapters::SourceIter", I, [], "as_inner", [] |),
                [
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "core::iter::adapters::filter_map::FilterMap",
                    "iter"
                  |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (I F : Ty.t),
          M.IsTraitInstance
            "core::iter::adapters::SourceIter"
            (Self I F)
            (* Trait polymorphic types *) []
            (* Instance *)
            [
              ("Source", InstanceField.Ty (_Source I F));
              ("as_inner", InstanceField.Method (as_inner I F))
            ].
      End Impl_core_iter_adapters_SourceIter_where_core_iter_adapters_SourceIter_I_for_core_iter_adapters_filter_map_FilterMap_I_F.
      
      Module Impl_core_iter_traits_marker_InPlaceIterable_where_core_iter_traits_marker_InPlaceIterable_I_for_core_iter_adapters_filter_map_FilterMap_I_F.
        Definition Self (I F : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "core::iter::adapters::filter_map::FilterMap") [] [ I; F ].
        
        (*     const EXPAND_BY: Option<NonZero<usize>> = I::EXPAND_BY; *)
        (* Ty.apply
          (Ty.path "core::option::Option")
          []
          [ Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ] ] *)
        Definition value_EXPAND_BY (I F : Ty.t) : Value.t :=
          let Self : Ty.t := Self I F in
          M.run
            ltac:(M.monadic
              (M.get_constant (| "core::iter::traits::marker::InPlaceIterable::EXPAND_BY" |))).
        
        (*     const MERGE_BY: Option<NonZero<usize>> = I::MERGE_BY; *)
        (* Ty.apply
          (Ty.path "core::option::Option")
          []
          [ Ty.apply (Ty.path "core::num::nonzero::NonZero") [] [ Ty.path "usize" ] ] *)
        Definition value_MERGE_BY (I F : Ty.t) : Value.t :=
          let Self : Ty.t := Self I F in
          M.run
            ltac:(M.monadic
              (M.get_constant (| "core::iter::traits::marker::InPlaceIterable::MERGE_BY" |))).
        
        Axiom Implements :
          forall (I F : Ty.t),
          M.IsTraitInstance
            "core::iter::traits::marker::InPlaceIterable"
            (Self I F)
            (* Trait polymorphic types *) []
            (* Instance *)
            [
              ("value_EXPAND_BY", InstanceField.Constant (value_EXPAND_BY I F));
              ("value_MERGE_BY", InstanceField.Constant (value_MERGE_BY I F))
            ].
      End Impl_core_iter_traits_marker_InPlaceIterable_where_core_iter_traits_marker_InPlaceIterable_I_for_core_iter_adapters_filter_map_FilterMap_I_F.
    End filter_map.
  End adapters.
End iter.
