@@ -140,22 +140,20 @@ fn check_opt_like<'a>(
140
140
ty : Ty < ' a > ,
141
141
els : Option < & Expr < ' _ > > ,
142
142
) {
143
- // We want to suggest to exclude an arm that contains only wildcards or forms the exhaustive
144
- // match with the second branch, without enum variants in matches .
145
- if ! contains_only_wilds ( arms [ 1 ] . pat ) && ! form_exhaustive_matches ( cx, ty, arms[ 0 ] . pat , arms[ 1 ] . pat ) {
146
- return ;
143
+ // We don't want to lint if the second arm contains an enum which could
144
+ // have more variants in the future .
145
+ if form_exhaustive_matches ( cx, ty, arms[ 0 ] . pat , arms[ 1 ] . pat ) {
146
+ report_single_pattern ( cx , ex , arms , expr , els ) ;
147
147
}
148
+ }
148
149
150
+ fn pat_in_candidate_enum < ' a > ( cx : & LateContext < ' a > , ty : Ty < ' a > , pat : & Pat < ' _ > ) -> bool {
149
151
let mut paths_and_types = Vec :: new ( ) ;
150
- if !collect_pat_paths ( & mut paths_and_types, cx, arms[ 1 ] . pat , ty) {
151
- return ;
152
- }
153
-
154
- if paths_and_types. iter ( ) . all ( |ty| in_candidate_enum ( cx, * ty) ) {
155
- report_single_pattern ( cx, ex, arms, expr, els) ;
156
- }
152
+ collect_pat_paths ( & mut paths_and_types, cx, pat, ty) ;
153
+ paths_and_types. iter ( ) . all ( |ty| in_candidate_enum ( cx, * ty) )
157
154
}
158
155
156
+ /// Returns `true` if the given type is an enum we know won't be expanded in the future
159
157
fn in_candidate_enum < ' a > ( cx : & LateContext < ' a > , ty : Ty < ' _ > ) -> bool {
160
158
// list of candidate `Enum`s we know will never get any more members
161
159
let candidates = [ & paths:: COW , & paths:: OPTION , & paths:: RESULT ] ;
@@ -168,20 +166,17 @@ fn in_candidate_enum<'a>(cx: &LateContext<'a>, ty: Ty<'_>) -> bool {
168
166
false
169
167
}
170
168
171
- /// Collects paths and their types from the given patterns. Returns true if the given pattern could
172
- /// be simplified, false otherwise.
173
- fn collect_pat_paths < ' a > ( acc : & mut Vec < Ty < ' a > > , cx : & LateContext < ' a > , pat : & Pat < ' _ > , ty : Ty < ' a > ) -> bool {
169
+ /// Collects paths and their types from the given patterns
170
+ fn collect_pat_paths < ' a > ( acc : & mut Vec < Ty < ' a > > , cx : & LateContext < ' a > , pat : & Pat < ' _ > , ty : Ty < ' a > ) {
174
171
match pat. kind {
175
- PatKind :: Wild => true ,
176
- PatKind :: Tuple ( inner, _) => inner. iter ( ) . all ( |p| {
172
+ PatKind :: Tuple ( inner, _) => inner. iter ( ) . for_each ( |p| {
177
173
let p_ty = cx. typeck_results ( ) . pat_ty ( p) ;
178
- collect_pat_paths ( acc, cx, p, p_ty)
174
+ collect_pat_paths ( acc, cx, p, p_ty) ;
179
175
} ) ,
180
176
PatKind :: TupleStruct ( ..) | PatKind :: Binding ( BindingAnnotation :: Unannotated , .., None ) | PatKind :: Path ( _) => {
181
177
acc. push ( ty) ;
182
- true
183
178
} ,
184
- _ => false ,
179
+ _ => { } ,
185
180
}
186
181
}
187
182
@@ -242,9 +237,9 @@ fn form_exhaustive_matches<'a>(cx: &LateContext<'a>, ty: Ty<'a>, left: &Pat<'_>,
242
237
}
243
238
true
244
239
} ,
245
- ( PatKind :: TupleStruct ( ..) , PatKind :: Path ( _) ) => in_candidate_enum ( cx, ty) ,
240
+ ( PatKind :: TupleStruct ( ..) , PatKind :: Path ( _) ) => pat_in_candidate_enum ( cx, ty, right ) ,
246
241
( PatKind :: TupleStruct ( ..) , PatKind :: TupleStruct ( _, inner, _) ) => {
247
- in_candidate_enum ( cx, ty) && inner. iter ( ) . all ( contains_only_wilds)
242
+ pat_in_candidate_enum ( cx, ty, right ) && inner. iter ( ) . all ( contains_only_wilds)
248
243
} ,
249
244
_ => false ,
250
245
}
0 commit comments