pub trait LendingIteratorwhere
    Self: for<'next> LendingIteratorඞItem<'next>,{
Show 27 methods // Required method fn next(&mut self) -> Option<Item<'_, Self>>; // Provided methods fn filter<F>(self, should_yield: F) -> Filter<Self, F> where Self: Sized, F: FnMut(&Item<'_, Self>) -> bool { ... } fn for_each(self, f: impl FnMut(Item<'_, Self>)) where Self: Sized { ... } fn fold<Acc>( self, acc: Acc, f: impl FnMut(Acc, Item<'_, Self>) -> Acc ) -> Acc where Self: Sized { ... } fn try_for_each<Err>( &mut self, f: impl FnMut(Item<'_, Self>) -> Result<(), Err> ) -> Result<(), Err> { ... } fn try_fold<Acc, Err>( &mut self, acc: Acc, f: impl FnMut(Acc, Item<'_, Self>) -> Result<Acc, Err> ) -> Result<Acc, Err> { ... } fn all(&mut self, predicate: impl FnMut(Item<'_, Self>) -> bool) -> bool where Self: Sized { ... } fn any(&mut self, predicate: impl FnMut(Item<'_, Self>) -> bool) -> bool where Self: Sized { ... } fn by_ref(&mut self) -> &mut Self where Self: Sized { ... } fn count(self) -> usize where Self: Sized { ... } fn find<'find>( &'find mut self, predicate: impl 'find + FnMut(&Item<'_, Self>) -> bool ) -> Option<Item<'find, Self>> where Self: Sized { ... } fn fuse(self) -> Fuse<Self> where Self: Sized { ... } fn nth(&mut self, n: usize) -> Option<Item<'_, Self>> { ... } fn position<F>( &mut self, predicate: impl FnMut(Item<'_, Self>) -> bool ) -> Option<usize> where Self: Sized { ... } fn skip(self, count: usize) -> Skip<Self> where Self: Sized { ... } fn take(self, count: usize) -> Take<Self> where Self: Sized { ... } fn map<NewItemType: HKT, F>(self, f: F) -> Map<Self, F, NewItemType> where for<'next> F: FnMut([&'next Self; 0], Item<'next, Self>) -> Feed<'next, NewItemType>, Self: Sized { ... } fn map_to_ref<R: ?Sized, F>(self, f: F) -> Map<Self, F, HKTRef<R>> where for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> &'any R, Self: Sized { ... } fn map_to_mut<R: ?Sized, F>(self, f: F) -> Map<Self, F, HKTRefMut<R>> where for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> &'any mut R, Self: Sized { ... } fn map_into_iter<F, NonLendingItem>(self, f: F) -> MapIntoIter<Self, F> where F: FnMut(Item<'_, Self>) -> NonLendingItem, Self: Sized { ... } fn filter_map<NewItemType: HKT, F>( self, f: F ) -> FilterMap<Self, F, NewItemType> where for<'next> F: FnMut([&'next Self; 0], Item<'next, Self>) -> Option<Feed<'next, NewItemType>>, Self: Sized { ... } fn filter_map_to_ref<R: ?Sized, F>( self, f: F ) -> FilterMap<Self, F, HKTRef<R>> where for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> Option<&'any R>, Self: Sized { ... } fn filter_map_to_mut<R: ?Sized, F>( self, f: F ) -> FilterMap<Self, F, HKTRefMut<R>> where for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> Option<&'any mut R>, Self: Sized { ... } fn filter_map_into_iter<F, NonLendingItem>( self, f: F ) -> FilterMapIntoIter<Self, F> where F: FnMut(Item<'_, Self>) -> Option<NonLendingItem>, Self: Sized { ... } fn into_iter<Item>(self) -> IntoIter<Self> where Self: for<'any> LendingIteratorඞItem<'any, T = Item> + Sized { ... } fn dyn_boxed<'usability>( self ) -> Box<dyn LendingIteratorDyn<Item = HKTItem<Self>> + 'usability> where Self: 'usability + Sized { ... } fn dyn_boxed_auto<BoxedDynLendingIterator, Item: HKT>( self ) -> BoxedDynLendingIterator where Self: Sized + DynCoerce<BoxedDynLendingIterator, Item> { ... }
}
Expand description

