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