@@ -140,6 +140,23 @@ 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 ;
147
+ }
148
+
149
+ 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 ( |info| in_candidate_enum ( cx, info) ) {
155
+ report_single_pattern ( cx, ex, arms, expr, els) ;
156
+ }
157
+ }
158
+
159
+ fn in_candidate_enum < ' a > ( cx : & LateContext < ' a > , path_info : & ( String , Ty < ' _ > ) ) -> bool {
143
160
// list of candidate `Enum`s we know will never get any more members
144
161
let candidates = & [
145
162
( & paths:: COW , "Borrowed" ) ,
@@ -151,29 +168,13 @@ fn check_opt_like<'a>(
151
168
( & paths:: RESULT , "Ok" ) ,
152
169
] ;
153
170
154
- // We want to suggest to exclude an arm that contains only wildcards or forms the exhaustive
155
- // match with the second branch, without enum variants in matches.
156
- if !contains_only_wilds ( arms[ 1 ] . pat ) && !form_exhaustive_matches ( arms[ 0 ] . pat , arms[ 1 ] . pat ) {
157
- return ;
158
- }
159
-
160
- let mut paths_and_types = Vec :: new ( ) ;
161
- if !collect_pat_paths ( & mut paths_and_types, cx, arms[ 1 ] . pat , ty) {
162
- return ;
163
- }
164
-
165
- let in_candidate_enum = |path_info : & ( String , Ty < ' _ > ) | -> bool {
166
- let ( path, ty) = path_info;
167
- for & ( ty_path, pat_path) in candidates {
168
- if path == pat_path && match_type ( cx, * ty, ty_path) {
169
- return true ;
170
- }
171
+ let ( path, ty) = path_info;
172
+ for & ( ty_path, pat_path) in candidates {
173
+ if path == pat_path && match_type ( cx, * ty, ty_path) {
174
+ return true ;
171
175
}
172
- false
173
- } ;
174
- if paths_and_types. iter ( ) . all ( in_candidate_enum) {
175
- report_single_pattern ( cx, ex, arms, expr, els) ;
176
176
}
177
+ false
177
178
}
178
179
179
180
/// Collects paths and their types from the given patterns. Returns true if the given pattern could
@@ -218,7 +219,7 @@ fn contains_only_wilds(pat: &Pat<'_>) -> bool {
218
219
219
220
/// Returns true if the given patterns forms only exhaustive matches that don't contain enum
220
221
/// patterns without a wildcard.
221
- fn form_exhaustive_matches ( left : & Pat < ' _ > , right : & Pat < ' _ > ) -> bool {
222
+ fn form_exhaustive_matches < ' a > ( cx : & LateContext < ' a > , ty : Ty < ' a > , left : & Pat < ' _ > , right : & Pat < ' _ > ) -> bool {
222
223
match ( & left. kind , & right. kind ) {
223
224
( PatKind :: Wild , _) | ( _, PatKind :: Wild ) => true ,
224
225
( PatKind :: Tuple ( left_in, left_pos) , PatKind :: Tuple ( right_in, right_pos) ) => {
@@ -264,6 +265,14 @@ fn form_exhaustive_matches(left: &Pat<'_>, right: &Pat<'_>) -> bool {
264
265
}
265
266
true
266
267
} ,
268
+ ( PatKind :: TupleStruct ( ..) , PatKind :: Path ( _) | PatKind :: TupleStruct ( ..) ) => {
269
+ let mut paths_and_types = Vec :: new ( ) ;
270
+ if !collect_pat_paths ( & mut paths_and_types, cx, right, ty) {
271
+ return false ;
272
+ }
273
+
274
+ paths_and_types. iter ( ) . all ( |info| in_candidate_enum ( cx, info) )
275
+ } ,
267
276
_ => false ,
268
277
}
269
278
}
0 commit comments