-
Notifications
You must be signed in to change notification settings - Fork 13.5k
clippy fix: remove manual PartialEq::ne #143377
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Note that implementations for reference types are not strictly the same as the default because they are forwarding of the underlying implementation. In such cases, if the compiler cannot optimize the inversion of the result from the underlying implementation (e.g., inline assembly or FFI is used), then |
@taiki-e that is a good point, thanks! |
fe36c54
to
eac6335
Compare
This comment has been minimized.
This comment has been minimized.
eac6335
to
4489647
Compare
library/core/src/cmp.rs
Outdated
// if <A as PartialEq<B>>::ne uses inline assembly or FFI, then | ||
// this forwarding impl may be more efficient than the default impl | ||
#[allow(clippy::partialeq_ne_impl)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably allow
->expect
so we get a bit of noise if these change for some reason.
Maybe just make this a module-level attribute? Since it applies to all but one fn ne
in this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But at module level would it not also conflict with the few missing ne, at least as expect
?
I was thinking of removing duplication a bit with a macro here, since the four cases of (&mut, &mut)
, (&mut, &)
, (&, &mut)
, (&, &)
are (nearly?) identical. That would also collapse most of these annotations...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've now collapsed this with macros to just one PartialEq::ne
impl with an expect.
4489647
to
88f2556
Compare
I don't think we should add macros to appease the thing that is linting in an effort to make the code more readable. Adding macros is rather the opposite of making the code more readable. |
@workingjubilee macros like these are used all over the library for repeating impls just like here... Do you feel the same way about those, or can you explain why you think these are any different? |
If you look you will find that I have pushed people to reduce the usage of macros in other PRs, yes. |
Very well, I was just trying to clarify your point. Macros come with the disadvantage of more complicated code, but one advantage of using macros like this is that it is easier to see which code is identically duplicated and which parts contain differences. Opinions will vary on in which cases the upside outweighs the downside. My latest change introduced 3 macros:
|
I don't have any strong preferences here r? workingjubilee |
|
59bece7
to
3c1c6e9
Compare
☔ The latest upstream changes (presumably #143867) made this pull request unmergeable. Please resolve the merge conflicts. |
3c1c6e9
to
9c60f35
Compare
#[inline] | ||
fn ne(&self, other: &Self) -> bool { *self != *other } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Primitive ne
isn't equivalent to !(*self == *other)
. This difference goes straight to MIR and codegen:
rust/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
Lines 822 to 833 in 0fb279b
mir::BinOp::Ne | |
| mir::BinOp::Lt | |
| mir::BinOp::Gt | |
| mir::BinOp::Eq | |
| mir::BinOp::Le | |
| mir::BinOp::Ge => { | |
if is_float { | |
bx.fcmp(base::bin_op_to_fcmp_predicate(op), lhs, rhs) | |
} else { | |
bx.icmp(base::bin_op_to_icmp_predicate(op, is_signed), lhs, rhs) | |
} | |
} |
Yes it can be trivially optimized away but why emit additional IR when you can emit less?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting! I suppose that treatment may be necessary in case these are implemented by inline assembly or via FFI.
Yes it can be trivially optimized away but why emit additional IR when you can emit less?
The documentation in this very file says that:
/// The default implementation of `ne` provides this consistency and is almost
/// always sufficient. It should not be overridden without very good reason.
Is the performance impact of emitting slightly more IR really a very good reason? I would expect it is on the edge of immeasurable.
Removes manual impls of PartialEq::ne which are equivalent to the default.