Skip to content
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

incorrect_partial_ord_impl_on_ord_type false positive: Some(Ord::cmp(self, other)) #11178

Closed
dtolnay opened this issue Jul 18, 2023 · 5 comments · Fixed by #11188
Closed

incorrect_partial_ord_impl_on_ord_type false positive: Some(Ord::cmp(self, other)) #11178

dtolnay opened this issue Jul 18, 2023 · 5 comments · Fixed by #11188
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied

Comments

@dtolnay
Copy link
Member

dtolnay commented Jul 18, 2023

Summary

Clippy flags the following as an incorrect PartialOrd impl, with a deny-by-default correctness lint:

impl PartialOrd for T {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(Ord::cmp(self, other))
    }
}

in favor of preferring:

impl PartialOrd for T {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

But there is no correctness difference between these impl, only a stylistic difference.

Lint Name

incorrect_partial_ord_impl_on_ord_type

Reproducer

use std::cmp::Ordering;

pub struct Struct(String);

impl Struct {
    pub fn cmp(&self) {
        println!("Struct::cmp!");
    }
}

impl Eq for Struct {}

impl PartialEq for Struct {
    fn eq(&self, other: &Self) -> bool {
        PartialEq::eq(&self.0, &other.0)
    }
}

impl Ord for Struct {
    fn cmp(&self, other: &Self) -> Ordering {
        Ord::cmp(&self.0, &other.0)
    }
}

impl PartialOrd for Struct {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(Ord::cmp(self, other))
    }
}
error: incorrect implementation of `partial_cmp` on an `Ord` type
  --> src/main.rs:25:1
   |
25 | /  impl PartialOrd for Struct {
26 | |      fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
   | | _____________________________________________________________-
27 | ||         Some(Ord::cmp(self, other))
28 | ||     }
   | ||_____- help: change this to: `{ Some(self.cmp(other)) }`
29 | |  }
   | |__^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#incorrect_partial_ord_impl_on_ord_type
   = note: `#[deny(clippy::incorrect_partial_ord_impl_on_ord_type)]` on by default

I consider this a false positive for this lint. If there is a compelling stylistic argument in favor of self.cmp(other) over Ord::cmp(self, other), that should be at most a warn-by-default style lint, not a deny-by-default correctness lint.

I think neither Some(Ord::cmp(self, other)) nor Some(T::cmp(self, other)) should trigger a lint.

Currently on GitHub, there are 1.6k search results for "::cmp(self" and 26k search results for "self.cmp(". Clearly there is a preference for self.cmp(other) but that is still a significant proportion of users who prefer to write the other, especially in macro-generated code where self.cmp(other) might not compile (as is the case above).

error[E0061]: this method takes 0 arguments but 1 argument was supplied
  --> src/main.rs:27:19
   |
27 |         Some(self.cmp(other))
   |                   ^^^ -----
   |                       |
   |                       unexpected argument of type `&Struct`
   |                       help: remove the extra argument
   |
note: method defined here
  --> src/main.rs:6:12
   |
6  |     pub fn cmp(&self) {
   |            ^^^

Version

rustc 1.73.0-nightly (da6b55cc5 2023-07-17)
binary: rustc
commit-hash: da6b55cc5eaf76ed6acb7dc2f7d611e32af7c9a7
commit-date: 2023-07-17
host: x86_64-unknown-linux-gnu
release: 1.73.0-nightly
LLVM version: 16.0.5

Additional Labels

@rustbot label +I-suggestion-causes-error

@dtolnay dtolnay added C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have labels Jul 18, 2023
@rustbot rustbot added the I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied label Jul 18, 2023
@dtolnay
Copy link
Member Author

dtolnay commented Jul 18, 2023

Mentioning @Centri3 @blyxyas @xFrednet, who recently worked on this lint in #10788.

@Centri3
Copy link
Member

Centri3 commented Jul 18, 2023

This sort of thing was already brought up: #10788 (comment)

It's a bit unfortunate but there's many, many variations of Some(self.cmp(other)) that are still correct but likely too difficult to not lint them all

@Centri3
Copy link
Member

Centri3 commented Jul 18, 2023

It should definitely be noted as a known issue however; not having that was an oversight on my part

@dtolnay
Copy link
Member Author

dtolnay commented Jul 18, 2023

I think there is a degree of difference between Some(Self::cmp(self, other)) and self.cmp(other).into() and I would not advocate in favor of the latter being recognized by the lint. But since the first one is calling literally the same function with the exact same arguments as clippy's preferred spelling, hopefully there would be an easy way for clippy to perceive that?

@Centri3
Copy link
Member

Centri3 commented Jul 18, 2023

Yeah it could handle both Call and MethodCall, that one could probably be fixed fine

bors added a commit that referenced this issue Jul 20, 2023
Allow `Self::cmp(self, other)` as a correct impl

Fixes #11178

Also no longer checks if the method name is *just* cmp, but the path. That was an oversight on my part ^^

r? `@xFrednet`
(and `@blyxyas` too!)

changelog: [`incorrect_partial_ord_impl_on_ord_type`]: Now allows non-method calls to `cmp` like `Self::cmp(self, other)`
@bors bors closed this as completed in ee8a429 Jul 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing I-false-positive Issue: The lint was triggered on code it shouldn't have I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants