@@ -5,7 +5,7 @@ use clippy_utils::diagnostics::{
55use clippy_utils:: macros:: { is_panic, root_macro_call} ;
66use clippy_utils:: source:: { expr_block, indent_of, snippet, snippet_block, snippet_opt, snippet_with_applicability} ;
77use clippy_utils:: sugg:: Sugg ;
8- use clippy_utils:: ty:: { implements_trait, is_type_diagnostic_item, peel_mid_ty_refs} ;
8+ use clippy_utils:: ty:: { implements_trait, is_type_diagnostic_item, match_type , peel_mid_ty_refs} ;
99use clippy_utils:: visitors:: is_local_used;
1010use clippy_utils:: {
1111 get_parent_expr, is_lang_ctor, is_lint_allowed, is_refutable, is_unit_expr, is_wild, meets_msrv, msrvs,
@@ -741,7 +741,7 @@ fn check_single_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], exp
741741 let ty = cx. typeck_results ( ) . expr_ty ( ex) ;
742742 if * ty. kind ( ) != ty:: Bool || is_lint_allowed ( cx, MATCH_BOOL , ex. hir_id ) {
743743 check_single_match_single_pattern ( cx, ex, arms, expr, els) ;
744- check_single_match_opt_like ( cx, ex, arms, expr, els) ;
744+ check_single_match_opt_like ( cx, ex, arms, expr, ty , els) ;
745745 }
746746 }
747747}
@@ -830,11 +830,12 @@ fn report_single_match_single_pattern(
830830 ) ;
831831}
832832
833- fn check_single_match_opt_like (
834- cx : & LateContext < ' _ > ,
833+ fn check_single_match_opt_like < ' a > (
834+ cx : & LateContext < ' a > ,
835835 ex : & Expr < ' _ > ,
836836 arms : & [ Arm < ' _ > ] ,
837837 expr : & Expr < ' _ > ,
838+ ty : Ty < ' a > ,
838839 els : Option < & Expr < ' _ > > ,
839840) {
840841 // list of candidate `Enum`s we know will never get any more members
@@ -854,44 +855,50 @@ fn check_single_match_opt_like(
854855 return ;
855856 }
856857
857- let mut paths = Vec :: new ( ) ;
858- if !collect_pat_paths ( & mut paths , arms[ 1 ] . pat ) {
858+ let mut paths_and_types = Vec :: new ( ) ;
859+ if !collect_pat_paths ( & mut paths_and_types , cx , arms[ 1 ] . pat , ty ) {
859860 return ;
860861 }
861862
862- let in_candidate_enum = |path : & String | -> bool {
863- for & ( _, pat_path) in candidates {
864- if path == pat_path {
863+ let in_candidate_enum = |path_info : & ( String , & TyS < ' _ > ) | -> bool {
864+ let ( path, ty) = path_info;
865+ for & ( ty_path, pat_path) in candidates {
866+ if path == pat_path && match_type ( cx, ty, ty_path) {
865867 return true ;
866868 }
867869 }
868870 false
869871 } ;
870- if paths . iter ( ) . all ( in_candidate_enum) {
872+ if paths_and_types . iter ( ) . all ( in_candidate_enum) {
871873 report_single_match_single_pattern ( cx, ex, arms, expr, els) ;
872874 }
873875}
874876
875- /// Collects paths from the given paths . Returns true if the given pattern could be simplified,
876- /// false otherwise.
877- fn collect_pat_paths ( acc : & mut Vec < String > , pat : & Pat < ' _ > ) -> bool {
877+ /// Collects paths and their types from the given patterns . Returns true if the given pattern could
878+ /// be simplified, false otherwise.
879+ fn collect_pat_paths < ' a > ( acc : & mut Vec < ( String , Ty < ' a > ) > , cx : & LateContext < ' a > , pat : & Pat < ' _ > , ty : Ty < ' a > ) -> bool {
878880 match pat. kind {
879881 PatKind :: Wild => true ,
880- PatKind :: Tuple ( inner, _) => inner. iter ( ) . all ( |p| collect_pat_paths ( acc, p) ) ,
882+ PatKind :: Tuple ( inner, _) => inner. iter ( ) . all ( |p| {
883+ let p_ty = cx. typeck_results ( ) . pat_ty ( p) ;
884+ collect_pat_paths ( acc, cx, p, p_ty)
885+ } ) ,
881886 PatKind :: TupleStruct ( ref path, ..) => {
882- acc . push ( rustc_hir_pretty:: to_string ( rustc_hir_pretty:: NO_ANN , |s| {
887+ let path = rustc_hir_pretty:: to_string ( rustc_hir_pretty:: NO_ANN , |s| {
883888 s. print_qpath ( path, false ) ;
884- } ) ) ;
889+ } ) ;
890+ acc. push ( ( path, ty) ) ;
885891 true
886892 } ,
887893 PatKind :: Binding ( BindingAnnotation :: Unannotated , .., ident, None ) => {
888- acc. push ( ident. to_string ( ) ) ;
894+ acc. push ( ( ident. to_string ( ) , ty ) ) ;
889895 true
890896 } ,
891897 PatKind :: Path ( ref path) => {
892- acc . push ( rustc_hir_pretty:: to_string ( rustc_hir_pretty:: NO_ANN , |s| {
898+ let path = rustc_hir_pretty:: to_string ( rustc_hir_pretty:: NO_ANN , |s| {
893899 s. print_qpath ( path, false ) ;
894- } ) ) ;
900+ } ) ;
901+ acc. push ( ( path, ty) ) ;
895902 true
896903 } ,
897904 _ => false ,
0 commit comments