@@ -2,7 +2,7 @@ use crate::utils::visitors::LocalUsedVisitor;
22use crate :: utils:: { span_lint_and_then, SpanlessEq } ;
33use if_chain:: if_chain;
44use 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 } ;
66use rustc_lint:: { LateContext , LateLintPass } ;
77use rustc_middle:: ty:: { DefIdTree , TyCtxt } ;
88use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
@@ -72,8 +72,7 @@ fn check_arm(arm: &Arm<'_>, wild_outer_arm: &Arm<'_>, cx: &LateContext<'_>) {
7272 if arms_inner. iter( ) . all( |arm| arm. guard. is_none( ) ) ;
7373 // match expression must be a local binding
7474 // 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) ;
7776 // one of the branches must be "wild-like"
7877 if let Some ( wild_inner_arm_idx) = arms_inner. iter( ) . rposition( |arm_inner| arm_is_wild_like( arm_inner, cx. tcx) ) ;
7978 let ( wild_inner_arm, non_wild_inner_arm) =
@@ -175,3 +174,20 @@ fn is_none_ctor(res: Res, tcx: TyCtxt<'_>) -> bool {
175174 }
176175 false
177176}
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