1- use rustc_ast:: { ExprPrecedence , LitKind } ;
1+ use rustc_ast:: LitKind ;
22use rustc_hir:: { Block , ExprKind } ;
33use rustc_lint:: { LateContext , LateLintPass } ;
44use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
55
6- use clippy_utils:: { diagnostics:: span_lint_and_then, is_else_clause, source :: snippet_block_with_applicability } ;
6+ use clippy_utils:: { diagnostics:: span_lint_and_then, is_else_clause, sugg :: Sugg } ;
77use rustc_errors:: Applicability ;
88
99declare_clippy_lint ! {
@@ -55,27 +55,42 @@ fn check_if_else<'tcx>(ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx
5555 if let ExprKind :: If ( check, then, Some ( else_) ) = expr. kind
5656 && let Some ( then_lit) = int_literal ( then)
5757 && let Some ( else_lit) = int_literal ( else_)
58- && check_int_literal_equals_val ( then_lit, 1 )
59- && check_int_literal_equals_val ( else_lit, 0 )
6058 {
59+ let inverted = if
60+ check_int_literal_equals_val ( then_lit, 1 )
61+ && check_int_literal_equals_val ( else_lit, 0 ) {
62+ false
63+ } else if
64+ check_int_literal_equals_val ( then_lit, 0 )
65+ && check_int_literal_equals_val ( else_lit, 1 ) {
66+ true
67+ } else {
68+ // Expression isn't boolean, exit
69+ return ;
70+ } ;
6171 let mut applicability = Applicability :: MachineApplicable ;
62- let snippet = snippet_block_with_applicability ( ctx, check. span , ".." , None , & mut applicability) ;
63- let snippet_with_braces = {
64- let need_parens = should_have_parentheses ( check) ;
65- let ( left_paren, right_paren) = if need_parens { ( "(" , ")" ) } else { ( "" , "" ) } ;
66- format ! ( "{left_paren}{snippet}{right_paren}" )
72+ let snippet = {
73+ let mut sugg = Sugg :: hir_with_applicability ( ctx, check, ".." , & mut applicability) ;
74+ if inverted {
75+ sugg = !sugg;
76+ }
77+ sugg
6778 } ;
6879
6980 let ty = ctx. typeck_results ( ) . expr_ty ( then_lit) ; // then and else must be of same type
7081
7182 let suggestion = {
7283 let wrap_in_curly = is_else_clause ( ctx. tcx , expr) ;
73- let ( left_curly, right_curly) = if wrap_in_curly { ( "{" , "}" ) } else { ( "" , "" ) } ;
74- format ! (
75- "{left_curly}{ty}::from({snippet}){right_curly}"
76- )
84+ let mut s = Sugg :: NonParen ( format ! ( "{ty}::from({snippet})" ) . into ( ) ) ;
85+ if wrap_in_curly {
86+ s = s. blockify ( ) ;
87+ }
88+ s
7789 } ; // when used in else clause if statement should be wrapped in curly braces
7890
91+ let into_snippet = snippet. clone ( ) . maybe_par ( ) ;
92+ let as_snippet = snippet. as_ty ( ty) ;
93+
7994 span_lint_and_then ( ctx,
8095 BOOL_TO_INT_WITH_IF ,
8196 expr. span ,
@@ -87,7 +102,7 @@ fn check_if_else<'tcx>(ctx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx
87102 suggestion,
88103 applicability,
89104 ) ;
90- diag. note ( format ! ( "`{snippet_with_braces} as {ty} ` or `{snippet_with_braces }.into()` can also be valid options" ) ) ;
105+ diag. note ( format ! ( "`{as_snippet} ` or `{into_snippet }.into()` can also be valid options" ) ) ;
91106 } ) ;
92107 } ;
93108}
@@ -119,7 +134,3 @@ fn check_int_literal_equals_val<'tcx>(expr: &'tcx rustc_hir::Expr<'tcx>, expecte
119134 false
120135 }
121136}
122-
123- fn should_have_parentheses < ' tcx > ( check : & ' tcx rustc_hir:: Expr < ' tcx > ) -> bool {
124- check. precedence ( ) . order ( ) < ExprPrecedence :: Cast . order ( )
125- }
0 commit comments