]> git.proxmox.com Git - rustc.git/blob - src/tools/clippy/clippy_lints/src/matches/match_bool.rs
New upstream version 1.63.0+dfsg1
[rustc.git] / src / tools / clippy / clippy_lints / src / matches / match_bool.rs
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 }