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
+ } ;
2
4
use crate :: utils:: { SpanlessEq , SpanlessHash } ;
3
5
use rustc:: hir:: * ;
4
6
use rustc:: lint:: { LateContext , LateLintPass , LintArray , LintPass } ;
@@ -165,7 +167,18 @@ fn lint_same_cond(cx: &LateContext<'_, '_>, conds: &[&Expr]) {
165
167
}
166
168
167
169
/// 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
+
169
182
if let ExprKind :: Match ( _, ref arms, MatchSource :: Normal ) = expr. node {
170
183
let hash = |& ( _, arm) : & ( usize , & Arm ) | -> u64 {
171
184
let mut h = SpanlessHash :: new ( cx, cx. tables ) ;
@@ -176,12 +189,13 @@ fn lint_match_arms(cx: &LateContext<'_, '_>, expr: &Expr) {
176
189
let eq = |& ( lindex, lhs) : & ( usize , & Arm ) , & ( rindex, rhs) : & ( usize , & Arm ) | -> bool {
177
190
let min_index = usize:: min ( lindex, rindex) ;
178
191
let max_index = usize:: max ( lindex, rindex) ;
192
+
179
193
// Arms with a guard are ignored, those can’t always be merged together
180
194
// This is also the case for arms in-between each there is an arm with a guard
181
195
( min_index..=max_index) . all ( |index| arms[ index] . guard . is_none ( ) ) &&
182
196
SpanlessEq :: new ( cx) . eq_expr ( & lhs. body , & rhs. body ) &&
183
197
// 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 ] ) )
185
199
} ;
186
200
187
201
let indexed_arms: Vec < ( usize , & Arm ) > = arms. iter ( ) . enumerate ( ) . collect ( ) ;
0 commit comments