@@ -13,6 +13,7 @@ use rustc_hir::LangItem::OptionNone;
1313use rustc_hir:: { Arm , Expr , ExprKind , HirId , Pat , PatExpr , PatExprKind , PatKind } ;
1414use rustc_lint:: LateContext ;
1515use rustc_span:: Span ;
16+ use rustc_span:: symbol:: Ident ;
1617
1718use super :: { COLLAPSIBLE_MATCH , pat_contains_disallowed_or} ;
1819
@@ -50,15 +51,17 @@ fn check_arm<'tcx>(
5051 if let Some ( inner) = IfLetOrMatch :: parse ( cx, inner_expr)
5152 && let Some ( ( inner_scrutinee, inner_then_pat, inner_else_body) ) = match inner {
5253 IfLetOrMatch :: IfLet ( scrutinee, pat, _, els, _) => Some ( ( scrutinee, pat, els) ) ,
53- IfLetOrMatch :: Match ( scrutinee, arms, ..) => if arms. len ( ) == 2 && arms. iter ( ) . all ( |a| a. guard . is_none ( ) )
54- // if there are more than two arms, collapsing would be non-trivial
55- // one of the arms must be "wild-like"
56- && let Some ( wild_idx) = arms. iter ( ) . rposition ( |a| arm_is_wild_like ( cx, a) )
57- {
58- let ( then, els) = ( & arms[ 1 - wild_idx] , & arms[ wild_idx] ) ;
59- Some ( ( scrutinee, then. pat , Some ( els. body ) ) )
60- } else {
61- None
54+ IfLetOrMatch :: Match ( scrutinee, arms, ..) => {
55+ if arms. len ( ) == 2 && arms. iter ( ) . all ( |a| a. guard . is_none ( ) )
56+ // if there are more than two arms, collapsing would be non-trivial
57+ // one of the arms must be "wild-like"
58+ && let Some ( wild_idx) = arms. iter ( ) . rposition ( |a| arm_is_wild_like ( cx, a) )
59+ {
60+ let ( then, els) = ( & arms[ 1 - wild_idx] , & arms[ wild_idx] ) ;
61+ Some ( ( scrutinee, then. pat , Some ( els. body ) ) )
62+ } else {
63+ None
64+ }
6265 } ,
6366 }
6467 && outer_pat. span . eq_ctxt ( inner_scrutinee. span )
@@ -68,18 +71,16 @@ fn check_arm<'tcx>(
6871 && !pat_contains_disallowed_or ( cx, inner_then_pat, msrv)
6972 // the binding must come from the pattern of the containing match arm
7073 // ..<local>.. => match <local> { .. }
71- && let ( Some ( binding_span) , is_innermost_parent_pat_struct)
72- = find_pat_binding_and_is_innermost_parent_pat_struct ( outer_pat, binding_id)
74+ && let ( Some ( ( binding_ident , binding_span) ) , is_innermost_parent_pat_struct) =
75+ find_pat_binding_and_is_innermost_parent_pat_struct ( outer_pat, binding_id)
7376 // the "else" branches must be equal
7477 && match ( outer_else_body, inner_else_body) {
7578 ( None , None ) => true ,
7679 ( None , Some ( e) ) | ( Some ( e) , None ) => is_unit_expr ( e) ,
7780 ( Some ( a) , Some ( b) ) => SpanlessEq :: new ( cx) . eq_expr ( a, b) ,
7881 }
7982 // the binding must not be used in the if guard
80- && outer_guard. is_none_or (
81- |e| !is_local_used ( cx, e, binding_id)
82- )
83+ && outer_guard. is_none_or ( |e| !is_local_used ( cx, e, binding_id) )
8384 // ...or anywhere in the inner expression
8485 && match inner {
8586 IfLetOrMatch :: IfLet ( _, _, body, els, _) => {
@@ -103,7 +104,7 @@ fn check_arm<'tcx>(
103104 // collapsing patterns need an explicit field name in struct pattern matching
104105 // ex: Struct {x: Some(1)}
105106 let replace_msg = if is_innermost_parent_pat_struct {
106- format ! ( ", prefixed by `{}`:" , snippet ( cx , binding_span , "their field name" ) )
107+ format ! ( ", prefixed by `{binding_ident}: `" )
107108 } else {
108109 String :: new ( )
109110 } ;
@@ -140,16 +141,16 @@ fn arm_is_wild_like(cx: &LateContext<'_>, arm: &Arm<'_>) -> bool {
140141 }
141142}
142143
143- fn find_pat_binding_and_is_innermost_parent_pat_struct ( pat : & Pat < ' _ > , hir_id : HirId ) -> ( Option < Span > , bool ) {
144- let mut span = None ;
144+ fn find_pat_binding_and_is_innermost_parent_pat_struct ( pat : & Pat < ' _ > , hir_id : HirId ) -> ( Option < ( Ident , Span ) > , bool ) {
145+ let mut binding = None ;
145146 let mut is_innermost_parent_pat_struct = false ;
146- pat. walk_short ( |p| match & p. kind {
147+ pat. walk_short ( |p| match p. kind {
147148 // ignore OR patterns
148149 PatKind :: Or ( _) => false ,
149- PatKind :: Binding ( _bm, _, _ident , _) => {
150+ PatKind :: Binding ( _bm, _, ident , _) => {
150151 let found = p. hir_id == hir_id;
151152 if found {
152- span = Some ( p. span ) ;
153+ binding = Some ( ( ident , p. span ) ) ;
153154 }
154155 !found
155156 } ,
@@ -158,7 +159,7 @@ fn find_pat_binding_and_is_innermost_parent_pat_struct(pat: &Pat<'_>, hir_id: Hi
158159 true
159160 } ,
160161 } ) ;
161- ( span , is_innermost_parent_pat_struct)
162+ ( binding , is_innermost_parent_pat_struct)
162163}
163164
164165/// Builds a chain of reference-manipulation method calls (e.g., `.as_ref()`, `.as_mut()`,
0 commit comments