-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to express a Fn generic with a lifetime involved without falling into 'static #108852
Comments
This doesn't seem to be a bug as such, just a problem you were trying to solve you ran into difficulty with. The issue tracker is not a support forum. For future questions please ask in one of these places: https://discord.gg/rust-lang/ |
Ok, thanks @jyn514 for the reply. Just to leave something for the poor people who lands here searching for the same problem, this version works: pub trait LendingIterator {
type Item<'a>
where
Self: 'a;
fn next(&'_ mut self) -> Option<Self::Item<'_>>;
}
pub trait PeekableIterator: Iterator + Sized {
fn peekable_iter(self) -> Peekable<Self> {
Peekable::new(self)
}
}
impl<T: Iterator> PeekableIterator for T {}
pub struct Peekable<T: Iterator> {
inner: T,
next: Option<T::Item>,
}
impl<T: Iterator> Peekable<T> {
fn new(mut inner: T) -> Self {
let next = inner.next();
Peekable { inner, next }
}
fn next(&mut self) -> Option<T::Item> {
std::mem::replace(&mut self.next, self.inner.next())
}
}
impl<T: Iterator> LendingIterator for Peekable<T> {
type Item<'a> = (T::Item, Option<&'a T::Item>) where T: 'a;
fn next(&'_ mut self) -> Option<Self::Item<'_>> {
self.next().map(|t| (t, self.next.as_ref()))
}
}
pub trait LendingIteratorExt: LendingIterator {
fn for_each<F>(self, mut f: F)
where
Self: Sized,
F: for<'a> FnMut(Self::Item<'a>),
{
/*
#[inline]
fn call<T>(mut f: impl FnMut(T)) -> impl FnMut((), T) {
move |(), item| f(item)
}
self.fold((), call(f));
*/
self.fold((), move |_, item| f(item))
}
fn fold<B, F>(mut self, init: B, mut f: F) -> B
where
Self: Sized,
F: for<'a> FnMut(B, Self::Item<'a>) -> B,
{
let mut accum = init;
while let Some(x) = self.next() {
accum = f(accum, x);
}
accum
}
}
impl<T: LendingIterator> LendingIteratorExt for T {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let a = [0, 1, 2, 3, 4];
//a.iter().peekable_iter().for_each(|(a, b)| {
a.into_iter().peekable_iter().for_each(|(a, b)| {
if let Some(b) = b {
//assert_eq!(*a, *b - 1)
assert_eq!(a, *b - 1)
}
});
}
} Why does it works? Well, there are two main reasons:
|
Long story short, I was trying to make a functional programming compatible version of
Iterator::peekable
(code can be found also in my repo)First problem you can see is on the for_each implementation, copied from std. Here the problem seems to be the two different impl Trait using two different lifetimes for Self::Item<'_>.
Here I've tried several approaches, for example using an HRTB
Or adding a lifetime at method level, like
Both approaches end up asking for a 'static lifetime, as can be seen trying to run the test
I've searched for similar issues, like that but haven't found a solution so far
The text was updated successfully, but these errors were encountered: