Lint reversed ordering in partial ord impl (#14945)

Fixes rust-lang/rust-clippy#14574

Lint reversed ordering in partial ord impl

changelog: [`non_canonical_partial_ord_impl`] lint reversed ordering
This commit is contained in:
Samuel Tardieu 2025-06-03 15:37:41 +00:00 committed by GitHub
commit a4debd2345
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 56 additions and 2 deletions

View file

@ -293,7 +293,14 @@ fn self_cmp_call<'tcx>(
ExprKind::Call(path, [_, _]) => path_res(cx, path)
.opt_def_id()
.is_some_and(|def_id| cx.tcx.is_diagnostic_item(sym::ord_cmp_method, def_id)),
ExprKind::MethodCall(_, _, [_other], ..) => {
ExprKind::MethodCall(_, recv, [_], ..) => {
let ExprKind::Path(path) = recv.kind else {
return false;
};
if last_path_segment(&path).ident.name != kw::SelfLower {
return false;
}
// We can set this to true here no matter what as if it's a `MethodCall` and goes to the
// `else` branch, it must be a method named `cmp` that isn't `Ord::cmp`
*needs_fully_qualified = true;

View file

@ -195,3 +195,19 @@ impl PartialOrd for K {
//~^ non_canonical_partial_ord_impl
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
}
// #14574, check that partial_cmp invokes other.cmp
#[derive(Eq, PartialEq)]
struct L(u32);
impl Ord for L {
fn cmp(&self, other: &Self) -> Ordering {
todo!();
}
}
impl PartialOrd for L {
//~^ non_canonical_partial_ord_impl
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
}

View file

@ -201,3 +201,21 @@ impl PartialOrd for K {
Ordering::Greater.into()
}
}
// #14574, check that partial_cmp invokes other.cmp
#[derive(Eq, PartialEq)]
struct L(u32);
impl Ord for L {
fn cmp(&self, other: &Self) -> Ordering {
todo!();
}
}
impl PartialOrd for L {
//~^ non_canonical_partial_ord_impl
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(other.cmp(self))
}
}

View file

@ -44,5 +44,18 @@ LL | || }
LL | | }
| |__^
error: aborting due to 3 previous errors
error: non-canonical implementation of `partial_cmp` on an `Ord` type
--> tests/ui/non_canonical_partial_ord_impl.rs:216:1
|
LL | / impl PartialOrd for L {
LL | |
LL | | fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
| | _____________________________________________________________-
LL | || Some(other.cmp(self))
LL | || }
| ||_____- help: change this to: `{ Some(self.cmp(other)) }`
LL | | }
| |__^
error: aborting due to 4 previous errors