11use clippy_utils:: diagnostics:: span_lint_and_help;
2+ use clippy_utils:: eager_or_lazy:: switch_to_eager_eval;
23use clippy_utils:: source:: snippet_with_macro_callsite;
34use clippy_utils:: { contains_return, higher, is_else_clause, is_lang_ctor, meets_msrv, msrvs, peel_blocks} ;
4- use if_chain:: if_chain;
55use rustc_hir:: LangItem :: { OptionNone , OptionSome } ;
66use rustc_hir:: { Expr , ExprKind , Stmt , StmtKind } ;
77use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
@@ -56,7 +56,7 @@ impl IfThenSomeElseNone {
5656impl_lint_pass ! ( IfThenSomeElseNone => [ IF_THEN_SOME_ELSE_NONE ] ) ;
5757
5858impl < ' 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 > ) {
6060 if !meets_msrv ( self . msrv , msrvs:: BOOL_THEN ) {
6161 return ;
6262 }
@@ -70,43 +70,47 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
7070 return ;
7171 }
7272
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+ ) ;
110114 }
111115 }
112116
0 commit comments