-
-
Notifications
You must be signed in to change notification settings - Fork 14.6k
Description
Code
#[derive(Debug, Eq, PartialEq)]
struct OopsNoOrd(i32);
#[derive(Debug)]
struct Container {
inner: OopsNoOrd,
}
fn main() {
let mut list = vec![
Container { inner: OopsNoOrd(1) },
Container { inner: OopsNoOrd(10) },
Container { inner: OopsNoOrd(3) },
];
list.sort_by(|a, b| a.inner.cmp(&b.inner));
dbg!(&list);
}Current output
error[E0599]: `OopsNoOrd` is not an iterator
--> src/main.rs:16:33
|
2 | struct OopsNoOrd(i32);
| ----------------
| |
| method `cmp` not found for this struct
| doesn't satisfy `OopsNoOrd: Iterator`
...
16 | list.sort_by(|a, b| a.inner.cmp(&b.inner));
| ^^^ `OopsNoOrd` is not an iterator
|
= note: the following trait bounds were not satisfied:
`OopsNoOrd: Iterator`
which is required by `&mut OopsNoOrd: Iterator`
note: the trait `Iterator` must be implemented
--> /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/iter/traits/iterator.rs:74:1
= help: items from traits can only be used if the trait is implemented and in scope
= note: the following trait defines an item `cmp`, perhaps you need to implement it:
candidate #1: `Iterator`
Desired output
I would like the output to recommend implementing or deriving Ord to get cmp instead of saying "the trait Iterator must be implemented", as implementing Ord is much more likely to be what I'm trying to do (in my experience).
Rationale and extra context
I tried calling cmp on a custom type that I had forgotten to derive Ord on, and I was surprised to see the compiler tell me the problem was that I didn't implement Iterator (which also has a cmp method, but isn't the best/most likely trait to provide cmp in this case).
Other cases
Interestingly, if I call sort_by a vec of OopsNoOrds such that I'm calling cmp on &OopsNoOrd instead of OopsNoOrd, then the compiler says I need both Ord and Iterator. This code:
#[derive(Debug, Eq, PartialEq)]
struct OopsNoOrd(i32);
fn main() {
let mut list2 = vec![OopsNoOrd(1), OopsNoOrd(10), OopsNoOrd(3)];
list2.sort_by(|a, b| a.cmp(&b));
dbg!(list2);
}gives me:
error[[E0599]](https://doc.rust-lang.org/stable/error_codes/E0599.html): the method `cmp` exists for reference `&OopsNoOrd`, but its trait bounds were not satisfied
--> src/main.rs:6:28
|
2 | struct OopsNoOrd(i32);
| ----------------
| |
| doesn't satisfy `OopsNoOrd: Iterator`
| doesn't satisfy `OopsNoOrd: Ord`
...
6 | list2.sort_by(|a, b| a.cmp(&b));
| ^^^ method cannot be called on `&OopsNoOrd` due to unsatisfied trait bounds
|
= note: the following trait bounds were not satisfied:
`OopsNoOrd: Ord`
which is required by `&OopsNoOrd: Ord`
`&OopsNoOrd: Iterator`
which is required by `&mut &OopsNoOrd: Iterator`
`OopsNoOrd: Iterator`
which is required by `&mut OopsNoOrd: Iterator`
note: the trait `Iterator` must be implemented
--> /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/iter/traits/iterator.rs:74:1
help: consider annotating `OopsNoOrd` with `#[derive(Eq, Ord, PartialEq, PartialOrd)]`
|
2 + #[derive(Eq, Ord, PartialEq, PartialOrd)]
3 | struct OopsNoOrd(i32);
|
Anything else?
I'm using rustc 1.70.0, and I'm seeing the same compiler output with beta 1.71.0-beta.6 and nightly 2023-07-09 1065d87.