Inconsistent treatment of different kinds of trait bounds with GATs · Issue #87831 · rust-lang/rust (original) (raw)

I tried this code:

#![feature(generic_associated_types)]

trait Collection { type Iter<'a>: IntoIterator where <Self::Iter<'a> as IntoIterator>::Item: std::fmt::Debug; }

This fails to compile with:

   Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `<Self as Collection>::Iter<'a>: IntoIterator` is not satisfied
 --> src/lib.rs:4:5
  |
4 | /     type Iter<'a>: IntoIterator
5 | |     where
6 | |         <Self::Iter<'a> as IntoIterator>::Item: std::fmt::Debug;
  | |________________________________________________________________^ the trait `IntoIterator` is not implemented for `<Self as Collection>::Iter<'a>`
  |
help: consider further restricting the associated type
  |
3 | trait Collection where <Self as Collection>::Iter<'a>: IntoIterator {
  |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: the trait bound `<Self as Collection>::Iter<'a>: IntoIterator` is not satisfied
   --> src/lib.rs:4:20
    |
4   |       type Iter<'a>: IntoIterator
    |                      ^^^^^^^^^^^^ the trait `IntoIterator` is not implemented for `<Self as Collection>::Iter<'a>`
    |
help: consider further restricting the associated type
    |
3   | trait Collection where <Self as Collection>::Iter<'a>: IntoIterator {
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to 2 previous errors

Playground

aka/rrevenantt on Discord discovered the following workaround, which to me seems like it should be treated the same as above. The only difference is the location of the bound - one using "inheritance style", the other as part of a where clause:

#![feature(generic_associated_types)]

trait Collection { type Iter<'a> where Self::Iter<'a>: IntoIterator, <Self::Iter<'a> as IntoIterator>::Item: std::fmt::Debug; }

It's worth noting that the same issue exists without GATs. But where clauses on associated types are also feature gated under generic_associated_types.

This fails to compile:

#![feature(generic_associated_types)]

trait Collection { type Iter: IntoIterator where <Self::Iter as IntoIterator>::Item: std::fmt::Debug; }

However this works on stable (lifting the bound to the trait itself):

trait Collection where <Self::Iter as IntoIterator>::Item: std::fmt::Debug, { type Iter: IntoIterator; }