Skip to content

"the following other types implement trait" needs improvement. #103822

Open
@mejrs

Description

@mejrs

tl;dr: this help message is pretty bad, and needs work. See some prior discussion at #102752

Let me begin with some examples:

Examples

Showing completely unrelated impls

pub fn foo() -> Result<u8, u8> {
    let i = 42_i32;
    Ok(i).into()
}
error[E0277]: the trait bound `Result<u8, u8>: From<Result<i32, _>>` is not satisfied
 --> src/main.rs:4:5
  |
4 |     Ok(i).into()
  |     ^^^^^ ---- required by a bound introduced by this call
  |     |
  |     the trait `From<Result<i32, _>>` is not implemented for `Result<u8, u8>`
  |
  = help: the following other types implement trait `From<T>`:
            <Result<miniz_oxide::MZStatus, miniz_oxide::MZError> as From<&miniz_oxide::StreamResult>>
            <Result<miniz_oxide::MZStatus, miniz_oxide::MZError> as From<miniz_oxide::StreamResult>>
  = note: required for `Result<i32, _>` to implement `Into<Result<u8, u8>>`

For more information about this error, try `rustc --explain E0277`.

Showing hundreds of impls

42_u8 >> "blah"
error[E0277]: no implementation for `u8 >> &str`
 --> src/main.rs:2:7
  |
2 | 42_u8 >> "blah"
  |       ^^ no implementation for `u8 >> &str`
  |
  = help: the trait `Shr<&str>` is not implemented for `u8`
  = help: the following other types implement trait `Shr<Rhs>`:
            <&'a i128 as Shr<i128>>
            <&'a i128 as Shr<i16>>
            <&'a i128 as Shr<i32>>
            <&'a i128 as Shr<i64>>
            <&'a i128 as Shr<i8>>
            <&'a i128 as Shr<isize>>
            <&'a i128 as Shr<u128>>
            <&'a i128 as Shr<u16>>
          and 568 others

For more information about this error, try `rustc --explain E0277`.

Cryptic bounds and types

fn a() -> Result<i32, ()> {
    Err(5)?
}
error[E0277]: `?` couldn't convert the error to `()`
 --> src/lib.rs:2:11
  |
1 | fn a() -> Result<i32, ()> {
  |           --------------- expected `()` because of this
2 |     Err(5)?
  |           ^ the trait `From<{integer}>` is not implemented for `()`
  |
  = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait
  = help: the following other types implement trait `FromResidual<R>`:
            <Result<T, F> as FromResidual<Result<Infallible, E>>>
            <Result<T, F> as FromResidual<Yeet<E>>>
  = note: required for `Result<i32, ()>` to implement `FromResidual<Result<Infallible, {integer}>>`

For more information about this error, try `rustc --explain E0277`.

Discussion

Now, lets look at what these "help" messages tend to have in common:

  • they take up a lot of space (especially the second example) and look pretty noisy.
  • they require significant effort to parse. To get to "does this look like what I need?" you have to read the message, understand what the mentioned types are and how it might fit in your code. All these things are much harder if you're not familiar with Rust.
  • they're more often than not completely useless
  • if they're useless, you have to mentally discard all this information you've just loaded.
  • because they're usually useless, they introduce fatigue. I don't even look at these anymore, unless I can see at a glance that they're simple like in the case of
   = help: the following other types implement trait `Pattern<'a>`:
             &'b String
             &'b [char; N]
             &'b [char]
             &'b str
             &'c &'b str
             [char; N]
             char

but these cases are fairly rare.

Discussion

Do you agree this is a problem, and what can we do about it?

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-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