@@ -12,7 +12,7 @@ use rustc_errors::Applicability;
12
12
use rustc_hir:: {
13
13
def:: Res ,
14
14
intravisit:: { walk_expr, ErasedMap , NestedVisitorMap , Visitor } ,
15
- Arm , BindingAnnotation , Block , Expr , ExprKind , Mutability , Pat , PatKind , Path , QPath ,
15
+ Arm , BindingAnnotation , Block , Expr , ExprKind , MatchSource , Mutability , Node , Pat , PatKind , Path , QPath ,
16
16
} ;
17
17
use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
18
18
use rustc_middle:: lint:: in_external_macro;
@@ -55,8 +55,11 @@ impl LateLintPass<'_> for ManualMap {
55
55
return ;
56
56
}
57
57
58
- if let ExprKind :: Match ( scrutinee, [ arm1 @ Arm { guard : None , .. } , arm2 @ Arm { guard : None , .. } ] , _) =
59
- expr. kind
58
+ if let ExprKind :: Match (
59
+ scrutinee,
60
+ [ arm1 @ Arm { guard : None , .. } , arm2 @ Arm { guard : None , .. } ] ,
61
+ match_kind,
62
+ ) = expr. kind
60
63
{
61
64
let ( scrutinee_ty, ty_ref_count, ty_mutability) =
62
65
peel_mid_ty_refs_is_mutable ( cx. typeck_results ( ) . expr_ty ( scrutinee) ) ;
@@ -182,13 +185,36 @@ impl LateLintPass<'_> for ManualMap {
182
185
expr. span ,
183
186
"manual implementation of `Option::map`" ,
184
187
"try this" ,
185
- format ! ( "{}{}.map({})" , scrutinee_str, as_ref_str, body_str) ,
188
+ if matches ! ( match_kind, MatchSource :: IfLetDesugar { .. } ) && is_else_of_if_let_else ( cx, expr) {
189
+ format ! ( "{{ {}{}.map({}) }}" , scrutinee_str, as_ref_str, body_str)
190
+ } else {
191
+ format ! ( "{}{}.map({})" , scrutinee_str, as_ref_str, body_str)
192
+ } ,
186
193
app,
187
194
) ;
188
195
}
189
196
}
190
197
}
191
198
199
+ fn is_else_of_if_let_else ( cx : & LateContext < ' _ > , expr : & Expr < ' _ > ) -> bool {
200
+ let map = cx. tcx . hir ( ) ;
201
+ let mut iter = map. parent_iter ( expr. hir_id ) ;
202
+ let arm_id = match iter. next ( ) {
203
+ Some ( ( id, Node :: Arm ( ..) ) ) => id,
204
+ _ => return false ,
205
+ } ;
206
+ match iter. next ( ) {
207
+ Some ( (
208
+ _,
209
+ Node :: Expr ( Expr {
210
+ kind : ExprKind :: Match ( _, [ _, else_arm] , kind) ,
211
+ ..
212
+ } ) ,
213
+ ) ) => else_arm. hir_id == arm_id && matches ! ( kind, MatchSource :: IfLetDesugar { .. } ) ,
214
+ _ => false ,
215
+ }
216
+ }
217
+
192
218
// Checks if the expression can be moved into a closure as is.
193
219
fn can_move_expr_to_closure ( cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > ) -> bool {
194
220
struct V < ' cx , ' tcx > {
0 commit comments