]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/assertions_on_constants.rs
Fix assertions_on_constants lint
[rust.git] / clippy_lints / src / assertions_on_constants.rs
1 use rustc::hir::{Expr, ExprKind};
2 use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
3 use rustc::{declare_lint_pass, declare_tool_lint};
4
5 use crate::consts::{constant, Constant};
6 use crate::utils::{in_macro_or_desugar, is_direct_expn_of, is_expn_of, span_help_and_lint};
7
8 declare_clippy_lint! {
9     /// **What it does:** Checks for `assert!(true)` and `assert!(false)` calls.
10     ///
11     /// **Why is this bad?** Will be optimized out by the compiler or should probably be replaced by a
12     /// panic!() or unreachable!()
13     ///
14     /// **Known problems:** None
15     ///
16     /// **Example:**
17     /// ```rust,ignore
18     /// assert!(false)
19     /// // or
20     /// assert!(true)
21     /// // or
22     /// const B: bool = false;
23     /// assert!(B)
24     /// ```
25     pub ASSERTIONS_ON_CONSTANTS,
26     style,
27     "`assert!(true)` / `assert!(false)` will be optimized out by the compiler, and should probably be replaced by a `panic!()` or `unreachable!()`"
28 }
29
30 declare_lint_pass!(AssertionsOnConstants => [ASSERTIONS_ON_CONSTANTS]);
31
32 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for AssertionsOnConstants {
33     fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
34         let lint_assert_cb = |is_debug_assert: bool| {
35             if let ExprKind::Unary(_, ref lit) = e.node {
36                 if let Some((Constant::Bool(is_true), _)) = constant(cx, cx.tables, lit) {
37                     if is_true {
38                         span_help_and_lint(
39                             cx,
40                             ASSERTIONS_ON_CONSTANTS,
41                             e.span,
42                             "`assert!(true)` will be optimized out by the compiler",
43                             "remove it",
44                         );
45                     } else if !is_debug_assert {
46                         span_help_and_lint(
47                             cx,
48                             ASSERTIONS_ON_CONSTANTS,
49                             e.span,
50                             "`assert!(false)` should probably be replaced",
51                             "use `panic!()` or `unreachable!()`",
52                         );
53                     }
54                 }
55             }
56         };
57         if let Some(debug_assert_span) = is_expn_of(e.span, "debug_assert") {
58             if in_macro_or_desugar(debug_assert_span) {
59                 return;
60             }
61             lint_assert_cb(true);
62         } else if let Some(assert_span) = is_direct_expn_of(e.span, "assert") {
63             if in_macro_or_desugar(assert_span) {
64                 return;
65             }
66             lint_assert_cb(false);
67         }
68     }
69 }