Is a bound on an associated type really an equality?

I know that you can give a concrete type to an associated type of a type parameter like I: Iterator<Item=J::Item>. I think this is meant to be an equality, as it is represented with ProjectionPredicate, which also deals with I::Item == J::Item. An equivalence relation is always symmetric, so i tried to swap it, but encountered an error with HRTB:

trait T {    
    fn works<I>(&mut self, _i: I)
    where
        I: Iterator,
        for<'imm> &'imm Self: Iterator<Item = I::Item>
    {}
    
    fn doesnt_work<I>(&mut self, _i: I)
    where
        for<'imm> I: Iterator<Item = <&'imm Self as Iterator>::Item>,
        for<'imm> &'imm Self: Iterator
    {}
}

The second example produces a compiler error: error[E0582]: binding for associated type `Item` references lifetime `'imm`, which does not appear in the trait input types.

My question is: Is it supposed to be an equivalence, and if so, what is the syntax to invert it?

Yes, it is an equality. The problem is that <&'a Self as Iterator>::Item and <&'b Self as Iterator>::Item might not be the same type when the lifetimes 'a and 'b are different, but you are treating it as-if it is a single type.

(If both types exist, then there isn't any way for them to be different on stable Rust, but the trait checker doesn't care about this.)

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.