Skip to content

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

Closed
@cristicbz

Description

@cristicbz
Contributor

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.

Activity

cristicbz

cristicbz commented on Oct 13, 2016

@cristicbz
ContributorAuthor

Changing the QueryT constraint to a subtrait of ProxiedBy, we can fix bad by adding the superfluous OnT: ProxiedBy<OnT> constraint (playground):

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

// New subtrait:
pub trait ProxiedBySubtrait<T>: ProxiedBy<T> {}
impl<T> ProxiedBySubtrait<T> for T {}

pub trait SomeConstraint {}

struct Performer<OnT>(OnT);

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

fn good_again<OnT, IrrelevantT>(performer: Performer<OnT>, on: OnT)
        where OnT: SomeConstraint + ProxiedBy<IrrelevantT>,
              OnT: ProxiedBy<OnT>  // This constraint should be unnecessary!
{
    performer.perform(on);
}
changed the title [-]Inference failure when blanket impl would resolve constraint, but where clause takes priority[/-] [+]Constraint does not match because where clause hides blanket impl[/+] on May 14, 2017
added 2 commits that reference this issue on Oct 19, 2019

Rollup merge of rust-lang#65192 - estebank:restrict-bound, r=matthewj…

ef8ac78

Rollup merge of rust-lang#65192 - estebank:restrict-bound, r=matthewj…

7e4ff91
added and removed on Dec 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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

      Participants

      @cristicbz@Mark-Simulacrum@fmease

      Issue actions

        Constraint does not match because where clause hides blanket impl · Issue #37138 · rust-lang/rust