I'm trying to add functions to Iterator
where the associated type Item
is a reference to a struct with an explicit lifetime.
When I've wanted to modify the iterator state or return a new value I've had no problems, but when I attempt to return a new Iterator
where Item
is a reference with an explicit lifetime, the compiler complains.
Example
use std::marker::PhantomData;
/// First, an "Inner" struct to be contained in my custom iterator
pub struct Inner {
text: String,
}
/// Then, the "CustomIterator" in question. Notice that `Item` is `&'a Inner`.
pub struct CustomIterator<'a, I: Iterator<Item = &'a Inner>> {
iter: I,
_marker: PhantomData<&'a i8>,
}
/// Implementing Iterator for CustomIterator so as to define the `next()` function, as you do...
impl<'a, I: Iterator<Item = &'a Inner>> Iterator for CustomIterator<'a, I> {
type Item = &'a Inner;
fn next(&mut self) -> Option<Self::Item> {
println!("Custom next called");
self.iter.next()
}
}
/// Now, creating a custom trait definition called IterateMore that:
/// 1. inherits Iterator
/// 2. includes a default method called `more` which returns a `CustomIterator`
pub trait IterateMore<'a>: Iterator {
type Item;
fn more(self) -> CustomIterator<'a, Self>
where
Self: Sized;
}
/// Implementing `IterateMore` for an iterator of the specific type `Iterator<Item=&'a Inner>`
impl<'a, I: Iterator<Item = &'a Inner>> IterateMore<'a> for I
where
I: Iterator,
{
type Item = &'a Inner;
fn more(self) -> CustomIterator<'a, Self>
where
Self: Sized,
{
CustomIterator {
iter: self,
_marker: PhantomData,
}
}
}
fn main() {
let inner = Inner {
text: "Hello world".to_string(),
};
let inners = vec![&inner];
inners.iter().more().next();
}
(See it on repl.it)
Error
error[E0271]: type mismatch resolving `<Self as std::iter::Iterator>::Item == &'a Inner`
--> src/main.rs:28:5
|
28 | / fn more(self) -> CustomIterator<'a, Self>
29 | | where
30 | | Self: Sized;
| |____________________^ expected associated type, found reference
|
= note: expected type `<Self as std::iter::Iterator>::Item`
found type `&'a Inner`
= note: required by `CustomIterator`
Why is Item
not being resolved here? It is a bit frustrating as the compiler also complains if I try to set &'a Inner
as the default Item
type in the trait definition, saying:
error: associated type defaults are unstable (see issue #29661)
How could this be fixed or done differently?