@@ -2,7 +2,7 @@ use crate::utils::visitors::LocalUsedVisitor;
2
2
use crate :: utils:: { span_lint_and_then, SpanlessEq } ;
3
3
use if_chain:: if_chain;
4
4
use rustc_hir:: def:: { CtorKind , CtorOf , DefKind , Res } ;
5
- use rustc_hir:: { Arm , Expr , ExprKind , Guard , HirId , Pat , PatKind , QPath , StmtKind } ;
5
+ use rustc_hir:: { Arm , Expr , ExprKind , Guard , HirId , Pat , PatKind , QPath , StmtKind , UnOp } ;
6
6
use rustc_lint:: { LateContext , LateLintPass } ;
7
7
use rustc_middle:: ty:: { DefIdTree , TyCtxt } ;
8
8
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
@@ -72,8 +72,7 @@ fn check_arm(arm: &Arm<'_>, wild_outer_arm: &Arm<'_>, cx: &LateContext<'_>) {
72
72
if arms_inner. iter( ) . all( |arm| arm. guard. is_none( ) ) ;
73
73
// match expression must be a local binding
74
74
// match <local> { .. }
75
- if let ExprKind :: Path ( QPath :: Resolved ( None , path) ) = expr_in. kind;
76
- if let Res :: Local ( binding_id) = path. res;
75
+ if let Some ( binding_id) = addr_adjusted_binding( expr_in, cx) ;
77
76
// one of the branches must be "wild-like"
78
77
if let Some ( wild_inner_arm_idx) = arms_inner. iter( ) . rposition( |arm_inner| arm_is_wild_like( arm_inner, cx. tcx) ) ;
79
78
let ( wild_inner_arm, non_wild_inner_arm) =
@@ -175,3 +174,20 @@ fn is_none_ctor(res: Res, tcx: TyCtxt<'_>) -> bool {
175
174
}
176
175
false
177
176
}
177
+
178
+ /// Retrieves a binding ID with optional `&` and/or `*` operators removed. (e.g. `&**foo`)
179
+ /// Returns `None` if a non-reference type is de-referenced.
180
+ /// For example, if `Vec` is de-referenced to a slice, `None` is returned.
181
+ fn addr_adjusted_binding ( mut expr : & Expr < ' _ > , cx : & LateContext < ' _ > ) -> Option < HirId > {
182
+ loop {
183
+ match expr. kind {
184
+ ExprKind :: AddrOf ( _, _, e) => expr = e,
185
+ ExprKind :: Path ( QPath :: Resolved ( None , path) ) => match path. res {
186
+ Res :: Local ( binding_id) => break Some ( binding_id) ,
187
+ _ => break None ,
188
+ } ,
189
+ ExprKind :: Unary ( UnOp :: UnDeref , e) if cx. typeck_results ( ) . expr_ty ( e) . is_ref ( ) => expr = e,
190
+ _ => break None ,
191
+ }
192
+ }
193
+ }
0 commit comments