]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/unit_types/mod.rs
Merge commit 'e9d1a0a7b0b28dd422f1a790ccde532acafbf193' into sync_cg_clif-2022-08-24
[rust.git] / src / tools / clippy / 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, Local};
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     #[clippy::version = "pre 1.29.0"]
25     pub LET_UNIT_VALUE,
26     style,
27     "creating a `let` binding to a value of unit type, which usually can't be used afterwards"
28 }
29
30 declare_clippy_lint! {
31     /// ### What it does
32     /// Checks for comparisons to unit. This includes all binary
33     /// comparisons (like `==` and `<`) and asserts.
34     ///
35     /// ### Why is this bad?
36     /// Unit is always equal to itself, and thus is just a
37     /// clumsily written constant. Mostly this happens when someone accidentally
38     /// adds semicolons at the end of the operands.
39     ///
40     /// ### Example
41     /// ```rust
42     /// # fn foo() {};
43     /// # fn bar() {};
44     /// # fn baz() {};
45     /// if {
46     ///     foo();
47     /// } == {
48     ///     bar();
49     /// } {
50     ///     baz();
51     /// }
52     /// ```
53     /// is equal to
54     /// ```rust
55     /// # fn foo() {};
56     /// # fn bar() {};
57     /// # fn baz() {};
58     /// {
59     ///     foo();
60     ///     bar();
61     ///     baz();
62     /// }
63     /// ```
64     ///
65     /// For asserts:
66     /// ```rust
67     /// # fn foo() {};
68     /// # fn bar() {};
69     /// assert_eq!({ foo(); }, { bar(); });
70     /// ```
71     /// will always succeed
72     #[clippy::version = "pre 1.29.0"]
73     pub UNIT_CMP,
74     correctness,
75     "comparing unit values"
76 }
77
78 declare_clippy_lint! {
79     /// ### What it does
80     /// Checks for passing a unit value as an argument to a function without using a
81     /// unit literal (`()`).
82     ///
83     /// ### Why is this bad?
84     /// This is likely the result of an accidental semicolon.
85     ///
86     /// ### Example
87     /// ```rust,ignore
88     /// foo({
89     ///     let a = bar();
90     ///     baz(a);
91     /// })
92     /// ```
93     #[clippy::version = "pre 1.29.0"]
94     pub UNIT_ARG,
95     complexity,
96     "passing unit to a function"
97 }
98
99 declare_lint_pass!(UnitTypes => [LET_UNIT_VALUE, UNIT_CMP, UNIT_ARG]);
100
101 impl<'tcx> LateLintPass<'tcx> for UnitTypes {
102     fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) {
103         let_unit_value::check(cx, local);
104     }
105
106     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
107         unit_cmp::check(cx, expr);
108         unit_arg::check(cx, expr);
109     }
110 }