Skip to content

Compiler forgets about function-level where clause when a clause for an associated type is present #123173

Open
@sfackler

Description

I tried this code:

trait Foo {
    type Input;

    fn foo<T>(&self, task: T) -> T::Output
    where
        T: Task<Self::Input> + Send,
        T::Output: Send;
}

trait Task<T> {
    type Output;
    
    fn run(&self, t: &mut T) -> Self::Output;
}

struct FooImpl;

impl Foo for FooImpl {
    type Input = FooInput;

    fn foo<T>(&self, task: T) -> T::Output
    where
        T: Task<Self::Input> + Send,
        T::Output: Send,
    {
        task.run(&mut FooInput)
    }
}

struct FooInput;

I expected to see this happen: It should compile.

Instead, this happened:

error[E0277]: the trait bound `T: Task<FooInput>` is not satisfied
  --> src/lib.rs:21:5
   |
21 | /     fn foo<T>(&self, task: T) -> T::Output
22 | |     where
23 | |         T: Task<Self::Input> + Send,
24 | |         T::Output: Send,
   | |________________________^ the trait `Task<FooInput>` is not implemented for `T`
   |
help: consider further restricting this bound
   |
23 |         T: Task<Self::Input> + Send + Task<FooInput>,
   |                                     ++++++++++++++++

error[E0276]: impl has stricter requirements than trait
  --> src/lib.rs:23:12
   |
4  | /     fn foo<T>(&self, task: T) -> T::Output
5  | |     where
6  | |         T: Task<Self::Input> + Send,
7  | |         T::Output: Send;
   | |________________________- definition of `foo` from trait
...
23 |           T: Task<Self::Input> + Send,
   |              ^^^^^^^^^^^^^^^^^ impl has extra requirement `T: Task<FooInput>`

error[E0277]: the trait bound `T: Task<FooInput>` is not satisfied
  --> src/lib.rs:21:34
   |
21 |     fn foo<T>(&self, task: T) -> T::Output
   |                                  ^^^^^^^^^ the trait `Task<FooInput>` is not implemented for `T`
   |
help: consider further restricting this bound
   |
23 |         T: Task<Self::Input> + Send + Task<FooInput>,
   |                                     ++++++++++++++++

Some errors have detailed explanations: E0276, E0277.
For more information about an error, try `rustc --explain E0276`.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6c4ab41d94cd20eb5102402919325773

Removing the T::Output: Send clauses allows it to compile, as does switching Task's type parameter from Self::Input to a fixed type like ().

Meta

rustc --version --verbose:

rustc 1.77.0 (aedd173a2 2024-03-17)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    A-associated-itemsArea: Associated items (types, constants & functions)A-trait-systemArea: Trait systemC-bugCategory: This is a bug.T-typesRelevant to the types team, which will review and decide on the PR/issue.fixed-by-next-solverFixed by the next-generation trait solver, `-Znext-solver`.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions