JDemler
JDemler

Reputation: 1316

Check for equal Associated Types in where clause

Consider these two traits:

trait Iterator {
   type Item;

   fn next(&mut self) -> Option<Self::Item>;
}

and

trait SeeekingIterator {
    type Item;

    fn next(&mut self, other: &Self::Item) -> Option<Self::Item>;
}

Now assume, I wanted to implement something like std::iter::Peekable for structs that implement both Iterator and SeekingIterator.

This would look a bit like:

struct PeekableSeekable<I>  where
    I: Iterator + SeekingIterator
{
    iter: I,
    peeked: Option<<I as Iterator>::Item>        
}

It would implement

fn peek(&mut self) -> Option<&<I as Iterator>::Item>;

and

fn peek_seek(&mut self, other: &<I as SeekingIterator>::Item) -> Option<&<I as SeekingIterator>::Item>   

The problem now is, that this would only work if <I as Iterator>::Item == <I as SeekingIterator>::Item.

I don't know of a way to express this inside a where clause. I'm faking it by using

Option<<I as Iterator>::Item>: From<Option<<I as SeekingIterator>::Item>>

and

Option<<I as SeekingIterator>::Item>: From<Option<<I as Iterator>::Item>>

And then calling Option::from when a transformation is needed. This seems a bit ugly and I am wondering if this problem could be solved more concisely.

Upvotes: 2

Views: 936

Answers (1)

Shepmaster
Shepmaster

Reputation: 432139

Reference one trait from the other trait constraint:

struct PeekableSeekable<I>
    where I: Iterator
{
    iter: I,
    peeked: Option<I::Item>,
}

impl<I> PeekableSeekable<I>
    where I: Iterator<Item = <I as SeekingIterator>::Item> + SeekingIterator
{
    // Implement
}

Upvotes: 6

Related Questions