Skip to content

Diagnostics for trait methods with additional unmet bounds can be confusing to read #100433

Open
@semicoleon

Description

@semicoleon

A URLO thread about confusion over why Iterator's rev method didn't work for HashMap's iterators kicked off some discussion about the way the error message was phrased.

It has all of the information about the root cause of the error (a missing impl), as well as what caused that requirement to be introduced (calling rev). I think the ordering of the information is a little confusing though, especially for people new to the language.

Given the following code:

Playground

use std::collections::HashMap;

fn map() {
    let map = HashMap::<u32, u32>::new();

    for _ in map.iter().rev() {}
}

The current output is:

error[E0277]: the trait bound `std::collections::hash_map::Iter<'_, u32, u32>: DoubleEndedIterator` is not satisfied
    --> src/main.rs:6:25
     |
6    |     for _ in map.iter().rev() {}
     |                         ^^^ the trait `DoubleEndedIterator` is not implemented for `std::collections::hash_map::Iter<'_, u32, u32>`
     |
note: required by a bound in `rev`
    --> /<redacted>/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:3111:23
     |
3111 |         Self: Sized + DoubleEndedIterator,
     |                       ^^^^^^^^^^^^^^^^^^^ required by this bound in `rev`

error[E0277]: the trait bound `std::collections::hash_map::Iter<'_, u32, u32>: DoubleEndedIterator` is not satisfied
 --> src/main.rs:6:14
  |
6 |     for _ in map.iter().rev() {}
  |              ^^^^^^^^^^^^^^^^ the trait `DoubleEndedIterator` is not implemented for `std::collections::hash_map::Iter<'_, u32, u32>`
  |
  = note: required because of the requirements on the impl of `Iterator` for `Rev<std::collections::hash_map::Iter<'_, u32, u32>>`
  = note: required because of the requirements on the impl of `IntoIterator` for `Rev<std::collections::hash_map::Iter<'_, u32, u32>>`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `sample` due to 2 previous errors

I think it might be worth starting with a message about what the user did to cause the error rather than the root cause.

Mostly unrelated As I was writing this up I also noticed that the last error "required because of the requirements on the impl of `IntoIterator`" doesn't explain why `IntoIterator` is involved. It might be worth tacking on a note that for loops call into_iter automatically to clarify why that's there.

Ideally the output should look like:

error[?????]: The method `rev` has additional trait bounds that were not met
    --> src/main.rs:6:25
     |
6    |     for _ in map.iter().rev() {}
     |                         ^^^ the trait `DoubleEndedIterator` is not implemented for `std::collections::hash_map::Iter<'_, u32, u32>`
note: unmet bound in `rev`
    --> /<redacted>/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:3111:23
     |
3111 |         Self: Sized + DoubleEndedIterator,
     |                       ^^^^^^^^^^^^^^^^^^^ required by this bound in `rev`
... (existing diagnostic messages)

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