rust-lang / rust-clippy

A bunch of lints to catch common mistakes and improve your Rust code. Book: https://doc.rust-lang.org/clippy/
https://rust-lang.github.io/rust-clippy/
Other
11.07k stars 1.49k forks source link

False alarm with derive_ord_xor_partial_ord #6219

Open kangalio opened 3 years ago

kangalio commented 3 years ago

In my application, I have a struct wrapping a f32, but guaranteeing non-NaN values. Therefore, this struct can have an Ord implementation.

I've implemented this using:

#[derive(PartialOrd)]
struct MyWrapper {
    inner: f32,
}

impl Ord for MyWrapper {
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        self.partial_cmp(other).expect("Can't happen; this wrapper guarantees non-NaN")
    }
}

This triggers a deny-by-default warning, telling me that I'm making my Ord and PartialOrd implementation not match (link). However, as you can see, this is not the case here.

This false alarm was easily fixed with #[allow(clippy::derive_ord_xor_partial_ord)], however it may be good to

giraffate commented 3 years ago

Repro: playground

@rustbot modify labels: +L-bug

wfraser commented 2 years ago

Seems incredibly low risk if one of the operations is implemented in terms of the other.

Looking at the list of crates that have ignored this lint, that reasoning covers most of them. Several of them are also non-NaN float wrappers as well.

https://dtolnay.github.io/noisy-clippy/derive_ord_xor_partial_ord.html#local

In fact, I would argue the chances of getting it wrong are higher if someone manually implements both operations. That is what should be linted against: if you have explicit impls of both and one is not implemented in terms of the other.