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 { check_stmt(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>)99 fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) { 100 let_unit_value::check(cx, stmt); 101 } 102 check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>)103 fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { 104 unit_cmp::check(cx, expr); 105 unit_arg::check(cx, expr); 106 } 107 } 108