Open
Description
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:
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)