refactor(double_comparison): clean-up, simplify lint logic (#15955)

- use let-chains
- rm macro
- add comments explaining linted cases

changelog: none
This commit is contained in:
Samuel Tardieu 2025-10-27 08:03:05 +00:00 committed by GitHub
commit da8965202a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -8,46 +8,52 @@ use rustc_span::Span;
use super::DOUBLE_COMPARISONS;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, op: BinOpKind, lhs: &'tcx Expr<'_>, rhs: &'tcx Expr<'_>, span: Span) {
let (lkind, llhs, lrhs, rkind, rlhs, rrhs) = match (&lhs.kind, &rhs.kind) {
(ExprKind::Binary(lb, llhs, lrhs), ExprKind::Binary(rb, rlhs, rrhs)) => {
(lb.node, llhs, lrhs, rb.node, rlhs, rrhs)
},
_ => return,
};
if !(eq_expr_value(cx, llhs, rlhs) && eq_expr_value(cx, lrhs, rrhs)) {
return;
}
macro_rules! lint_double_comparison {
($op:tt) => {{
let mut applicability = Applicability::MachineApplicable;
let lhs_str = snippet_with_applicability(cx, llhs.span, "", &mut applicability);
let rhs_str = snippet_with_applicability(cx, lrhs.span, "", &mut applicability);
let sugg = format!("{} {} {}", lhs_str, stringify!($op), rhs_str);
span_lint_and_sugg(
cx,
DOUBLE_COMPARISONS,
span,
"this binary expression can be simplified",
"try",
sugg,
applicability,
);
}};
}
match (op, lkind, rkind) {
(BinOpKind::Or, BinOpKind::Eq, BinOpKind::Lt) | (BinOpKind::Or, BinOpKind::Lt, BinOpKind::Eq) => {
lint_double_comparison!(<=);
},
(BinOpKind::Or, BinOpKind::Eq, BinOpKind::Gt) | (BinOpKind::Or, BinOpKind::Gt, BinOpKind::Eq) => {
lint_double_comparison!(>=);
},
(BinOpKind::Or, BinOpKind::Lt, BinOpKind::Gt) | (BinOpKind::Or, BinOpKind::Gt, BinOpKind::Lt) => {
lint_double_comparison!(!=);
},
(BinOpKind::And, BinOpKind::Le, BinOpKind::Ge) | (BinOpKind::And, BinOpKind::Ge, BinOpKind::Le) => {
lint_double_comparison!(==);
},
_ => (),
pub(super) fn check(cx: &LateContext<'_>, op: BinOpKind, lhs: &Expr<'_>, rhs: &Expr<'_>, span: Span) {
if let ExprKind::Binary(lop, llhs, lrhs) = lhs.kind
&& let ExprKind::Binary(rop, rlhs, rrhs) = rhs.kind
&& eq_expr_value(cx, llhs, rlhs)
&& eq_expr_value(cx, lrhs, rrhs)
{
let op = match (op, lop.node, rop.node) {
// x == y || x < y => x <= y
(BinOpKind::Or, BinOpKind::Eq, BinOpKind::Lt)
// x < y || x == y => x <= y
| (BinOpKind::Or, BinOpKind::Lt, BinOpKind::Eq) => {
"<="
},
// x == y || x > y => x >= y
(BinOpKind::Or, BinOpKind::Eq, BinOpKind::Gt)
// x > y || x == y => x >= y
| (BinOpKind::Or, BinOpKind::Gt, BinOpKind::Eq) => {
">="
},
// x < y || x > y => x != y
(BinOpKind::Or, BinOpKind::Lt, BinOpKind::Gt)
// x > y || x < y => x != y
| (BinOpKind::Or, BinOpKind::Gt, BinOpKind::Lt) => {
"!="
},
// x <= y && x >= y => x == y
(BinOpKind::And, BinOpKind::Le, BinOpKind::Ge)
// x >= y && x <= y => x == y
| (BinOpKind::And, BinOpKind::Ge, BinOpKind::Le) => {
"=="
},
_ => return,
};
let mut applicability = Applicability::MachineApplicable;
let lhs_str = snippet_with_applicability(cx, llhs.span, "", &mut applicability);
let rhs_str = snippet_with_applicability(cx, lrhs.span, "", &mut applicability);
let sugg = format!("{lhs_str} {op} {rhs_str}");
span_lint_and_sugg(
cx,
DOUBLE_COMPARISONS,
span,
"this binary expression can be simplified",
"try",
sugg,
applicability,
);
}
}