diff --git a/clippy_lints/src/non_canonical_impls.rs b/clippy_lints/src/non_canonical_impls.rs index 93865197ec96..04b092769666 100644 --- a/clippy_lints/src/non_canonical_impls.rs +++ b/clippy_lints/src/non_canonical_impls.rs @@ -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; diff --git a/tests/ui/non_canonical_partial_ord_impl.fixed b/tests/ui/non_canonical_partial_ord_impl.fixed index 23dbee5a0848..6915e1984fb1 100644 --- a/tests/ui/non_canonical_partial_ord_impl.fixed +++ b/tests/ui/non_canonical_partial_ord_impl.fixed @@ -195,3 +195,19 @@ impl PartialOrd for K { //~^ non_canonical_partial_ord_impl fn partial_cmp(&self, other: &Self) -> Option { 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 { Some(self.cmp(other)) } +} diff --git a/tests/ui/non_canonical_partial_ord_impl.rs b/tests/ui/non_canonical_partial_ord_impl.rs index 12f055a542b8..7ce4cdc9aec8 100644 --- a/tests/ui/non_canonical_partial_ord_impl.rs +++ b/tests/ui/non_canonical_partial_ord_impl.rs @@ -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 { + Some(other.cmp(self)) + } +} diff --git a/tests/ui/non_canonical_partial_ord_impl.stderr b/tests/ui/non_canonical_partial_ord_impl.stderr index c7de968588f8..9bd6b1f726df 100644 --- a/tests/ui/non_canonical_partial_ord_impl.stderr +++ b/tests/ui/non_canonical_partial_ord_impl.stderr @@ -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 { + | | _____________________________________________________________- +LL | || Some(other.cmp(self)) +LL | || } + | ||_____- help: change this to: `{ Some(self.cmp(other)) }` +LL | | } + | |__^ + +error: aborting due to 4 previous errors