Skip to content

Commit

Permalink
Auto merge of rust-lang#12702 - Luv-Ray:non_canonical_partial_ord_imp…
Browse files Browse the repository at this point in the history
…l, r=Manishearth

[`non_canonical_partial_ord_impl`]: Fix emitting warnings which conflict with `needless_return`

fixes rust-lang#12683

---

changelog: fix [`non_canonical_partial_ord_impl`] emitting warnings which conflict with `needless_return`
  • Loading branch information
bors committed Apr 24, 2024
2 parents b2a7371 + 107e44b commit 9162bbf
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 11 deletions.
46 changes: 35 additions & 11 deletions clippy_lints/src/non_canonical_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,17 +182,17 @@ impl LateLintPass<'_> for NonCanonicalImpls {

if block.stmts.is_empty()
&& let Some(expr) = block.expr
&& let ExprKind::Call(
Expr {
kind: ExprKind::Path(some_path),
hir_id: some_hir_id,
..
},
[cmp_expr],
) = expr.kind
&& is_res_lang_ctor(cx, cx.qpath_res(some_path, *some_hir_id), LangItem::OptionSome)
// Fix #11178, allow `Self::cmp(self, ..)` too
&& self_cmp_call(cx, cmp_expr, impl_item.owner_id.def_id, &mut needs_fully_qualified)
&& expr_is_cmp(cx, &expr.kind, impl_item, &mut needs_fully_qualified)
{
}
// Fix #12683, allow [`needless_return`] here
else if block.expr.is_none()
&& let Some(stmt) = block.stmts.first()
&& let rustc_hir::StmtKind::Semi(Expr {
kind: ExprKind::Ret(Some(Expr { kind: ret_kind, .. })),
..
}) = stmt.kind
&& expr_is_cmp(cx, ret_kind, impl_item, &mut needs_fully_qualified)
{
} else {
// If `Self` and `Rhs` are not the same type, bail. This makes creating a valid
Expand Down Expand Up @@ -245,6 +245,30 @@ impl LateLintPass<'_> for NonCanonicalImpls {
}
}

/// Return true if `expr_kind` is a `cmp` call.
fn expr_is_cmp<'tcx>(
cx: &LateContext<'tcx>,
expr_kind: &'tcx ExprKind<'tcx>,
impl_item: &ImplItem<'_>,
needs_fully_qualified: &mut bool,
) -> bool {
if let ExprKind::Call(
Expr {
kind: ExprKind::Path(some_path),
hir_id: some_hir_id,
..
},
[cmp_expr],
) = expr_kind
{
is_res_lang_ctor(cx, cx.qpath_res(some_path, *some_hir_id), LangItem::OptionSome)
// Fix #11178, allow `Self::cmp(self, ..)` too
&& self_cmp_call(cx, cmp_expr, impl_item.owner_id.def_id, needs_fully_qualified)
} else {
false
}
}

/// Returns whether this is any of `self.cmp(..)`, `Self::cmp(self, ..)` or `Ord::cmp(self, ..)`.
fn self_cmp_call<'tcx>(
cx: &LateContext<'tcx>,
Expand Down
18 changes: 18 additions & 0 deletions tests/ui/non_canonical_partial_ord_impl.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -142,3 +142,21 @@ impl PartialOrd for H {
Some(Ord::cmp(self, other))
}
}

// #12683, do not lint

#[derive(Eq, PartialEq)]
struct I(u32);

impl Ord for I {
fn cmp(&self, other: &Self) -> Ordering {
todo!();
}
}

impl PartialOrd for I {
#[allow(clippy::needless_return)]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
return Some(self.cmp(other));
}
}
18 changes: 18 additions & 0 deletions tests/ui/non_canonical_partial_ord_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,21 @@ impl PartialOrd for H {
Some(Ord::cmp(self, other))
}
}

// #12683, do not lint

#[derive(Eq, PartialEq)]
struct I(u32);

impl Ord for I {
fn cmp(&self, other: &Self) -> Ordering {
todo!();
}
}

impl PartialOrd for I {
#[allow(clippy::needless_return)]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
return Some(self.cmp(other));
}
}

0 comments on commit 9162bbf

Please sign in to comment.