Skip to content

Constraint does not match because where clause hides blanket impl #37138

Closed
@cristicbz

Description

@cristicbz

playground

Sorry about the title gore, but I don't really know how to describe this:

pub trait ProxiedBy<T> {}
impl<T> ProxiedBy<T> for T {}

pub trait SomeConstraint {}

struct Performer<OnT>(OnT);

impl<OnT> Performer<OnT> {
    fn perform<QueryT, ProxyT>(&self, query: QueryT)
        where QueryT: ProxiedBy<ProxyT>,
              OnT: ProxiedBy<ProxyT>,
              ProxyT: SomeConstraint {}
}

fn good<OnT, IrrelevantT>(performer: Performer<OnT>, on: OnT)
        where OnT: SomeConstraint
{
    performer.perform(on);
}

fn bad<OnT, IrrelevantT>(performer: Performer<OnT>, on: OnT)
        where OnT: SomeConstraint + ProxiedBy<IrrelevantT>
{
    performer.perform(on);
}

fn main() {}

Fails with (on both stable & nightliy):

error[E0277]: the trait bound `IrrelevantT: SomeConstraint` is not satisfied
  --> y.rs:17:15
   |
17 |     performer.perform(on);
   |               ^^^^^^^ trait `IrrelevantT: SomeConstraint` not satisfied
   |
   = help: consider adding a `where IrrelevantT: SomeConstraint` bound

error: aborting due to previous error

The ProxiedBy<IrrelevantT> constraint is the only difference between good and bad. But OnT: ProxiedBy<OnT> + HasConstraint, therefore ProxyT = OnT should still be a valid substitution.

Since IrrelevantT: !SomeConstraint (as rustc helpfully explains) there also should be no problem.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-type-systemArea: Type systemC-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions