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

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

Closed
cristicbz opened this issue Oct 13, 2016 · 1 comment · Fixed by #65192
Closed

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

cristicbz opened this issue Oct 13, 2016 · 1 comment · Fixed by #65192
Labels
A-type-system Area: Type system C-bug Category: This is a bug.

Comments

@cristicbz
Copy link
Contributor

cristicbz commented Oct 13, 2016

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.

@cristicbz
Copy link
Contributor Author

cristicbz commented Oct 13, 2016

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

@Mark-Simulacrum Mark-Simulacrum 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 May 14, 2017
@Mark-Simulacrum Mark-Simulacrum added the A-type-system Area: Type system label Jun 22, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-bug Category: This is a bug. label Jul 26, 2017
Centril added a commit to Centril/rust that referenced this issue Oct 19, 2019
…asper

Use structured suggestion for restricting bounds

When a trait bound is not met and restricting a type parameter would
make the restriction hold, use a structured suggestion pointing at an
appropriate place (type param in param list or `where` clause).

Account for opaque parameters where instead of suggesting extending
the `where` clause, we suggest appending the new restriction:
`fn foo(impl Trait + UnmetTrait)`. Fix rust-lang#64565, fix rust-lang#41817, fix rust-lang#24354,
cc rust-lang#26026, cc rust-lang#37808, cc rust-lang#24159, fix rust-lang#37138, fix rust-lang#24354, cc rust-lang#20671.
@bors bors closed this as completed in 7e4ff91 Oct 19, 2019
@fmease fmease added A-type-system Area: Type system and removed A-type-system Area: Type system labels Dec 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system C-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants