]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/let_underscore.rs
Normalize lint messages
[rust.git] / clippy_lints / src / let_underscore.rs
1 use if_chain::if_chain;
2 use rustc::declare_lint_pass;
3 use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
4 use rustc_hir::*;
5 use rustc_session::declare_tool_lint;
6
7 use crate::utils::{is_must_use_func_call, is_must_use_ty, span_help_and_lint};
8
9 declare_clippy_lint! {
10     /// **What it does:** Checks for `let _ = <expr>`
11     /// where expr is #[must_use]
12     ///
13     /// **Why is this bad?** It's better to explicitly
14     /// handle the value of a #[must_use] expr
15     ///
16     /// **Known problems:** None.
17     ///
18     /// **Example:**
19     /// ```rust
20     /// fn f() -> Result<u32, u32> {
21     ///     Ok(0)
22     /// }
23     ///
24     /// let _ = f();
25     /// // is_ok() is marked #[must_use]
26     /// let _ = f().is_ok();
27     /// ```
28     pub LET_UNDERSCORE_MUST_USE,
29     restriction,
30     "non-binding let on a `#[must_use]` expression"
31 }
32
33 declare_lint_pass!(LetUnderscore => [LET_UNDERSCORE_MUST_USE]);
34
35 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LetUnderscore {
36     fn check_stmt(&mut self, cx: &LateContext<'_, '_>, stmt: &Stmt<'_>) {
37         if_chain! {
38             if let StmtKind::Local(ref local) = stmt.kind;
39             if let PatKind::Wild = local.pat.kind;
40             if let Some(ref init) = local.init;
41             then {
42                 if is_must_use_ty(cx, cx.tables.expr_ty(init)) {
43                    span_help_and_lint(
44                         cx,
45                         LET_UNDERSCORE_MUST_USE,
46                         stmt.span,
47                         "non-binding let on an expression with `#[must_use]` type",
48                         "consider explicitly using expression value"
49                     )
50                 } else if is_must_use_func_call(cx, init) {
51                     span_help_and_lint(
52                         cx,
53                         LET_UNDERSCORE_MUST_USE,
54                         stmt.span,
55                         "non-binding let on a result of a `#[must_use]` function",
56                         "consider explicitly using function result"
57                     )
58                 }
59             }
60         }
61     }
62 }