1- use crate :: utils:: { get_parent_expr, higher, in_macro_or_desugar, snippet, span_lint_and_then, span_note_and_lint} ;
1+ use crate :: utils:: {
2+ get_parent_expr, higher, in_macro_or_desugar, same_tys, snippet, span_lint_and_then, span_note_and_lint,
3+ } ;
24use crate :: utils:: { SpanlessEq , SpanlessHash } ;
35use rustc:: hir:: * ;
46use rustc:: lint:: { LateContext , LateLintPass , LintArray , LintPass } ;
@@ -165,7 +167,18 @@ fn lint_same_cond(cx: &LateContext<'_, '_>, conds: &[&Expr]) {
165167}
166168
167169/// Implementation of `MATCH_SAME_ARMS`.
168- fn lint_match_arms ( cx : & LateContext < ' _ , ' _ > , expr : & Expr ) {
170+ fn lint_match_arms < ' tcx > ( cx : & LateContext < ' _ , ' tcx > , expr : & Expr ) {
171+ fn same_bindings < ' tcx > (
172+ cx : & LateContext < ' _ , ' tcx > ,
173+ lhs : & FxHashMap < LocalInternedString , Ty < ' tcx > > ,
174+ rhs : & FxHashMap < LocalInternedString , Ty < ' tcx > > ,
175+ ) -> bool {
176+ lhs. len ( ) == rhs. len ( )
177+ && lhs
178+ . iter ( )
179+ . all ( |( name, l_ty) | rhs. get ( name) . map_or ( false , |r_ty| same_tys ( cx, l_ty, r_ty) ) )
180+ }
181+
169182 if let ExprKind :: Match ( _, ref arms, MatchSource :: Normal ) = expr. node {
170183 let hash = |& ( _, arm) : & ( usize , & Arm ) | -> u64 {
171184 let mut h = SpanlessHash :: new ( cx, cx. tables ) ;
@@ -176,12 +189,13 @@ fn lint_match_arms(cx: &LateContext<'_, '_>, expr: &Expr) {
176189 let eq = |& ( lindex, lhs) : & ( usize , & Arm ) , & ( rindex, rhs) : & ( usize , & Arm ) | -> bool {
177190 let min_index = usize:: min ( lindex, rindex) ;
178191 let max_index = usize:: max ( lindex, rindex) ;
192+
179193 // Arms with a guard are ignored, those can’t always be merged together
180194 // This is also the case for arms in-between each there is an arm with a guard
181195 ( min_index..=max_index) . all ( |index| arms[ index] . guard . is_none ( ) ) &&
182196 SpanlessEq :: new ( cx) . eq_expr ( & lhs. body , & rhs. body ) &&
183197 // all patterns should have the same bindings
184- bindings ( cx, & lhs. pats [ 0 ] ) == bindings ( cx, & rhs. pats [ 0 ] )
198+ same_bindings ( cx , & bindings ( cx, & lhs. pats [ 0 ] ) , & bindings ( cx, & rhs. pats [ 0 ] ) )
185199 } ;
186200
187201 let indexed_arms: Vec < ( usize , & Arm ) > = arms. iter ( ) . enumerate ( ) . collect ( ) ;
0 commit comments