rust-clippy
rust-clippy copied to clipboard
derive_partial_eq_without_eq should acknowledge the constraint it adds
Summary
The derive_partial_eq_without_eq lint and its documentation recommends deriving Eq whenever PartialEq is implemented on a public type. However, doing so may constrain the evolution of a library: adding derive(Eq) prevents later adding a private field, or public field or variant in a non_exhaustive enum or struct, which contains an !Eq type such as f64.
Notably, Clippy reported this lint on my library's non-exhaustive error enums — types that are more likely than most to gain new variants with new kinds of data.
At a minimum, the lint documentation should acknowledge that adding Eq constrains future choices.
Lint Name
derive_partial_eq_without_eq
Reproducer
I tried this code:
#[derive(Clone, Debug, PartialEq)]
pub struct Value {
x: bool,
// y: f64, // adding this line would not be a breaking change, but it conflicts with `derive(Eq)`
}
I saw this happen:
warning: you are deriving `PartialEq` and can implement `Eq`
--> src/lib.rs:1:24
|
1 | #[derive(Clone, Debug, PartialEq)]
| ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
|
= note: `#[warn(clippy::derive_partial_eq_without_eq)]` on by default
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
Version
Tested with clippy 0.1.63 (2022-06-27 2f3ddd9) on Rust Playground
(The original detection was with `rustc 1.64.0-nightly (c80c4b8fd 2022-06-26)` — sorry, neither my CI nor the Playground provides `rustc -Vv` output)
Additional Labels
No response
I do not think that the benefit of having people consider also implementing Eq outweighs everyone making deliberate design choices around their public API having to disable this linting rule.
At the very least, it should not suggest adding Eq for public types.
I came here after hearing criticism over this lint. I have to agree that it feels like a mistake having it as warn by default. It introduces unnecessary noise to packages choosing to be more conservative about what impls to expose.
Part of me suspects that the C-COMMON-TRAITS had some influence on how it was raised, considering that it advocates for making types implement as many traits as it can. The real design decision criterion is not that clear-cut, but more of a balance between early interoperability and API stability.
I was just surprised by this. I don't derive any traits I don't strictly need, so I can keep track of the changes that force each derive, and also to always have the fastest possible compiling experience, even the slightest increases adds up. PS.: They're private types so I can easily change derives when/if needed.
So what's the best proposed solution for derive_partial_eq_without_eq lint would be?
- Move this lint to
pedantic? The lint is currently in thenursery, so this seems to already be the case? - Expand documentation to explain that doing so would prevent future changes to the
struct- i.e. inability to add non-Eq-capable private fields (this is not exactly true because someone could implementEqby hand, but it won't be perfectlyEq) - something else?
- no action needed, can close the issue?
@nyurik As I wrote when I filed this issue:
At a minimum, the lint documentation should acknowledge that adding
Eqconstrains future choices.
I have no strong opinion on the other elements given that it is now not warn-by-default.
I opened https://github.com/rust-lang/rust-clippy/pull/12153 which should mitigate this issue a bit by non emitting the lint on non-exhaustive types.