Skip to content

Inconsistent treatment of different kinds of trait bounds with GATs #87831

Open
@udoprog

Description

@udoprog

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-GATsArea: Generic associated types (GATs)GATs-triagedIssues using the `generic_associated_types` feature that have been triagedT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions