Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using GATs with other associated types sometimes claims those types don't satisfy their supertraits #88405

Closed
kahomayo opened this issue Aug 27, 2021 · 2 comments · Fixed by #89918
Labels
A-GATs Area: Generic associated types (GATs) A-traits Area: Trait system C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. F-generic_associated_types `#![feature(generic_associated_types)]` a.k.a. GATs requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@kahomayo
Copy link

kahomayo commented Aug 27, 2021

Using an associated type as an argument to a GAT will sometimes fail with an incorrect [E0277] "trait bound is not satisfied" error, when that type is used to constrain an associated type of another trait.

#![feature(generic_associated_types)]

trait SomeTrait {}
trait OtherTrait { type Item; }

trait ErrorSimpleExample {
    type AssociatedType: SomeTrait;
    type GatBounded<T: SomeTrait>;
    type ErrorMinimal: OtherTrait<Item = Self::GatBounded<Self::AssociatedType>>;
}

Playground link including the other examples in this issue

This code should compile fine. In particular, Self::GatBounded<Self::AssociatedType> should be valid because Self::AssociatedType is constrained to implement SomeTrait.

However, the compilation fails with the following error:

error[E0277]: the trait bound `<Self as ErrorSimpleExample>::AssociatedType: SomeTrait` is not satisfied
 --> src/lib.rs:9:35
  |
9 |     type ErrorMinimal: OtherTrait<Item = Self::GatBounded<Self::AssociatedType>>;
  |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `SomeTrait` is not implemented for `<Self as ErrorSimpleExample>::AssociatedType`
  |
note: required by a bound in `ErrorSimpleExample::GatBounded`
 --> src/lib.rs:8:24
  |
8 |     type GatBounded<T: SomeTrait>;
  |                        ^^^^^^^^^ required by this bound in `ErrorSimpleExample::GatBounded`
help: consider further restricting the associated type
  |
