Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit f3dd909

Browse files
committed
Split out match_bool
1 parent f23dc16 commit f3dd909

File tree

2 files changed

+80
-69
lines changed

2 files changed

+80
-69
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
use clippy_utils::diagnostics::span_lint_and_then;
2+
use clippy_utils::is_unit_expr;
3+
use clippy_utils::source::{expr_block, snippet};
4+
use clippy_utils::sugg::Sugg;
5+
use rustc_ast::LitKind;
6+
use rustc_errors::Applicability;
7+
use rustc_hir::{Arm, Expr, ExprKind, PatKind};
8+
use rustc_lint::LateContext;
9+
use rustc_middle::ty;
10+
11+
use super::MATCH_BOOL;
12+
13+
pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) {
14+
// Type of expression is `bool`.
15+
if *cx.typeck_results().expr_ty(ex).kind() == ty::Bool {
16+
span_lint_and_then(
17+
cx,
18+
MATCH_BOOL,
19+
expr.span,
20+
"you seem to be trying to match on a boolean expression",
21+
move |diag| {
22+
if arms.len() == 2 {
23+
// no guards
24+
let exprs = if let PatKind::Lit(arm_bool) = arms[0].pat.kind {
25+
if let ExprKind::Lit(ref lit) = arm_bool.kind {
26+
match lit.node {
27+
LitKind::Bool(true) => Some((&*arms[0].body, &*arms[1].body)),
28+
LitKind::Bool(false) => Some((&*arms[1].body, &*arms[0].body)),
29+
_ => None,
30+
}
31+
} else {
32+
None
33+
}
34+
} else {
35+
None
36+
};
37+
38+
if let Some((true_expr, false_expr)) = exprs {
39+
let sugg = match (is_unit_expr(true_expr), is_unit_expr(false_expr)) {
40+
(false, false) => Some(format!(
41+
"if {} {} else {}",
42+
snippet(cx, ex.span, "b"),
43+
expr_block(cx, true_expr, None, "..", Some(expr.span)),
44+
expr_block(cx, false_expr, None, "..", Some(expr.span))
45+
)),
46+
(false, true) => Some(format!(
47+
"if {} {}",
48+
snippet(cx, ex.span, "b"),
49+
expr_block(cx, true_expr, None, "..", Some(expr.span))
50+
)),
51+
(true, false) => {
52+
let test = Sugg::hir(cx, ex, "..");
53+
Some(format!(
54+
"if {} {}",
55+
!test,
56+
expr_block(cx, false_expr, None, "..", Some(expr.span))
57+
))
58+
},
59+
(true, true) => None,
60+
};
61+
62+
if let Some(sugg) = sugg {
63+
diag.span_suggestion(
64+
expr.span,
65+
"consider using an `if`/`else` expression",
66+
sugg,
67+
Applicability::HasPlaceholders,
68+
);
69+
}
70+
}
71+
}
72+
},
73+
);
74+
}
75+
}

clippy_lints/src/matches/mod.rs

Lines changed: 5 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@ use clippy_utils::diagnostics::{
44
};
55
use clippy_utils::macros::{is_panic, root_macro_call};
66
use clippy_utils::peel_blocks_with_stmt;
7-
use clippy_utils::source::{expr_block, indent_of, snippet, snippet_block, snippet_opt, snippet_with_applicability};
7+
use clippy_utils::source::{indent_of, snippet, snippet_block, snippet_opt, snippet_with_applicability};
88
use clippy_utils::sugg::Sugg;
99
use clippy_utils::ty::is_type_diagnostic_item;
1010
use clippy_utils::visitors::is_local_used;
1111
use clippy_utils::{
12-
get_parent_expr, is_lang_ctor, is_refutable, is_unit_expr, is_wild, meets_msrv, msrvs, path_to_local_id,
13-
peel_blocks, peel_hir_pat_refs, recurse_or_patterns, strip_pat_refs,
12+
get_parent_expr, is_lang_ctor, is_refutable, is_wild, meets_msrv, msrvs, path_to_local_id, peel_blocks,
13+
peel_hir_pat_refs, recurse_or_patterns, strip_pat_refs,
1414
};
1515
use core::iter::once;
1616
use if_chain::if_chain;
17-
use rustc_ast::ast::LitKind;
1817
use rustc_errors::Applicability;
1918
use rustc_hir::def::{CtorKind, DefKind, Res};
2019
use rustc_hir::LangItem::{OptionNone, OptionSome};
@@ -29,6 +28,7 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
2928
use rustc_span::{sym, symbol::kw, Span};
3029
use std::cmp::Ordering;
3130