The meat of the crate. Trait similar to Iterator but for the return type of the fn next(&'_ mut self) method being allowed to depend on that '_.

Click to hide
  • That type is called the Item<'_> type, and is a generic_associated_type.

  • That difference is crucial both in terms of signature complexity (as this crate’s API ought to prove 😅) and borrowing semantics.

Mainly, when yielded, such Item<'_> is still &mut borrowing *self, so it won’t be possible to further advance the iterator (or anything else, for that matter), until the current item is no longer used.

That is: the Item<'_>s yielded by a LendingIterator cannot coëxist!

  • this will thus impose serious usability limitations on it (e.g, no .collect()ing whatsoever, since collecting items, by definition, expects them to coëxist (within the collection)).

    • For instance, there won’t be a for item in iter { sugar on these things, since that for sugar currently only blesses the stdlib Iterator trait.

      That being said, while let Some(item) = iter.next() { works just as well, to be honest.

  • but the dual / other side of that API restriction is that it is way simpler / less constraining, for implementors, to implement this trait.

    The canonical example illustrating this difference is windows_mut(), which is both an intuitive “iterator” we can think of, and yet something for which it is impossible to implement Iterator.

A Generic Associated Type

The core definition of this trait is thus:

  • #![feature(generic_associated_types)]
    
    trait LendingIterator {
        type Item<'next>
        where
            Self : 'next,
        ;
    
        fn next<'next> (
            self: &'next mut Self, // <- `Self : 'next` indeed!
        ) -> Option<Self::Item<'next>>
        ;
    }

As you can see, it involves that more complex type Item definition, which is called a generic associated type (GAT for short), and, it currently requires the nightly-only feature(generic_associated_types).

–Then how come this crate can work on stable?— you may ask.

The answer is that (lifetime)-GATs can actually be emulated in stable Rust through some extra slightly convoluted hoops.

That’s why this crate uses those techniques (and the crate featuring them, ::nougat), to achieve Stable Rust support:

  • #[::nougat::gat] // 👈 Add this and now It Just Works™ on stable.
    trait LendingIterator {
        type Item<'next>
        where
            Self : 'next,
        ;
    
        fn next<'next> (
            self: &'next mut Self,
        ) -> Option<Self::Item<'next>>
        ;
    }

It does come with a few caveats, though: the LendingIterator::Item item is no longer really nameable, at least not directly.

  • The current implementation of ::nougat uses a helper higher-order super-trait, called for<'any> LendingIteratorඞItem<'any>, which has, itself, a non-generic associated type, ::T. That way, LendingIteratorඞItem<'next>::T plays the role of LendingIterator::Item<'next>.

    BUT THIS MAY change within semver-compatible changes of nougat

    That’s why that path should never be used, directly, by downstream code.

    The only reason I am even talking about it and not having it #[doc(hidden)] is that exposing it makes understanding the signatures of the adapters multiple order of magnitude easier.

Hence the following “rules”:

  • Use Item<'_, I> instead of I::Item<'_>.

    • you could technically import the Gat! macro from the ::nougat crate, and then use Gat!(I::Item<'_>) (this is how this crate manages to define Item, for instance). But it seems less convenient than a type alias.

    • within a #[gat]-annotated trait or impl, most of the …::Item<'_> mentions will automagically be amended by the macro (which is why the previous snippet works, despite its usage of Self::Item<'next>).

  • If implementing the trait yourself, you need to apply #[gat] to the impl yourself.

  • If reëxporting the trait yourself, you need to also apply #[gat(Item)] to the use statement as well, so people can implement the trait through the new path.

  • LendingIterator is not really dyn-friendly (although IIUC, with feature(generic_associated_types) it wouldn’t have been either).

    But you can use dyn LendingIteratorDyn<Item = …> + … instead, which has been designed with dyn-friendlyness in mind 🙂.

Required Methods§

source

fn next(&mut self) -> Option<Item<'_, Self>>

Query the next() Item of this Self iterator.

LendingIterator counterpart of Iterator::next().

Provided Methods§

source

fn filter<F>(self, should_yield: F) -> Filter<Self, F> where Self: Sized, F: FnMut(&Item<'_, Self>) -> bool,

source

fn for_each(self, f: impl FnMut(Item<'_, Self>))where Self: Sized,

source

fn fold<Acc>(self, acc: Acc, f: impl FnMut(Acc, Item<'_, Self>) -> Acc) -> Accwhere Self: Sized,

source

fn try_for_each<Err>( &mut self, f: impl FnMut(Item<'_, Self>) -> Result<(), Err> ) -> Result<(), Err>

source

fn try_fold<Acc, Err>( &mut self, acc: Acc, f: impl FnMut(Acc, Item<'_, Self>) -> Result<Acc, Err> ) -> Result<Acc, Err>

source

fn all(&mut self, predicate: impl FnMut(Item<'_, Self>) -> bool) -> boolwhere Self: Sized,

source

fn any(&mut self, predicate: impl FnMut(Item<'_, Self>) -> bool) -> boolwhere Self: Sized,

source

fn by_ref(&mut self) -> &mut Self where Self: Sized,

source

fn count(self) -> usizewhere Self: Sized,

source

fn find<'find>( &'find mut self, predicate: impl 'find + FnMut(&Item<'_, Self>) -> bool ) -> Option<Item<'find, Self>>where Self: Sized,

source

fn fuse(self) -> Fuse<Self> where Self: Sized,

source

fn nth(&mut self, n: usize) -> Option<Item<'_, Self>>

source

fn position<F>( &mut self, predicate: impl FnMut(Item<'_, Self>) -> bool ) -> Option<usize>where Self: Sized,

source

fn skip(self, count: usize) -> Skip<Self> where Self: Sized,

source

fn take(self, count: usize) -> Take<Self> where Self: Sized,

source

fn map<NewItemType: HKT, F>(self, f: F) -> Map<Self, F, NewItemType> where for<'next> F: FnMut([&'next Self; 0], Item<'next, Self>) -> Feed<'next, NewItemType>, Self: Sized,

LendingIterator counterpart of Iterator::map().

  • Turbofishing the NewItemType is mandatory, otherwise you’ll run into issues with non-higher-order closures.

    See the module-level documentation of crate::higher_kinded_types for more info.

    But the TL,DR is that you’d use it as:

    lending_iter.map::<HKT!(ReturnType<'_>), _>(

  • the second idiosyncracy is that, for technical reasons1 related to the maximally generic aspect of this API, the closure itself cannot just be a Self::Item<'_> -> Feed<'_, NewItemType> closure, and instead, requires that an extra [] dummy parameter be part of the signature:

    lending_iter.map::<HKT…, _>(|[], item| { … })
                                 👆

  1. In the case where Self::Item<'_> does not depend on '_, the return type then technically can’t depend on it either, so Rust complains about this (in a rather obtuse fashion). We solve this by requiring that extra [] parameter which acts as a convenient-to-write PhantomData which does depend on '_

source

fn map_to_ref<R: ?Sized, F>(self, f: F) -> Map<Self, F, HKTRef<R>> where for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> &'any R, Self: Sized,

Convenience method: same as .map(), but for hard-coding the HKT parameter to HKTRef<R> = HKT!(&R).

This alleviates the call-sites (no more turbofishing needed!) for such pervasive use cases 🙂

source

fn map_to_mut<R: ?Sized, F>(self, f: F) -> Map<Self, F, HKTRefMut<R>> where for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> &'any mut R, Self: Sized,

Convenience method: same as .map(), but for hard-coding the HKT parameter to HKTRefMut<R> = HKT!(&mut R).

This alleviates the call-sites (no more turbofishing needed!) for such pervasive use cases 🙂

source

fn map_into_iter<F, NonLendingItem>(self, f: F) -> MapIntoIter<Self, F> where F: FnMut(Item<'_, Self>) -> NonLendingItem, Self: Sized,

Convenience shorthand for .map…(…).into_iter().

When the return type of the .map() closure is not lending / borrowing from *self, it becomes possible to call .into_iter() on it right away.

Moreover, it makes the [], closure arg hack no longer necessary.

This convenience function encompasses both things, thence returning an Iterator (not a LendingIterator!).

source

fn filter_map<NewItemType: HKT, F>( self, f: F ) -> FilterMap<Self, F, NewItemType> where for<'next> F: FnMut([&'next Self; 0], Item<'next, Self>) -> Option<Feed<'next, NewItemType>>, Self: Sized,

LendingIterator counterpart of Iterator::filter_map().

All the caveats and remarks of .map() apply, go check them up.

source

fn filter_map_to_ref<R: ?Sized, F>(self, f: F) -> FilterMap<Self, F, HKTRef<R>> where for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> Option<&'any R>, Self: Sized,

Convenience method: same as .filter_map(), but for hard-coding the HKT parameter to HKTRef<R> = HKT!(&R).

All the caveats and remarks of .map_to_ref() apply, go check them up.

source

fn filter_map_to_mut<R: ?Sized, F>( self, f: F ) -> FilterMap<Self, F, HKTRefMut<R>> where for<'any> F: FnMut([&'any Self; 0], Item<'any, Self>) -> Option<&'any mut R>, Self: Sized,

Convenience method: same as .filter_map(), but for hard-coding the HKT parameter to HKTRefMut<R> = HKT!(&mut R).

All the caveats and remarks of .map_to_mut() apply, go check them up.

source

fn filter_map_into_iter<F, NonLendingItem>( self, f: F ) -> FilterMapIntoIter<Self, F> where F: FnMut(Item<'_, Self>) -> Option<NonLendingItem>, Self: Sized,

Convenience shorthand for .filter_map…(…).into_iter().

When the return type of the .filter_map() closure is not lending / borrowing from *self, it becomes possible to call .into_iter() on it right away.

Moreover, it makes the [], closure arg hack no longer necessary.

This convenience function encompasses both things, thence returning an Iterator (not a LendingIterator!).

source

fn into_iter<Item>(self) -> IntoIter<Self> where Self: for<'any> LendingIteratorඞItem<'any, T = Item> + Sized,

Convert a Self : LendingIterator into an Iterator, provided Self::Item<'_> does not depend on '_.

source

fn dyn_boxed<'usability>( self ) -> Box<dyn LendingIteratorDyn<Item = HKTItem<Self>> + 'usability>where Self: 'usability + Sized,

Available on crate feature alloc only.

Converts this LendingIterator into a Box<dyn LendingIteratorDyn…>.

Note that the return dyn Trait will not be Send or implement any other auto-traits. For a more general albeit harder-on-type-inference alternative, see .dyn_boxed_auto().

source

fn dyn_boxed_auto<BoxedDynLendingIterator, Item: HKT>( self ) -> BoxedDynLendingIteratorwhere Self: Sized + DynCoerce<BoxedDynLendingIterator, Item>,

Available on crate feature alloc only.

Converts this LendingIterator into a Box<dyn LendingIteratorDyn…>.

In order for it to work, the Item parameter has to be provided (probably funneled through a CanonicalHKT), as well as an explicit “landing type” (inference will probably fail to figure it out!).

That is, BoxedDynLendingIterator is expected to be of the form:

Box<dyn 'lt [+ Send] [+ Sync] + LendingIteratorDyn<Item = CanonicalHKT<…>>>

Implementations on Foreign Types§

source§

impl<I: ?Sized + LendingIterator> LendingIterator for Box<I>

Available on crate feature alloc only.
source§

fn next<'next>(self: &'next mut Box<I>) -> Option<Item<'next, Self>>

source§

impl<'r, I: ?Sized + LendingIterator> LendingIterator for &'r mut I

source§

fn next<'next>(self: &'next mut &'r mut I) -> Option<Item<'next, Self>>

source§

impl<I> LendingIterator for Pin<Box<I>>where I: Unpin + ?Sized + LendingIterator,

Available on crate feature alloc only.
source§

fn next<'next>(self: &'next mut Pin<Box<I>>) -> Option<Item<'next, Self>>

source§

impl<'r, I> LendingIterator for Pin<&'r mut I>where I: Unpin + ?Sized + LendingIterator,

source§

fn next<'next>(self: &'next mut Pin<&'r mut I>) -> Option<Item<'next, Self>>

Implementors§

source§

impl<'lt, T, const WINDOW_SIZE: usize> LendingIterator for WindowsMut<&'lt mut [T], WINDOW_SIZE>

source§

impl<'usability, Item: HKT> LendingIterator for dyn LendingIteratorDyn<Item = Item> + 'usability

dyn LendingIteratorDyn + … : LendingIterator

source§

impl<'usability, Item: HKT> LendingIterator for dyn LendingIteratorDyn<Item = Item> + Send + 'usability

dyn LendingIteratorDyn + … : LendingIterator

source§

impl<'usability, Item: HKT> LendingIterator for dyn LendingIteratorDyn<Item = Item> + Send + Sync + 'usability

dyn LendingIteratorDyn + … : LendingIterator

source§

impl<'usability, Item: HKT> LendingIterator for dyn LendingIteratorDyn<Item = Item> + Sync + 'usability

dyn LendingIteratorDyn + … : LendingIterator

source§

impl<I, F> LendingIterator for Filter<I, F>where I: LendingIterator, F: FnMut(&Item<'_, I>) -> bool,

source§

impl<I, NewItemType, F> LendingIterator for FilterMap<I, F, NewItemType>where I: LendingIterator, NewItemType: HKT, for<'any> F: FnMut([&'any I; 0], Item<'any, I>) -> Option<Feed<'any, NewItemType>>,

source§

impl<I, NewItemType, F> LendingIterator for Map<I, F, NewItemType>where I: LendingIterator, NewItemType: HKT, for<'any> F: FnMut([&'any I; 0], Item<'any, I>) -> Feed<'any, NewItemType>,

source§

impl<I: LendingIterator> LendingIterator for Fuse<I>

source§

impl<I: LendingIterator> LendingIterator for Skip<I>

source§

impl<I: LendingIterator> LendingIterator for Take<I>

source§

impl<I: ?Sized + Iterator> LendingIterator for FromIter<I>

source§

impl<Item, State, Next> LendingIterator for FromFn<Item, State, Next>where Item: HKT, Next: FnMut(&mut State) -> Option<Feed<'_, Item>>,

source§

impl<S: Stream + Unpin> LendingIterator for FromStream<S>

Available on crate feature futures only.
source§

impl<State> LendingIterator for RepeatMut<State>