fix: restrict match_bool to 2 arms

This commit is contained in:
alhubanov 2026-01-02 18:02:52 +02:00
parent 86eaeaadd9
commit da1ffbe181

View file

@ -16,6 +16,7 @@ pub(crate) fn check(cx: &LateContext<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>]
&& arms
.iter()
.all(|arm| arm.pat.walk_short(|p| !matches!(p.kind, PatKind::Binding(..))))
&& arms.len() == 2
{
span_lint_and_then(
cx,
@ -23,59 +24,57 @@ pub(crate) fn check(cx: &LateContext<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>]
expr.span,
"`match` on a boolean expression",
move |diag| {
if arms.len() == 2 {
let mut app = Applicability::MachineApplicable;
let test_sugg = if let PatKind::Expr(arm_bool) = arms[0].pat.kind {
let test = Sugg::hir_with_applicability(cx, scrutinee, "_", &mut app);
if let PatExprKind::Lit { lit, .. } = arm_bool.kind {
match &lit.node {
LitKind::Bool(true) => Some(test),
LitKind::Bool(false) => Some(!test),
_ => None,
}
.map(|test| {
if let Some(guard) = &arms[0]
.guard
.map(|g| Sugg::hir_with_applicability(cx, g, "_", &mut app))
{
test.and(guard)
} else {
test
}
})
} else {
None
let mut app = Applicability::MachineApplicable;
let test_sugg = if let PatKind::Expr(arm_bool) = arms[0].pat.kind {
let test = Sugg::hir_with_applicability(cx, scrutinee, "_", &mut app);
if let PatExprKind::Lit { lit, .. } = arm_bool.kind {
match &lit.node {
LitKind::Bool(true) => Some(test),
LitKind::Bool(false) => Some(!test),
_ => None,
}
.map(|test| {
if let Some(guard) = &arms[0]
.guard
.map(|g| Sugg::hir_with_applicability(cx, g, "_", &mut app))
{
test.and(guard)
} else {
test
}
})
} else {
None
}
} else {
None
};
if let Some(test_sugg) = test_sugg {
let ctxt = expr.span.ctxt();
let (true_expr, false_expr) = (arms[0].body, arms[1].body);
let sugg = match (is_unit_expr(true_expr), is_unit_expr(false_expr)) {
(false, false) => Some(format!(
"if {} {} else {}",
test_sugg,
expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app),
expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app)
)),
(false, true) => Some(format!(
"if {} {}",
test_sugg,
expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app)
)),
(true, false) => Some(format!(
"if {} {}",
!test_sugg,
expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app)
)),
(true, true) => None,
};
if let Some(test_sugg) = test_sugg {
let ctxt = expr.span.ctxt();
let (true_expr, false_expr) = (arms[0].body, arms[1].body);
let sugg = match (is_unit_expr(true_expr), is_unit_expr(false_expr)) {
(false, false) => Some(format!(
"if {} {} else {}",
test_sugg,
expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app),
expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app)
)),
(false, true) => Some(format!(
"if {} {}",
test_sugg,
expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app)
)),
(true, false) => Some(format!(
"if {} {}",
!test_sugg,
expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app)
)),
(true, true) => None,
};
if let Some(sugg) = sugg {
diag.span_suggestion(expr.span, "consider using an `if`/`else` expression", sugg, app);
}
if let Some(sugg) = sugg {
diag.span_suggestion(expr.span, "consider using an `if`/`else` expression", sugg, app);
}
}
},