]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/unit_types/mod.rs
Auto merge of #7478 - DevinR528:preemtive, r=llogiq
[rust.git] / clippy_lints / src / unit_types / mod.rs
1 mod let_unit_value;
2 mod unit_arg;
3 mod unit_cmp;
4 mod utils;
5
6 use rustc_hir::{Expr, Stmt};
7 use rustc_lint::{LateContext, LateLintPass};
8 use rustc_session::{declare_lint_pass, declare_tool_lint};
9
10 declare_clippy_lint! {
11     /// ### What it does
12     /// Checks for binding a unit value.
13     ///
14     /// ### Why is this bad?
15     /// A unit value cannot usefully be used anywhere. So
16     /// binding one is kind of pointless.
17     ///
18     /// ### Example
19     /// ```rust
20     /// let x = {
21     ///     1;
22     /// };
23     /// ```
24     pub LET_UNIT_VALUE,
25     pedantic,
26     "creating a `let` binding to a value of unit type, which usually can't be used afterwards"
27 }
28
29 declare_clippy_lint! {
30     /// ### What it does
31     /// Checks for comparisons to unit. This includes all binary
32     /// comparisons (like `==` and `<`) and asserts.
33     ///
34     /// ### Why is this bad?
35     /// Unit is always equal to itself, and thus is just a
36     /// clumsily written constant. Mostly this happens when someone accidentally
37     /// adds semicolons at the end of the operands.
38     ///
39     /// ### Example
40     /// ```rust
41     /// # fn foo() {};
42     /// # fn bar() {};
43     /// # fn baz() {};
44     /// if {
45     ///     foo();
46     /// } == {
47     ///     bar();
48     /// } {
49     ///     baz();
50     /// }
51     /// ```
52     /// is equal to
53     /// ```rust
54     /// # fn foo() {};
55     /// # fn bar() {};
56     /// # fn baz() {};
57     /// {
58     ///     foo();
59     ///     bar();
60     ///     baz();
61     /// }
62     /// ```
63     ///
64     /// For asserts:
65     /// ```rust
66     /// # fn foo() {};
67     /// # fn bar() {};
68     /// assert_eq!({ foo(); }, { bar(); });
69     /// ```
70     /// will always succeed
71     pub UNIT_CMP,
72     correctness,
73     "comparing unit values"
74 }
75
76 declare_clippy_lint! {
77     /// ### What it does
78     /// Checks for passing a unit value as an argument to a function without using a
79     /// unit literal (`()`).
80     ///
81     /// ### Why is this bad?
82     /// This is likely the result of an accidental semicolon.
83     ///
84     /// ### Example
85     /// ```rust,ignore
86     /// foo({
87     ///     let a = bar();
88     ///     baz(a);
89     /// })
90     /// ```
91     pub UNIT_ARG,
92     complexity,
93     "passing unit to a function"
94 }
95
96 declare_lint_pass!(UnitTypes => [LET_UNIT_VALUE, UNIT_CMP, UNIT_ARG]);
97
98 impl LateLintPass<'_> for UnitTypes {
99     fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) {
100         let_unit_value::check(cx, stmt);
101     }
102
103     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
104         unit_cmp::check(cx, expr);
105         unit_arg::check(cx, expr);
106     }
107 }