6 | trait ErrorSimpleExample where <Self as ErrorSimpleExample>::AssociatedType: SomeTrait {
  |                          +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

For more information about this error, try `rustc --explain E0277`.

The trait bound Self::AssociatedType: SomeTrait is obviously satisfied, so something is wrong here. The suggested where clause does not fix the error, instead the compiler will suggest you add another one.

Adding the same bound again and again

#![feature(generic_associated_types)]

trait SomeTrait {}
trait OtherTrait {
    type Item;
}

trait ErrorSimpleExample
where
    <Self as ErrorSimpleExample>::AssociatedType: SomeTrait,
    <Self as ErrorSimpleExample>::AssociatedType: SomeTrait,
    <Self as ErrorSimpleExample>::AssociatedType: SomeTrait,
    <Self as ErrorSimpleExample>::AssociatedType: SomeTrait,
    <Self as ErrorSimpleExample>::AssociatedType: SomeTrait,
    <Self as ErrorSimpleExample>::AssociatedType: SomeTrait,
{
    type AssociatedType: SomeTrait;
    type GatBounded<T: SomeTrait>;
    type ErrorMinimal: OtherTrait<Item = Self::GatBounded<Self::AssociatedType>>;
}
help: consider further restricting the associated type
   |
15 |     <Self as ErrorSimpleExample>::AssociatedType: SomeTrait, <Self as ErrorSimpleExample>::AssociatedType: SomeTrait
   |    

Further observations

Spreading types over several traits causes the same issue

This error occurs even if the first two types, AssociatedType and GatBounded, are part of other traits (implemented either by Self or some generic type arguments).

trait ExampleSetup {
    type AssociatedTypeOfSomeTrait: SomeTrait;
    type GatBoundedOnSomeTrait<T: SomeTrait>;
}

trait ErrorUsingSupertrait: ExampleSetup {
    type ErrorSupertrait: OtherTrait<Item = Self::GatBoundedOnSomeTrait<Self::AssociatedTypeOfSomeTrait>>;
}

Error also happens in generic argument

trait ErrorInTraitArgument: ExampleSetup {
    type ErrorTraitArg: From<Self::GatBoundedOnSomeTrait<Self::AssociatedTypeOfSomeTrait>>;
}

Error affected by other items in trait

The error seems to be affected by the presence and ordering of other items in the trait. This code happily compiles:

trait OkInReturnBefore: ExampleSetup {
    fn ok_before_type() -> Self::GatBoundedOnSomeTrait<Self::AssociatedTypeOfSomeTrait>;
    type OkAfterFn: OtherTrait<Item = Self::GatBoundedOnSomeTrait<Self::AssociatedTypeOfSomeTrait>>;
}

But swapping the two items causes the above error:

trait ErrorInReturnAfter: ExampleSetup {
    type ErrorBeforeFn: OtherTrait<Item = Self::GatBoundedOnSomeTrait<Self::AssociatedTypeOfSomeTrait>>;
    fn error_after_type() -> Self::GatBoundedOnSomeTrait<Self::AssociatedTypeOfSomeTrait>;
}

Make sure to write each test in a separate trait to avoid other items messing with your testing. I initially thought the ErrorTraitArg example did not produce an error because I had put it into the same trait as other working examples.

Potentially related issue

I found another issue, #88287, that produces the same error message. However, I'm not sure if that is the same bug because I could not get Self::GatBounded<Self::AssociatedType> to error in only the return type position. That issue's example also uses the TAIT feature (which I'm unfamiliar with) so I was unable to reduce it enough to see similarities to my example.

Meta

rustc --version --verbose:

rustc 1.56.0-nightly (0afc20860 2021-08-25)
binary: rustc
commit-hash: 0afc20860eb98a29d9bbeea80f2acc5be38c6bf3
commit-date: 2021-08-25
host: x86_64-pc-windows-msvc
release: 1.56.0-nightly
LLVM version: 13.0.0

As well as rust playground 1.56.0-nightly (2021-08-25 0afc20860eb98a29d9bb)

@rustbot label +T-compiler +F-generic_associated_types +A-Traits +requires-nightly

@kahomayo kahomayo added the C-bug Category: This is a bug. label Aug 27, 2021
@rustbot rustbot added A-traits Area: Trait system F-generic_associated_types `#![feature(generic_associated_types)]` a.k.a. GATs requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 27, 2021
@kahomayo
Copy link
Author

I just re-ran the playground example and noticed that the issue seems to have vanished. The playground is running 1.56.0-nightly (2021-08-27 ac50a53359328a5d7f2f) and my local installation is this:

rustc 1.56.0-nightly (ac50a5335 2021-08-27)
binary: rustc
commit-hash: ac50a53359328a5d7f2f558833e63d59d372e4f7
commit-date: 2021-08-27
host: x86_64-pc-windows-msvc
release: 1.56.0-nightly
LLVM version: 13.0.0

I have no idea if this was an intentional fix or these issues just randomly vanished and the TAIT bug I linked still reproduces. I didn't find mentions of how to handle this case in any docs, so I will simply close this issue.

@cynecx
Copy link
Contributor

cynecx commented Aug 28, 2021

Isn't it worth keeping this issue open so we can add a proper test, so this bug doesn't regress?

@kahomayo kahomayo reopened this Aug 28, 2021
@jackh726 jackh726 added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Sep 13, 2021
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Oct 15, 2021
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Oct 15, 2021
jackh726 added a commit to jackh726/rust that referenced this issue Oct 16, 2021
@bors bors closed this as completed in 4fa5d6e Oct 16, 2021
@fmease fmease added the A-GATs Area: Generic associated types (GATs) label Nov 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-GATs Area: Generic associated types (GATs) A-traits Area: Trait system C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. F-generic_associated_types `#![feature(generic_associated_types)]` a.k.a. GATs requires-nightly This issue requires a nightly compiler in some way. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants