Skip to content

Other missing bounds required to meet a trait's blanket impl are displayed too prominently #118779

Closed
@drmason13

Description

@drmason13

Code

pub trait Add {
    fn add(&self, left: usize, right: usize) -> usize;
}

impl<F> Add for F
where
    F: Fn(usize, usize) -> usize,
{
    fn add(&self, left: usize, right: usize) -> usize {
        self(left, right)
    }
}

pub struct NotAdd;

pub fn needs_add<A: Add>(add: &A) -> usize {
    add.add(1, 2)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        assert_eq!(needs_add(&NotAdd), 3);
    }
}

Current output

error[E0277]: expected a `Fn<(usize, usize)>` closure, found `NotAdd`
  --> src/lib.rs:26:30
   |
26 |         assert_eq!(needs_add(&NotAdd), 3);
   |                    --------- ^^^^^^^ expected an `Fn<(usize, usize)>` closure, found `NotAdd`
   |                    |
   |                    required by a bound introduced by this call
   |
   = help: the trait `Fn<(usize, usize)>` is not implemented for `NotAdd`
note: required for `NotAdd` to implement `Add`
  --> src/lib.rs:5:9
   |
5  | impl<F> Add for F
   |         ^^^     ^
6  | where
7  |     F: Fn(usize, usize) -> usize,
   |        ------------------------- unsatisfied trait bound introduced here
note: required by a bound in `needs_add`
  --> src/lib.rs:16:21
   |
16 | pub fn needs_add<A: Add>(add: &A) -> usize {
   |                     ^^^ required by this bound in `needs_add`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `fn-trait-error-test` (lib test) due to previous error

Desired output

error[E0277]: `NotAdd` doesn't implement `Add`
  --> src/lib.rs:26:30
   |
26 |         assert_eq!(needs_add(&NotAdd), 3);
   |                    --------- ^^^^^^^ `NotAdd` doesn't implement `Add`
   |                    |
   |                    required by a bound introduced by this call
   |
   = help: the trait `Fn<(usize, usize)>` is not implemented for `NotAdd`
note: required for `NotAdd` to implement `Add`
  --> src/lib.rs:5:9
   |
5  | impl<F> Add for F
   |         ^^^     ^
6  | where
7  |     F: Fn(usize, usize) -> usize,
   |        ------------------------- unsatisfied trait bound introduced here
note: required by a bound in `needs_add`
  --> src/lib.rs:16:21
   |
16 | pub fn needs_add<A: Add>(add: &A) -> usize {
   |                     ^^^ required by this bound in `needs_add`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `fn-trait-error-test` (lib test) due to previous error

Rationale and extra context

The first thing the error should make extremely obvious is the Trait that is required.

Then the existing (very useful and clever!) other bounds required to satisfy a blanket impl should be noted.

The fact that a type is implemented by a Blanket impl is often not in the forefront of a user's mind when they encounter this kind of error. They first need to realise that the type they probably think ought to impl a trait, definitely does not in fact impl that trait.

This becomes more important the more traits and types implementing those traits there are in scope, and the more bounds that might not be met.

Other cases

No response

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-trait-systemArea: Trait systemD-confusingDiagnostics: Confusing error or lint that should be reworked.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions