Repository: rust
Issue: Confusing diagnostic about nonexistent subtraction at generic function's call site
Labels: A-diagnostics,T-compiler

### Code

```Rust
fn main() {
    let value: f32 = 1337.;
    let noise = ping_pong(value);
}

fn ping_pong<T>(t: T) -> T
where
    f32: std::ops::Sub<T, Output = T>,
    f64: std::ops::Sub<T, Output = T>,
    T: std::ops::Mul<f64, Output = T>
        + std::ops::Sub<f64, Output = T>
        + std::cmp::PartialOrd<f64>
        + Into<f32>
        + Into<f64>,
{
    t - f64::trunc((t * 0.5).into()) * 2.;
    if t < 1. {
        t
    } else {
        2. - t
    }
}
```


### Current output

```Shell
Compiling playground v0.0.1 (/playground)
error[E0277]: cannot subtract `f32` from `f64`
 --> src/main.rs:3:27
  |
3 |     let noise = ping_pong(value);
  |                 --------- ^^^^^ no implementation for `f64 - f32`
  |                 |
  |                 required by a bound introduced by this call
  |
  = help: the trait `Sub<f32>` is not implemented for `f64`
  = help: the following other types implement trait `Sub<Rhs>`:
            <f64 as Sub>
            <f64 as Sub<&f64>>
            <&'a f64 as Sub<f64>>
            <&f64 as Sub<&f64>>
note: required by a bound in `ping_pong`
 --> src/main.rs:9:10
  |
6 | fn ping_pong<T>(t: T) -> T
  |    --------- required by a bound in this function
...
9 |     f64: std::ops::Sub<T, Output = T>,
  |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ping_pong`

error[E0277]: cannot multiply `f32` by `f64`
  --> src/main.rs:3:27
   |
3  |     let noise = ping_pong(value);
   |                 --------- ^^^^^ no implementation for `f32 * f64`
   |                 |
   |                 required by a bound introduced by this call
   |
   = help: the trait `Mul<f64>` is not implemented for `f32`
   = help: the following other types implement trait `Mul<Rhs>`:
             <f32 as Mul>
             <f32 as Mul<&f32>>
             <&'a f32 as Mul<f32>>
             <&f32 as Mul<&f32>>
note: required by a bound in `ping_pong`
  --> src/main.rs:10:8
   |
6  | fn ping_pong<T>(t: T) -> T
   |    --------- required by a bound in this function
...
10 |     T: std::ops::Mul<f64, Output = T>
   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ping_pong`

error[E0277]: cannot subtract `f64` from `f32`
  --> src/main.rs:3:27
   |
3  |     let noise = ping_pong(value);
   |                 --------- ^^^^^ no implementation for `f32 - f64`
   |                 |
   |                 required by a bound introduced by this call
   |
   = help: the trait `Sub<f64>` is not implemented for `f32`
   = help: the following other types implement trait `Sub<Rhs>`:
             <f32 as Sub>
             <f32 as Sub<&f32>>
             <&'a f32 as Sub<f32>>
             <&f32 as Sub<&f32>>
note: required by a bound in `ping_pong`
  --> src/main.rs:11:11
   |
6  | fn ping_pong<T>(t: T) -> T
   |    --------- required by a bound in this function
...
11 |         + std::ops::Sub<f64, Output = T>
   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ping_pong`

error[E0277]: can't compare `f32` with `f64`
  --> src/main.rs:3:27
   |
3  |     let noise = ping_pong(value);
   |                 --------- ^^^^^ no implementation for `f32 < f64` and `f32 > f64`
   |                 |
   |                 required by a bound introduced by this call
   |
   = help: the trait `PartialOrd<f64>` is not implemented for `f32`
   = help: the trait `PartialOrd` is implemented for `f32`
note: required by a bound in `ping_pong`
  --> src/main.rs:12:11
   |
6  | fn ping_pong<T>(t: T) -> T
   |    --------- required by a bound in this function
...
12 |         + std::cmp::PartialOrd<f64>
   |           ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ping_pong`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` (bin "playground") due to 4 previous errors
```


### Desired output

_No response_

### Rationale and extra context

The output shouldn't point to the call site and say that `f64 - f32` subtraction isn't valid because there is obviously no subtraction going on at the call site.

### Other cases

_No response_

### Anything else?

Note that I haven't actually been able to solve this problem since it's too confusing. It's also possible that this could be simplified further but I'm not sure how, although it's already pretty simple.

Here is the playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=dabecf1218004a90104d8136d893fe44