31+
mod match_bool;
3232
mod match_like_matches;
3333
mod match_same_arms;
3434
mod redundant_pattern_match;
@@ -631,7 +631,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
631631

632632
if let ExprKind::Match(ex, arms, MatchSource::Normal) = expr.kind {
633633
single_match::check(cx, ex, arms, expr);
634-
check_match_bool(cx, ex, arms, expr);
634+
match_bool::check(cx, ex, arms, expr);
635635
check_overlapping_arms(cx, ex, arms);
636636
check_wild_err_arm(cx, ex, arms);
637637
check_wild_enum_match(cx, ex, arms);
@@ -710,70 +710,6 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
710710
extract_msrv_attr!(LateContext);
711711
}
712712

713-
fn check_match_bool(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) {
714-
// Type of expression is `bool`.
715-
if *cx.typeck_results().expr_ty(ex).kind() == ty::Bool {
716-
span_lint_and_then(
717-
cx,
718-
MATCH_BOOL,
719-
expr.span,
720-
"you seem to be trying to match on a boolean expression",
721-
move |diag| {
722-
if arms.len() == 2 {
723-
// no guards
724-
let exprs = if let PatKind::Lit(arm_bool) = arms[0].pat.kind {
725-
if let ExprKind::Lit(ref lit) = arm_bool.kind {
726-
match lit.node {
727-
LitKind::Bool(true) => Some((&*arms[0].body, &*arms[1].body)),
728-
LitKind::Bool(false) => Some((&*arms[1].body, &*arms[0].body)),
729-
_ => None,
730-
}
731-
} else {
732-
None
733-
}
734-
} else {
735-
None
736-
};
737-
738-
if let Some((true_expr, false_expr)) = exprs {
739-
let sugg = match (is_unit_expr(true_expr), is_unit_expr(false_expr)) {
740-
(false, false) => Some(format!(
741-
"if {} {} else {}",
742-
snippet(cx, ex.span, "b"),
743-
expr_block(cx, true_expr, None, "..", Some(expr.span)),
744-
expr_block(cx, false_expr, None, "..", Some(expr.span))
745-
)),
746-
(false, true) => Some(format!(
747-
"if {} {}",
748-
snippet(cx, ex.span, "b"),
749-
expr_block(cx, true_expr, None, "..", Some(expr.span))
750-
)),
751-
(true, false) => {
752-
let test = Sugg::hir(cx, ex, "..");
753-
Some(format!(
754-
"if {} {}",
755-
!test,
756-
expr_block(cx, false_expr, None, "..", Some(expr.span))
757-
))
758-
},
759-
(true, true) => None,
760-
};
761-
762-
if let Some(sugg) = sugg {
763-
diag.span_suggestion(
764-
expr.span,
765-
"consider using an `if`/`else` expression",
766-
sugg,
767-
Applicability::HasPlaceholders,
768-
);
769-
}
770-
}
771-
}
772-
},
773-
);
774-
}
775-
}
776-
777713
fn check_overlapping_arms<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>]) {
778714
if arms.len() >= 2 && cx.typeck_results().expr_ty(ex).is_integral() {
779715
let ranges = all_ranges(cx, arms, cx.typeck_results().expr_ty(ex));

0 commit comments

Comments
 (0)