@@ -7,7 +7,7 @@ use clippy_utils::{
77} ;
88use rustc_ast:: ast:: LitKind ;
99use rustc_errors:: Applicability ;
10- use rustc_hir:: { BinOpKind , Expr , ExprKind , UnOp } ;
10+ use rustc_hir:: { BinOpKind , Expr , ExprKind } ;
1111use rustc_lint:: { LateContext , LateLintPass } ;
1212use rustc_session:: declare_lint_pass;
1313use rustc_span:: Span ;
@@ -232,7 +232,12 @@ impl<'tcx> LateLintPass<'tcx> for BoolComparison {
232232 return ;
233233 }
234234
235- if let ExprKind :: Binary ( Spanned { node, .. } , ..) = e. kind {
235+ if let ExprKind :: Binary ( Spanned { node, .. } , left_side, right_side) = e. kind
236+ && is_expn_of ( left_side. span , sym:: cfg) . is_none ( )
237+ && is_expn_of ( right_side. span , sym:: cfg) . is_none ( )
238+ && cx. typeck_results ( ) . expr_ty ( left_side) . is_bool ( )
239+ && cx. typeck_results ( ) . expr_ty ( right_side) . is_bool ( )
240+ {
236241 let ignore_case = None :: < ( fn ( _) -> _ , & str ) > ;
237242 let ignore_no_literal = None :: < ( fn ( _, _) -> _ , & str ) > ;
238243 match node {
@@ -288,30 +293,6 @@ impl<'tcx> LateLintPass<'tcx> for BoolComparison {
288293 }
289294}
290295
291- struct ExpressionInfoWithSpan {
292- one_side_is_unary_not : bool ,
293- left_span : Span ,
294- right_span : Span ,
295- }
296-
297- fn is_unary_not ( e : & Expr < ' _ > ) -> ( bool , Span ) {
298- if let ExprKind :: Unary ( UnOp :: Not , operand) = e. kind {
299- return ( true , operand. span ) ;
300- }
301- ( false , e. span )
302- }
303-
304- fn one_side_is_unary_not < ' tcx > ( left_side : & ' tcx Expr < ' _ > , right_side : & ' tcx Expr < ' _ > ) -> ExpressionInfoWithSpan {
305- let left = is_unary_not ( left_side) ;
306- let right = is_unary_not ( right_side) ;
307-
308- ExpressionInfoWithSpan {
309- one_side_is_unary_not : left. 0 != right. 0 ,
310- left_span : left. 1 ,
311- right_span : right. 1 ,
312- }
313- }
314-
315296fn check_comparison < ' a , ' tcx > (
316297 cx : & LateContext < ' tcx > ,
317298 e : & ' tcx Expr < ' _ > ,
@@ -321,81 +302,39 @@ fn check_comparison<'a, 'tcx>(
321302 right_false : Option < ( impl FnOnce ( Sugg < ' a > ) -> Sugg < ' a > , & ' static str ) > ,
322303 no_literal : Option < ( impl FnOnce ( Sugg < ' a > , Sugg < ' a > ) -> Sugg < ' a > , & ' static str ) > ,
323304) {
324- if let ExprKind :: Binary ( op, left_side, right_side) = e. kind {
325- let ( l_ty, r_ty) = (
326- cx. typeck_results ( ) . expr_ty ( left_side) ,
327- cx. typeck_results ( ) . expr_ty ( right_side) ,
328- ) ;
329- if is_expn_of ( left_side. span , sym:: cfg) . is_some ( ) || is_expn_of ( right_side. span , sym:: cfg) . is_some ( ) {
330- return ;
331- }
332- if l_ty. is_bool ( ) && r_ty. is_bool ( ) {
333- let mut applicability = Applicability :: MachineApplicable ;
334- // Eliminate parentheses in `e` by using the lo pos of lhs and hi pos of rhs,
335- // calling `source_callsite` make sure macros are handled correctly, see issue #9907
336- let binop_span = left_side
337- . span
338- . source_callsite ( )
339- . with_hi ( right_side. span . source_callsite ( ) . hi ( ) ) ;
305+ if let ExprKind :: Binary ( _, left_side, right_side) = e. kind {
306+ let mut applicability = Applicability :: MachineApplicable ;
307+ // Eliminate parentheses in `e` by using the lo pos of lhs and hi pos of rhs,
308+ // calling `source_callsite` make sure macros are handled correctly, see issue #9907
309+ let binop_span = left_side. span . source_callsite ( ) . to ( right_side. span . source_callsite ( ) ) ;
340310
341- if op. node == BinOpKind :: Eq {
342- let expression_info = one_side_is_unary_not ( left_side, right_side) ;
343- if expression_info. one_side_is_unary_not {
344- span_lint_and_sugg (
345- cx,
346- BOOL_COMPARISON ,
347- binop_span,
348- "this comparison might be written more concisely" ,
349- "try simplifying it as shown" ,
350- format ! (
351- "{} != {}" ,
352- snippet_with_applicability(
353- cx,
354- expression_info. left_span. source_callsite( ) ,
355- ".." ,
356- & mut applicability
357- ) ,
358- snippet_with_applicability(
359- cx,
360- expression_info. right_span. source_callsite( ) ,
361- ".." ,
362- & mut applicability
363- )
364- ) ,
365- applicability,
366- ) ;
367- }
368- }
369-
370- match ( fetch_bool_expr ( left_side) , fetch_bool_expr ( right_side) ) {
371- ( Some ( true ) , None ) => left_true. map_or ( ( ) , |( h, m) | {
372- suggest_bool_comparison ( cx, binop_span, right_side, applicability, m, h) ;
373- } ) ,
374- ( None , Some ( true ) ) => right_true. map_or ( ( ) , |( h, m) | {
375- suggest_bool_comparison ( cx, binop_span, left_side, applicability, m, h) ;
376- } ) ,
377- ( Some ( false ) , None ) => left_false. map_or ( ( ) , |( h, m) | {
378- suggest_bool_comparison ( cx, binop_span, right_side, applicability, m, h) ;
379- } ) ,
380- ( None , Some ( false ) ) => right_false. map_or ( ( ) , |( h, m) | {
381- suggest_bool_comparison ( cx, binop_span, left_side, applicability, m, h) ;
382- } ) ,
383- ( None , None ) => no_literal. map_or ( ( ) , |( h, m) | {
384- let left_side = Sugg :: hir_with_context ( cx, left_side, binop_span. ctxt ( ) , ".." , & mut applicability) ;
385- let right_side =
386- Sugg :: hir_with_context ( cx, right_side, binop_span. ctxt ( ) , ".." , & mut applicability) ;
387- span_lint_and_sugg (
388- cx,
389- BOOL_COMPARISON ,
390- binop_span,
391- m,
392- "try simplifying it as shown" ,
393- h ( left_side, right_side) . into_string ( ) ,
394- applicability,
395- ) ;
396- } ) ,
397- _ => ( ) ,
398- }
311+ match ( fetch_bool_expr ( left_side) , fetch_bool_expr ( right_side) ) {
312+ ( Some ( true ) , None ) => left_true. map_or ( ( ) , |( h, m) | {
313+ suggest_bool_comparison ( cx, binop_span, right_side, applicability, m, h) ;
314+ } ) ,
315+ ( None , Some ( true ) ) => right_true. map_or ( ( ) , |( h, m) | {
316+ suggest_bool_comparison ( cx, binop_span, left_side, applicability, m, h) ;
317+ } ) ,
318+ ( Some ( false ) , None ) => left_false. map_or ( ( ) , |( h, m) | {
319+ suggest_bool_comparison ( cx, binop_span, right_side, applicability, m, h) ;
320+ } ) ,
321+ ( None , Some ( false ) ) => right_false. map_or ( ( ) , |( h, m) | {
322+ suggest_bool_comparison ( cx, binop_span, left_side, applicability, m, h) ;
323+ } ) ,
324+ ( None , None ) => no_literal. map_or ( ( ) , |( h, m) | {
325+ let left_side = Sugg :: hir_with_context ( cx, left_side, binop_span. ctxt ( ) , ".." , & mut applicability) ;
326+ let right_side = Sugg :: hir_with_context ( cx, right_side, binop_span. ctxt ( ) , ".." , & mut applicability) ;
327+ span_lint_and_sugg (
328+ cx,
329+ BOOL_COMPARISON ,
330+ binop_span,
331+ m,
332+ "try" ,
333+ h ( left_side, right_side) . into_string ( ) ,
334+ applicability,
335+ ) ;
336+ } ) ,
337+ _ => ( ) ,
399338 }
400339 }
401340}
@@ -414,7 +353,7 @@ fn suggest_bool_comparison<'a, 'tcx>(
414353 BOOL_COMPARISON ,
415354 span,
416355 message,
417- "try simplifying it as shown " ,
356+ "try" ,
418357 conv_hint ( hint) . into_string ( ) ,
419358 app,
420359 ) ;
0 commit comments