1- use clippy_utils:: diagnostics:: { multispan_sugg, span_lint_and_help, span_lint_and_sugg, span_lint_and_then} ;
2- use clippy_utils:: source:: { snippet, snippet_with_applicability} ;
3- use clippy_utils:: sugg:: Sugg ;
1+ use clippy_utils:: diagnostics:: { span_lint_and_help, span_lint_and_sugg} ;
2+ use clippy_utils:: source:: snippet_with_applicability;
43use clippy_utils:: { is_wild, meets_msrv, msrvs, path_to_local_id, peel_blocks, strip_pat_refs} ;
5- use core:: iter:: once;
64use if_chain:: if_chain;
75use rustc_errors:: Applicability ;
8- use rustc_hir:: { Arm , BorrowKind , Expr , ExprKind , Local , MatchSource , Mutability , Pat , PatKind , QPath } ;
6+ use rustc_hir:: { Arm , Expr , ExprKind , Local , MatchSource , Pat , PatKind , QPath } ;
97use rustc_lint:: { LateContext , LateLintPass } ;
108use rustc_middle:: ty;
119use rustc_semver:: RustcVersion ;
@@ -14,6 +12,7 @@ use rustc_session::{declare_tool_lint, impl_lint_pass};
1412mod match_as_ref;
1513mod match_bool;
1614mod match_like_matches;
15+ mod match_ref_pats;
1716mod match_same_arms;
1817mod match_single_binding;
1918mod match_wild_enum;
@@ -633,7 +632,7 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
633632 }
634633 }
635634 if let ExprKind :: Match ( ex, arms, _) = expr. kind {
636- check_match_ref_pats ( cx, ex, arms. iter ( ) . map ( |el| el. pat ) , expr) ;
635+ match_ref_pats :: check ( cx, ex, arms. iter ( ) . map ( |el| el. pat ) , expr) ;
637636 }
638637 }
639638
@@ -698,42 +697,6 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
698697 extract_msrv_attr ! ( LateContext ) ;
699698}
700699
701- fn check_match_ref_pats < ' a , ' b , I > ( cx : & LateContext < ' _ > , ex : & Expr < ' _ > , pats : I , expr : & Expr < ' _ > )
702- where
703- ' b : ' a ,
704- I : Clone + Iterator < Item = & ' a Pat < ' b > > ,
705- {
706- if !has_multiple_ref_pats ( pats. clone ( ) ) {
707- return ;
708- }
709-
710- let ( first_sugg, msg, title) ;
711- let span = ex. span . source_callsite ( ) ;
712- if let ExprKind :: AddrOf ( BorrowKind :: Ref , Mutability :: Not , inner) = ex. kind {
713- first_sugg = once ( ( span, Sugg :: hir_with_macro_callsite ( cx, inner, ".." ) . to_string ( ) ) ) ;
714- msg = "try" ;
715- title = "you don't need to add `&` to both the expression and the patterns" ;
716- } else {
717- first_sugg = once ( ( span, Sugg :: hir_with_macro_callsite ( cx, ex, ".." ) . deref ( ) . to_string ( ) ) ) ;
718- msg = "instead of prefixing all patterns with `&`, you can dereference the expression" ;
719- title = "you don't need to add `&` to all patterns" ;
720- }
721-
722- let remaining_suggs = pats. filter_map ( |pat| {
723- if let PatKind :: Ref ( refp, _) = pat. kind {
724- Some ( ( pat. span , snippet ( cx, refp. span , ".." ) . to_string ( ) ) )
725- } else {
726- None
727- }
728- } ) ;
729-
730- span_lint_and_then ( cx, MATCH_REF_PATS , expr. span , title, |diag| {
731- if !expr. span . from_expansion ( ) {
732- multispan_sugg ( diag, msg, first_sugg. chain ( remaining_suggs) ) ;
733- }
734- } ) ;
735- }
736-
737700fn check_wild_in_or_pats ( cx : & LateContext < ' _ > , arms : & [ Arm < ' _ > ] ) {
738701 for arm in arms {
739702 if let PatKind :: Or ( fields) = arm. pat . kind {
@@ -751,25 +714,3 @@ fn check_wild_in_or_pats(cx: &LateContext<'_>, arms: &[Arm<'_>]) {
751714 }
752715 }
753716}
754-
755- fn has_multiple_ref_pats < ' a , ' b , I > ( pats : I ) -> bool
756- where
757- ' b : ' a ,
758- I : Iterator < Item = & ' a Pat < ' b > > ,
759- {
760- let mut ref_count = 0 ;
761- for opt in pats. map ( |pat| match pat. kind {
762- PatKind :: Ref ( ..) => Some ( true ) , // &-patterns
763- PatKind :: Wild => Some ( false ) , // an "anything" wildcard is also fine
764- _ => None , // any other pattern is not fine
765- } ) {
766- if let Some ( inner) = opt {
767- if inner {
768- ref_count += 1 ;
769- }
770- } else {
771- return false ;
772- }
773- }
774- ref_count > 1
775- }
0 commit comments