The sticking point is implementing Iterator::next() where
fn next(&mut self) -> Option<Self::Item>
&mut self lifetime clashes with lifetime of Self::Item which is &'a T.
I've tried introducing 'b but I don't know how/if it's possible to express that 'a outlives the &'b mut of the iterator instance when next() is called.
Context: I'm trying to avoid making copies of returned items since in my project, they're a bit heavy to construct and the plan behind the iterator is to use it in a busy loop and if possible, I'd like to avoid using Rc elements. Also, in my project I'm not using Default trait but I construct the "default" item manually and modify it in-place in (some of the) calls of next(), but that's another topic.
This is impossible in Iterator, because next is &'a self -> Option<Self::Item>, and there's no way to get that 'a into the item type.
You can look up "streaming iterators" or "lending iterators" for more about this problem.
If you've ever wondered why https://docs.rs/itertools/latest/itertools/trait.Itertools.html#method.chunk_by has the note about only being IntoIterator and not Iterator, it's because of this limitation. It needs to return an object, then the iterator for that object can return references into that object -- that way it's not trying to return references into the iterator itself.
The Iterator interface guarantees that it's always valid to use .collect():
let collection = iter.collect()
which allows all elements returned by the iterator to exist at the same time, and the collection to continue to exist after the iterator has been destroyed.
If you were allowed to return references to default_value: T, you'd end up with collections of dangling pointers.