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
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; }