Code
playground
#[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.
Code
playground
Current output
Desired output
I would like the output to recommend implementing or deriving
Ordto getcmpinstead of saying "the traitIteratormust be implemented", as implementingOrdis much more likely to be what I'm trying to do (in my experience).Rationale and extra context
I tried calling
cmpon a custom type that I had forgotten to deriveOrdon, and I was surprised to see the compiler tell me the problem was that I didn't implementIterator(which also has acmpmethod, but isn't the best/most likely trait to providecmpin this case).Other cases
Interestingly, if I call
sort_bya vec ofOopsNoOrds such that I'm callingcmpon&OopsNoOrdinstead ofOopsNoOrd, then the compiler says I need bothOrdandIterator. This code:gives me:
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.