@@ -140,22 +140,20 @@ fn check_opt_like<'a>(
140140 ty : Ty < ' a > ,
141141 els : Option < & Expr < ' _ > > ,
142142) {
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 ) ;
147147 }
148+ }
148149
150+ fn pat_in_candidate_enum < ' a > ( cx : & LateContext < ' a > , ty : Ty < ' a > , pat : & Pat < ' _ > ) -> bool {
149151 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) )
157154}
158155
156+ /// Returns `true` if the given type is an enum we know won't be expanded in the future
159157fn in_candidate_enum < ' a > ( cx : & LateContext < ' a > , ty : Ty < ' _ > ) -> bool {
160158 // list of candidate `Enum`s we know will never get any more members
161159 let candidates = [ & paths:: COW , & paths:: OPTION , & paths:: RESULT ] ;
@@ -168,20 +166,17 @@ fn in_candidate_enum<'a>(cx: &LateContext<'a>, ty: Ty<'_>) -> bool {
168166 false
169167}
170168
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 > ) {
174171 match pat. kind {
175- PatKind :: Wild => true ,
176- PatKind :: Tuple ( inner, _) => inner. iter ( ) . all ( |p| {
172+ PatKind :: Tuple ( inner, _) => inner. iter ( ) . for_each ( |p| {
177173 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) ;
179175 } ) ,
180176 PatKind :: TupleStruct ( ..) | PatKind :: Binding ( BindingAnnotation :: Unannotated , .., None ) | PatKind :: Path ( _) => {
181177 acc. push ( ty) ;
182- true
183178 } ,
184- _ => false ,
179+ _ => { } ,
185180 }
186181}
187182
@@ -242,9 +237,9 @@ fn form_exhaustive_matches<'a>(cx: &LateContext<'a>, ty: Ty<'a>, left: &Pat<'_>,
242237 }
243238 true
244239 } ,
245- ( PatKind :: TupleStruct ( ..) , PatKind :: Path ( _) ) => in_candidate_enum ( cx, ty) ,
240+ ( PatKind :: TupleStruct ( ..) , PatKind :: Path ( _) ) => pat_in_candidate_enum ( cx, ty, right ) ,
246241 ( 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)
248243 } ,
249244 _ => false ,
250245 }
0 commit comments