Implement Iterator for Item with lifetimes

I'm bit struggling with implementation of Iterator for Item associated type, which has lifetimes.
I extracted the core of the problem into this code:

use std::iter::Iterator;

#[derive(Clone, Copy)]
struct NodeRef<'a> {
    data: &'a String
    //there is more 
}

pub struct TreePath<'a, 'b> {
    parents: &'b[&'a String],
    leaf: &'a String
}

struct DirTreeIterator<'a> {
    current_path: Vec<&'a String>,
    current_node: NodeRef<'a>
} 

impl <'a>  DirTreeIterator<'a> 
    
 {
    
    fn get_next<'b>(&'b mut self) -> Option<TreePath<'a, 'b>> {
        // there is more
        Some(
            TreePath {
                leaf: self.current_node.data,
                parents: &self.current_path
            }
        )
    }

}

impl <'a, 'b>  Iterator for DirTreeIterator<'a> 
where Self: 'b
 {
    type Item = TreePath<'a, 'b>;

    fn next(&'b mut self) -> Option<TreePath<'a, 'b>> {
        Some(
            TreePath {
                leaf: self.current_node.data,
                parents: &self.current_path
            }
        )
    }
}

What I want to achieve is show in get_next method. However I cannot use similar approach, when implementing Iterator - I cannot add lifetime param to next method, as it would not match trait signature .
If I add another lifetime to impl I get unbound lifetime error.
Is there any possibility how to make it work?
Or the only possibility for Iterator is that it can use only it's own lifetime and nothing else?
What are generally possibilities to use lifetimes in associated types?
Thanks

1 Like

This is the motivation for RFC 1598 - generic associated types.

I don't know if Iterator can ever use that without a breaking change though. In the meantime, you might like StreamingIterator instead.

2 Likes

Obligatory link to Solving the Generalized Streaming Iterator Problem without GATs · Lukasʼ Blog, which does a great job exploring the current situation (ie without GATs).

3 Likes