@@ -18,7 +18,7 @@ use crate::rustc_errors::Applicability;
1818use crate :: syntax:: ast:: LitKind ;
1919use crate :: syntax:: source_map:: Spanned ;
2020use crate :: utils:: sugg:: Sugg ;
21- use crate :: utils:: { in_macro, snippet_with_applicability , span_lint, span_lint_and_sugg} ;
21+ use crate :: utils:: { in_macro, span_lint, span_lint_and_sugg} ;
2222
2323/// **What it does:** Checks for expressions of the form `if c { true } else {
2424/// false }`
@@ -45,8 +45,8 @@ declare_clippy_lint! {
4545 "if-statements with plain booleans in the then- and else-clause, e.g. `if p { true } else { false }`"
4646}
4747
48- /// **What it does:** Checks for expressions of the form `x == true` (or vice
49- /// versa) and suggest using the variable directly.
48+ /// **What it does:** Checks for expressions of the form `x == true` and
49+ /// `x != true` (or vice versa) and suggest using the variable directly.
5050///
5151/// **Why is this bad?** Unnecessary code.
5252///
@@ -59,7 +59,7 @@ declare_clippy_lint! {
5959declare_clippy_lint ! {
6060 pub BOOL_COMPARISON ,
6161 complexity,
62- "comparing a variable to a boolean, e.g. `if x == true`"
62+ "comparing a variable to a boolean, e.g. `if x == true` or `if x != true` "
6363}
6464
6565#[ derive( Copy , Clone ) ]
@@ -138,76 +138,78 @@ impl LintPass for BoolComparison {
138138
139139impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for BoolComparison {
140140 fn check_expr ( & mut self , cx : & LateContext < ' a , ' tcx > , e : & ' tcx Expr ) {
141- use self :: Expression :: * ;
142-
143141 if in_macro ( e. span ) {
144142 return ;
145143 }
146144
147- if let ExprKind :: Binary (
148- Spanned {
149- node : BinOpKind :: Eq , ..
150- } ,
151- ref left_side,
152- ref right_side,
153- ) = e. node
154- {
155- let mut applicability = Applicability :: MachineApplicable ;
156- match ( fetch_bool_expr ( left_side) , fetch_bool_expr ( right_side) ) {
157- ( Bool ( true ) , Other ) => {
158- let hint = snippet_with_applicability ( cx, right_side. span , ".." , & mut applicability) ;
159- span_lint_and_sugg (
160- cx,
161- BOOL_COMPARISON ,
162- e. span ,
163- "equality checks against true are unnecessary" ,
164- "try simplifying it as shown" ,
165- hint. to_string ( ) ,
166- applicability,
167- ) ;
168- } ,
169- ( Other , Bool ( true ) ) => {
170- let hint = snippet_with_applicability ( cx, left_side. span , ".." , & mut applicability) ;
171- span_lint_and_sugg (
172- cx,
173- BOOL_COMPARISON ,
174- e. span ,
175- "equality checks against true are unnecessary" ,
176- "try simplifying it as shown" ,
177- hint. to_string ( ) ,
178- applicability,
179- ) ;
180- } ,
181- ( Bool ( false ) , Other ) => {
182- let hint = Sugg :: hir_with_applicability ( cx, right_side, ".." , & mut applicability) ;
183- span_lint_and_sugg (
184- cx,
185- BOOL_COMPARISON ,
186- e. span ,
187- "equality checks against false can be replaced by a negation" ,
188- "try simplifying it as shown" ,
189- ( !hint) . to_string ( ) ,
190- applicability,
191- ) ;
192- } ,
193- ( Other , Bool ( false ) ) => {
194- let hint = Sugg :: hir_with_applicability ( cx, left_side, ".." , & mut applicability) ;
195- span_lint_and_sugg (
196- cx,
197- BOOL_COMPARISON ,
198- e. span ,
199- "equality checks against false can be replaced by a negation" ,
200- "try simplifying it as shown" ,
201- ( !hint) . to_string ( ) ,
202- applicability,
203- ) ;
204- } ,
145+ if let ExprKind :: Binary ( Spanned { node, .. } , ..) = e. node {
146+ match node {
147+ BinOpKind :: Eq => check_comparison (
148+ cx,
149+ e,
150+ "equality checks against true are unnecessary" ,
151+ "equality checks against false can be replaced by a negation" ,
152+ |h| h,
153+ |h| !h,
154+ ) ,
155+ BinOpKind :: Ne => check_comparison (
156+ cx,
157+ e,
158+ "inequality checks against true can be replaced by a negation" ,
159+ "inequality checks against false are unnecessary" ,
160+ |h| !h,
161+ |h| h,
162+ ) ,
205163 _ => ( ) ,
206164 }
207165 }
208166 }
209167}
210168
169+ fn check_comparison < ' a , ' tcx > (
170+ cx : & LateContext < ' a , ' tcx > ,
171+ e : & ' tcx Expr ,
172+ true_message : & str ,
173+ false_message : & str ,
174+ true_hint : impl FnOnce ( Sugg < ' _ > ) -> Sugg < ' _ > ,
175+ false_hint : impl FnOnce ( Sugg < ' _ > ) -> Sugg < ' _ > ,
176+ ) {
177+ use self :: Expression :: * ;
178+
179+ if let ExprKind :: Binary ( _, ref left_side, ref right_side) = e. node {
180+ let applicability = Applicability :: MachineApplicable ;
181+ match ( fetch_bool_expr ( left_side) , fetch_bool_expr ( right_side) ) {
182+ ( Bool ( true ) , Other ) => suggest_bool_comparison ( cx, e, right_side, applicability, true_message, true_hint) ,
183+ ( Other , Bool ( true ) ) => suggest_bool_comparison ( cx, e, left_side, applicability, true_message, true_hint) ,
184+ ( Bool ( false ) , Other ) => {
185+ suggest_bool_comparison ( cx, e, right_side, applicability, false_message, false_hint)
186+ } ,
187+ ( Other , Bool ( false ) ) => suggest_bool_comparison ( cx, e, left_side, applicability, false_message, false_hint) ,
188+ _ => ( ) ,
189+ }
190+ }
191+ }
192+
193+ fn suggest_bool_comparison < ' a , ' tcx > (
194+ cx : & LateContext < ' a , ' tcx > ,
195+ e : & ' tcx Expr ,
196+ expr : & Expr ,
197+ mut applicability : Applicability ,
198+ message : & str ,
199+ conv_hint : impl FnOnce ( Sugg < ' _ > ) -> Sugg < ' _ > ,
200+ ) {
201+ let hint = Sugg :: hir_with_applicability ( cx, expr, ".." , & mut applicability) ;
202+ span_lint_and_sugg (
203+ cx,
204+ BOOL_COMPARISON ,
205+ e. span ,
206+ message,
207+ "try simplifying it as shown" ,
208+ conv_hint ( hint) . to_string ( ) ,
209+ applicability,
210+ ) ;
211+ }
212+
211213enum Expression {
212214 Bool ( bool ) ,
213215 RetBool ( bool ) ,
0 commit comments