1
1
use clippy_utils:: diagnostics:: span_lint_and_help;
2
+ use clippy_utils:: eager_or_lazy:: switch_to_eager_eval;
2
3
use clippy_utils:: source:: snippet_with_macro_callsite;
3
4
use clippy_utils:: { contains_return, higher, is_else_clause, is_lang_ctor, meets_msrv, msrvs, peel_blocks} ;
4
- use if_chain:: if_chain;
5
5
use rustc_hir:: LangItem :: { OptionNone , OptionSome } ;
6
6
use rustc_hir:: { Expr , ExprKind , Stmt , StmtKind } ;
7
7
use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
@@ -56,7 +56,7 @@ impl IfThenSomeElseNone {
56
56
impl_lint_pass ! ( IfThenSomeElseNone => [ IF_THEN_SOME_ELSE_NONE ] ) ;
57
57
58
58
impl < ' tcx > LateLintPass < ' tcx > for IfThenSomeElseNone {
59
- fn check_expr ( & mut self , cx : & LateContext < ' _ > , expr : & ' tcx Expr < ' _ > ) {
59
+ fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' tcx > ) {
60
60
if !meets_msrv ( self . msrv , msrvs:: BOOL_THEN ) {
61
61
return ;
62
62
}
@@ -70,43 +70,47 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
70
70
return ;
71
71
}
72
72
73
- if_chain ! {
74
- if let Some ( higher:: If { cond, then, r#else: Some ( els) } ) = higher:: If :: hir( expr) ;
75
- if let ExprKind :: Block ( then_block, _) = then. kind;
76
- if let Some ( then_expr) = then_block. expr;
77
- if let ExprKind :: Call ( then_call, [ then_arg] ) = then_expr. kind;
78
- if let ExprKind :: Path ( ref then_call_qpath) = then_call. kind;
79
- if is_lang_ctor( cx, then_call_qpath, OptionSome ) ;
80
- if let ExprKind :: Path ( ref qpath) = peel_blocks( els) . kind;
81
- if is_lang_ctor( cx, qpath, OptionNone ) ;
82
- if !stmts_contains_early_return( then_block. stmts) ;
83
- then {
84
- let cond_snip = snippet_with_macro_callsite( cx, cond. span, "[condition]" ) ;
85
- let cond_snip = if matches!( cond. kind, ExprKind :: Unary ( _, _) | ExprKind :: Binary ( _, _, _) ) {
86
- format!( "({})" , cond_snip)
87
- } else {
88
- cond_snip. into_owned( )
89
- } ;
90
- let arg_snip = snippet_with_macro_callsite( cx, then_arg. span, "" ) ;
91
- let closure_body = if then_block. stmts. is_empty( ) {
92
- arg_snip. into_owned( )
93
- } else {
94
- format!( "{{ /* snippet */ {} }}" , arg_snip)
95
- } ;
96
- let help = format!(
97
- "consider using `bool::then` like: `{}.then(|| {})`" ,
98
- cond_snip,
99
- closure_body,
100
- ) ;
101
- span_lint_and_help(
102
- cx,
103
- IF_THEN_SOME_ELSE_NONE ,
104
- expr. span,
105
- "this could be simplified with `bool::then`" ,
106
- None ,
107
- & help,
108
- ) ;
109
- }
73
+ if let Some ( higher:: If { cond, then, r#else : Some ( els) } ) = higher:: If :: hir ( expr)
74
+ && let ExprKind :: Block ( then_block, _) = then. kind
75
+ && let Some ( then_expr) = then_block. expr
76
+ && let ExprKind :: Call ( then_call, [ then_arg] ) = then_expr. kind
77
+ && let ExprKind :: Path ( ref then_call_qpath) = then_call. kind
78
+ && is_lang_ctor ( cx, then_call_qpath, OptionSome )
79
+ && let ExprKind :: Path ( ref qpath) = peel_blocks ( els) . kind
80
+ && is_lang_ctor ( cx, qpath, OptionNone )
81
+ && !stmts_contains_early_return ( then_block. stmts )
82
+ {
83
+ let cond_snip = snippet_with_macro_callsite ( cx, cond. span , "[condition]" ) ;
84
+ let cond_snip = if matches ! ( cond. kind, ExprKind :: Unary ( _, _) | ExprKind :: Binary ( _, _, _) ) {
85
+ format ! ( "({})" , cond_snip)
86
+ } else {
87
+ cond_snip. into_owned ( )
88
+ } ;
89
+ let arg_snip = snippet_with_macro_callsite ( cx, then_arg. span , "" ) ;
90
+ let mut method_body = if then_block. stmts . is_empty ( ) {
91
+ arg_snip. into_owned ( )
92
+ } else {
93
+ format ! ( "{{ /* snippet */ {} }}" , arg_snip)
94
+ } ;
95
+ let method_name = if switch_to_eager_eval ( cx, expr) && meets_msrv ( self . msrv , msrvs:: BOOL_THEN_SOME ) {
96
+ "then_some"
97
+ } else {
98
+ method_body. insert_str ( 0 , "|| " ) ;
99
+ "then"
100
+ } ;
101
+
102
+ let help = format ! (
103
+ "consider using `bool::{}` like: `{}.{}({})`" ,
104
+ method_name, cond_snip, method_name, method_body,
105
+ ) ;
106
+ span_lint_and_help (
107
+ cx,
108
+ IF_THEN_SOME_ELSE_NONE ,
109
+ expr. span ,
110
+ & format ! ( "this could be simplified with `bool::{}`" , method_name) ,
111
+ None ,
112
+ & help,
113
+ ) ;
110
114
}
111
115
}
112
116
0 commit comments