3
3
//! This lint is **warn** by default
4
4
5
5
use crate :: utils:: sugg:: Sugg ;
6
- use crate :: utils:: { higher, parent_node_is_if_expr, span_lint, span_lint_and_help, span_lint_and_sugg} ;
6
+ use crate :: utils:: { higher, parent_node_is_if_expr, span_lint, span_lint_and_help, span_lint_and_sugg, snippet_with_applicability } ;
7
7
use if_chain:: if_chain;
8
8
use rustc_ast:: ast:: LitKind ;
9
9
use rustc_errors:: Applicability ;
@@ -189,19 +189,23 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison {
189
189
}
190
190
}
191
191
192
- fn is_unary_not < ' tcx > ( e : & ' tcx Expr < ' _ > ) -> bool {
192
+ fn is_unary_not < ' tcx > ( e : & ' tcx Expr < ' _ > ) -> ( bool , rustc_span :: Span ) {
193
193
if_chain ! {
194
- if let ExprKind :: Unary ( unop, _ ) = e. kind;
194
+ if let ExprKind :: Unary ( unop, operand ) = e. kind;
195
195
if let UnOp :: UnNot = unop;
196
196
then {
197
- return true ;
197
+ return ( true , operand . span ) ;
198
198
}
199
199
} ;
200
- false
200
+ ( false , e . span )
201
201
}
202
202
203
- fn one_side_is_unary_not < ' tcx > ( left_side : & ' tcx Expr < ' _ > , right_side : & ' tcx Expr < ' _ > ) -> bool {
204
- is_unary_not ( left_side) ^ is_unary_not ( right_side)
203
+ fn one_side_is_unary_not < ' tcx > ( left_side : & ' tcx Expr < ' _ > , right_side : & ' tcx Expr < ' _ > ) -> ( bool , rustc_span:: Span , rustc_span:: Span ) {
204
+ let left = is_unary_not ( left_side) ;
205
+ let right = is_unary_not ( right_side) ;
206
+
207
+ let retval = left. 0 ^ right. 0 ;
208
+ ( retval, left. 1 , right. 1 )
205
209
}
206
210
207
211
fn check_comparison < ' a , ' tcx > (
@@ -218,14 +222,27 @@ fn check_comparison<'a, 'tcx>(
218
222
if let ExprKind :: Binary ( op, ref left_side, ref right_side) = e. kind {
219
223
let ( l_ty, r_ty) = ( cx. tables . expr_ty ( left_side) , cx. tables . expr_ty ( right_side) ) ;
220
224
if l_ty. is_bool ( ) && r_ty. is_bool ( ) {
221
- if_chain ! {
222
- if let BinOpKind :: Eq = op. node;
223
- if one_side_is_unary_not( & left_side, & right_side) ;
224
- then {
225
- span_lint_and_help( cx, BOOL_COMPARISON , e. span, "Here comes" , "the suggestion" ) ;
226
- }
227
- } ;
228
225
let mut applicability = Applicability :: MachineApplicable ;
226
+
227
+ if let BinOpKind :: Eq = op. node
228
+ {
229
+ let xxx = one_side_is_unary_not ( & left_side, & right_side) ;
230
+ if xxx. 0
231
+ {
232
+ span_lint_and_sugg (
233
+ cx,
234
+ BOOL_COMPARISON ,
235
+ e. span ,
236
+ "This comparison might be written more concisely" ,
237
+ "try simplifying it as shown" ,
238
+ format ! ( "{} != {}" ,
239
+ snippet_with_applicability( cx, xxx. 1 , ".." , & mut applicability) ,
240
+ snippet_with_applicability( cx, xxx. 2 , ".." , & mut applicability) ) ,
241
+ applicability,
242
+ )
243
+ }
244
+ }
245
+
229
246
match ( fetch_bool_expr ( left_side) , fetch_bool_expr ( right_side) ) {
230
247
( Bool ( true ) , Other ) => left_true. map_or ( ( ) , |( h, m) | {
231
248
suggest_bool_comparison ( cx, e, right_side, applicability, m, h)
0 commit comments