1+ use crate :: utils;
12use crate :: utils:: sugg:: Sugg ;
23use crate :: utils:: { match_type, paths, span_lint_and_sugg} ;
34use if_chain:: if_chain;
@@ -89,6 +90,7 @@ struct OptionIfLetElseOccurence {
8990 method_sugg : String ,
9091 some_expr : String ,
9192 none_expr : String ,
93+ wrap_braces : bool ,
9294}
9395
9496struct ReturnBreakContinueVisitor < ' tcx > {
@@ -140,6 +142,7 @@ fn contains_return_break_continue<'tcx>(expression: &'tcx Expr<'tcx>) -> bool {
140142fn detect_option_if_let_else < ' a > ( cx : & LateContext < ' _ , ' a > , expr : & ' a Expr < ' a > ) -> Option < OptionIfLetElseOccurence > {
141143 //(String, String, String, String)> {
142144 if_chain ! {
145+ // if !utils::in_macro(expr.span); // Don't lint macros, because it behaves weirdly
143146 if let ExprKind :: Match ( let_body, arms, MatchSource :: IfLetDesugar { contains_else_clause: true } ) = & expr. kind;
144147 if arms. len( ) == 2 ;
145148 if match_type( cx, & cx. tables. expr_ty( let_body) , & paths:: OPTION ) ;
@@ -170,11 +173,23 @@ fn detect_option_if_let_else<'a>(cx: &LateContext<'_, 'a>, expr: &'a Expr<'a>) -
170173 return None ;
171174 } ;
172175 let capture_name = id. name. to_ident_string( ) ;
176+ let wrap_braces = utils:: get_enclosing_block( cx, expr. hir_id) . map_or( false , |parent| {
177+ if_chain! {
178+ if let Some ( Expr { kind: ExprKind :: Match ( condition, arms, MatchSource :: IfDesugar { contains_else_clause: true } |MatchSource :: IfLetDesugar { contains_else_clause: true } ) , .. } ) = parent. expr;
179+ if expr. hir_id == arms[ 1 ] . body. hir_id;
180+ then {
181+ true
182+ } else {
183+ false
184+ }
185+ }
186+ } ) ;
173187 Some ( OptionIfLetElseOccurence {
174188 option: format!( "{}" , Sugg :: hir( cx, let_body, ".." ) ) ,
175189 method_sugg: format!( "{}" , method_sugg) ,
176190 some_expr: format!( "|{}| {}" , capture_name, Sugg :: hir( cx, some_body, ".." ) ) ,
177- none_expr: format!( "{}{}" , if method_sugg == "map_or" { "" } else { "|| " } , Sugg :: hir( cx, none_body, ".." ) )
191+ none_expr: format!( "{}{}" , if method_sugg == "map_or" { "" } else { "|| " } , Sugg :: hir( cx, none_body, ".." ) ) ,
192+ wrap_braces,
178193 } )
179194 } else {
180195 None
@@ -192,8 +207,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OptionIfLetElse {
192207 format ! ( "use Option::{} instead of an if let/else" , detection. method_sugg) . as_str ( ) ,
193208 "try" ,
194209 format ! (
195- "{}.{}({}, {})" ,
196- detection. option, detection. method_sugg, detection. none_expr, detection. some_expr
210+ "{}{}.{}({}, {}){}" ,
211+ if detection. wrap_braces { "{ " } else { "" } ,
212+ detection. option, detection. method_sugg, detection. none_expr, detection. some_expr,
213+ if detection. wrap_braces { " }" } else { "" } ,
197214 ) ,
198215 Applicability :: MachineApplicable ,
199216 ) ;
0 commit comments