Repository: rust
Issue: Poor diagnostics for associated type mismatch on inherent method.
Labels: C-enhancement,A-diagnostics,T-compiler

Given the following code ([playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ecde3a7b167daae7d50bc0e6b9087b8c)):

```rust
// These are simplifications of the tower traits by the same name:

pub trait Service<Request> {
    type Response;
}

pub trait Layer<C> {
    type Service;
}

// Any type will do here:

pub struct Req;
pub struct Res;

// This is encoding a trait alias.

pub trait ParticularService:
    Service<Req, Response = Res> {
}

impl<T> ParticularService for T
where
    T: Service<Req, Response = Res>,
{
}

// This is also a trait alias.
// The weird = <Self as ...> bound is there so that users of the trait do not
// need to repeat the bounds. See https://github.com/rust-lang/rust/issues/20671
// for context, and in particular the workaround in:
// https://github.com/rust-lang/rust/issues/20671#issuecomment-529752828

pub trait ParticularServiceLayer<C>: Layer<C, Service = <Self as ParticularServiceLayer<C>>::Service> {
    type Service: ParticularService;
}

impl<T, C> ParticularServiceLayer<C> for T
where
    T: Layer<C>,
    T::Service: ParticularService,
{
    type Service = T::Service;
}

// These are types that implement the traits that the trait aliases refer to.
// They should also implement the alias traits due to the blanket impls.

struct ALayer<C>(C);
impl<C> Layer<C> for ALayer<C> {
    type Service = AService;
}

struct AService;
impl Service<Req> for AService {
    // However, AService does _not_ meet the blanket implementation,
    // since its Response type is bool, not Res as it should be.
    type Response = bool;
}

// This is a wrapper type around ALayer that uses the trait alias
// as a way to communicate the requirements of the provided types.
struct Client<C>(C);

// The method and the free-standing function below both have the same bounds.

impl<C> Client<C>
where
    ALayer<C>: ParticularServiceLayer<C>,
{
    fn check(&self) {}
}

fn check<C>(_: C) where ALayer<C>: ParticularServiceLayer<C> {}

// But, they give very different error messages.

#[allow(dead_code)]
fn test() {
    // This gives a very poor error message that does nothing to point the user
    // at the underlying cause of why the types involved do not meet the bounds.
    Client(()).check();
    
    // This gives a good(ish) error message that points the user at _why_ the
    // bound isn't met, and thus how they might fix it.
    check(());
}
```

The current output (for the indicated bad case) is:

```
error[E0599]: the method `check` exists for struct `Client<()>`, but its trait bounds were not satisfied
  --> src/lib.rs:82:16
   |
49 | struct ALayer<C>(C);
   | -------------------- doesn't satisfy `ALayer<()>: ParticularServiceLayer<()>`
...
63 | struct Client<C>(C);
   | -------------------- method `check` not found for this
...
82 |     Client(()).check();
   |                ^^^^^ method cannot be called on `Client<()>` due to unsatisfied trait bounds
   |
   = note: the following trait bounds were not satisfied:
           `ALayer<()>: ParticularServiceLayer<()>`
```

Ideally the output should look like (the current nightly output for the indicated good case):

```
error[E0271]: type mismatch resolving `<AService as Service<Req>>::Response == Res`
  --> src/lib.rs:82:5
   |
69 |     ALayer<C>: ParticularServiceLayer<C>,
   |     ------------------------------------ required by this bound in `impl<C> Client<C>`
...
82 |     Client(()).check();
   |                ^^^^^^^ expected struct `Res`, found `bool`
   |
note: required because of the requirements on the impl of `ParticularService` for `AService`
  --> src/lib.rs:22:9
   |
22 | impl<T> ParticularService for T
   |         ^^^^^^^^^^^^^^^^^     ^
note: required because of the requirements on the impl of `ParticularServiceLayer<_>` for `ALayer<_>`
  --> src/lib.rs:38:12
   |
38 | impl<T, C> ParticularServiceLayer<C> for T
   |            ^^^^^^^^^^^^^^^^^^^^^^^^^     ^
```

Actually pointing at the associated type and where the requirement that it be `Res` comes from would also be helpful to make it perfect.