Repository: rust
Issue: Blanket, recursive impls cause bad compiler suggestions
Labels: A-diagnostics,T-compiler

### Code

```Rust
use std::cmp::PartialEq;

#[derive(Debug)]
enum MyOption<T> {
    Some(T),
    None,
}

impl<T, U: PartialEq<T>> PartialEq<Option<T>> for MyOption<U> {
    fn eq(&self, other: &Option<T>) -> bool {
        match (self, other) {
            (MyOption::Some(a), Some(b)) => a == b,
            (MyOption::None, None) => true,
            _ => false
        }
    }
}

// This impl causes a worse error message. Comment out the impl to see the ideal one
impl<T: PartialEq<U>, U> PartialEq<MyOption<T>> for Option<U> {
    #[inline]
    fn eq(&self, other: &MyOption<T>) -> bool {
        other.eq(self)
    }
}

#[derive(Debug)]
struct S;

fn main() {
    // Want: note: an implementation of `PartialEq` might be missing for `S`
    // Actual:    = note: expected enum `MyOption<_>`
    //                  found enum `Option<S>`
    assert_eq!(Some(S), Some(S));
}
```


### Current output

```Shell
error[E0308]: mismatched types
  --> src/main.rs:34:25
   |
34 |     assert_eq!(Some(S), Some(S));
   |                         ^^^^^^^ expected `MyOption<_>`, found `Option<S>`
   |
   = note: expected enum `MyOption<_>`
              found enum `Option<S>`
help: try wrapping the expression in `MyOption::Some`
   |
34 |     assert_eq!(Some(S), MyOption::Some(Some(S)));
   |                         +++++++++++++++       +
```


### Desired output

```Shell
error[E0369]: binary operation `==` cannot be applied to type `Option<S>`
  --> src/main.rs:34:5
   |
34 |     assert_eq!(Some(S), Some(S));
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |     |
   |     Option<S>
   |     Option<S>
   |
note: an implementation of `PartialEq` might be missing for `S`
  --> src/main.rs:28:1
   |
28 | struct S;
   | ^^^^^^^^ must implement `PartialEq`
   = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider annotating `S` with `#[derive(PartialEq)]`
   |
28 + #[derive(PartialEq)]
29 | struct S;
   |
```


### Rationale and extra context

The actual issue in the code is that S does not implement PartialEq, and ideally the error message would tell me to implement PartialEq for S. rustc looks for an implementation of PartialEq on Option\<S\> and due to the blanket impls for comparing Option and MyOption, it thinks that wrapping in MyOption will resolve it (it won't) and suggests to use MyOption, even though the type MyOption is not used at all on the relevant line.

The MyOption type in the repro is inspired by rkyv::option::ArchivedOption which has this issue in the real world. I have helped several beginners with this exact compile error due to ArchivedOption

### Other cases

_No response_

### Rust Version

```Shell
% rustc --version --verbose
rustc 1.81.0-nightly (cf2df68d1 2024-07-01)
binary: rustc
commit-hash: cf2df68d1f5e56803c97d91e2b1a9f1c9923c533
commit-date: 2024-07-01
host: x86_64-apple-darwin
release: 1.81.0-nightly
LLVM version: 18.1.7
```


### Anything else?

Playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7a349cc3cb9f841f52b4f07e58501226