@@ -540,6 +540,102 @@ fn ident_search_pat(ident: Ident) -> (Pat, Pat) {
540540 ( Pat :: Sym ( ident. name ) , Pat :: Sym ( ident. name ) )
541541}
542542
543+ fn pat_search_pat ( tcx : TyCtxt < ' _ > , pat : & rustc_hir:: Pat < ' _ > ) -> ( Pat , Pat ) {
544+ match pat. kind {
545+ rustc_hir:: PatKind :: Missing | rustc_hir:: PatKind :: Err ( _) => ( Pat :: Str ( "" ) , Pat :: Str ( "" ) ) ,
546+ rustc_hir:: PatKind :: Wild => ( Pat :: Sym ( kw:: Underscore ) , Pat :: Sym ( kw:: Underscore ) ) ,
547+ rustc_hir:: PatKind :: Binding ( binding_mode, _, ident, Some ( end_pat) ) => {
548+ let start = match binding_mode. 0 {
549+ rustc_hir:: ByRef :: Yes ( rustc_hir:: Mutability :: Not ) => Pat :: Str ( "ref" ) ,
550+ rustc_hir:: ByRef :: Yes ( rustc_hir:: Mutability :: Mut ) => Pat :: Str ( "ref mut" ) ,
551+ rustc_hir:: ByRef :: No => {
552+ let ( s, _) = ident_search_pat ( ident) ;
553+ s
554+ } ,
555+ } ;
556+
557+ let ( _, end) = pat_search_pat ( tcx, end_pat) ;
558+ ( start, end)
559+ } ,
560+ rustc_hir:: PatKind :: Binding ( binding_mode, _, ident, None ) => {
561+ let ( s, end) = ident_search_pat ( ident) ;
562+ let start = match binding_mode. 0 {
563+ rustc_hir:: ByRef :: Yes ( rustc_hir:: Mutability :: Not ) => Pat :: Str ( "ref" ) ,
564+ rustc_hir:: ByRef :: Yes ( rustc_hir:: Mutability :: Mut ) => Pat :: Str ( "ref mut" ) ,
565+ rustc_hir:: ByRef :: No => s,
566+ } ;
567+
568+ ( start, end)
569+ } ,
570+ rustc_hir:: PatKind :: Struct ( path, _, _) => {
571+ let ( start, _) = qpath_search_pat ( & path) ;
572+ ( start, Pat :: Str ( "}" ) )
573+ } ,
574+ rustc_hir:: PatKind :: TupleStruct ( path, _, _) => {
575+ let ( start, _) = qpath_search_pat ( & path) ;
576+ ( start, Pat :: Str ( ")" ) )
577+ } ,
578+ rustc_hir:: PatKind :: Or ( plist) => {
579+ // documented invariant
580+ debug_assert ! ( plist. len( ) >= 2 ) ;
581+ let ( start, _) = pat_search_pat ( tcx, plist. first ( ) . unwrap ( ) ) ;
582+ let ( _, end) = pat_search_pat ( tcx, plist. last ( ) . unwrap ( ) ) ;
583+ ( start, end)
584+ } ,
585+ rustc_hir:: PatKind :: Never => ( Pat :: Str ( "!" ) , Pat :: Str ( "" ) ) ,
586+ rustc_hir:: PatKind :: Tuple ( _, _) => ( Pat :: Str ( "(" ) , Pat :: Str ( ")" ) ) ,
587+ rustc_hir:: PatKind :: Box ( p) => {
588+ let ( _, end) = pat_search_pat ( tcx, p) ;
589+ ( Pat :: Str ( "box" ) , end)
590+ } ,
591+ rustc_hir:: PatKind :: Deref ( _) => ( Pat :: Str ( "deref!(" ) , Pat :: Str ( ")" ) ) ,
592+ rustc_hir:: PatKind :: Ref ( p, _) => {
593+ let ( _, end) = pat_search_pat ( tcx, p) ;
594+ ( Pat :: Str ( "&" ) , end)
595+ } ,
596+ rustc_hir:: PatKind :: Expr ( expr) => pat_search_pat_expr_kind ( expr) ,
597+ rustc_hir:: PatKind :: Guard ( pat, guard) => {
598+ let ( start, _) = pat_search_pat ( tcx, pat) ;
599+ let ( _, end) = expr_search_pat ( tcx, guard) ;
600+ ( start, end)
601+ } ,
602+ rustc_hir:: PatKind :: Range ( None , None , range) => match range {
603+ rustc_hir:: RangeEnd :: Included => ( Pat :: Str ( "..=" ) , Pat :: Str ( "" ) ) ,
604+ rustc_hir:: RangeEnd :: Excluded => ( Pat :: Str ( ".." ) , Pat :: Str ( "" ) ) ,
605+ } ,
606+ rustc_hir:: PatKind :: Range ( r_start, r_end, range) => {
607+ let ( start, _) = match r_start {
608+ Some ( e) => pat_search_pat_expr_kind ( e) ,
609+ None => match range {
610+ rustc_hir:: RangeEnd :: Included => ( Pat :: Str ( "..=" ) , Pat :: Str ( "" ) ) ,
611+ rustc_hir:: RangeEnd :: Excluded => ( Pat :: Str ( ".." ) , Pat :: Str ( "" ) ) ,
612+ } ,
613+ } ;
614+
615+ let ( _, end) = match r_end {
616+ Some ( e) => pat_search_pat_expr_kind ( e) ,
617+ None => match range {
618+ rustc_hir:: RangeEnd :: Included => ( Pat :: Str ( "" ) , Pat :: Str ( "..=" ) ) ,
619+ rustc_hir:: RangeEnd :: Excluded => ( Pat :: Str ( "" ) , Pat :: Str ( ".." ) ) ,
620+ } ,
621+ } ;
622+ ( start, end)
623+ } ,
624+ rustc_hir:: PatKind :: Slice ( _, _, _) => ( Pat :: Str ( "[" ) , Pat :: Str ( "]" ) ) ,
625+ }
626+ }
627+
628+ fn pat_search_pat_expr_kind ( expr : & crate :: PatExpr < ' _ > ) -> ( Pat , Pat ) {
629+ match expr. kind {
630+ crate :: PatExprKind :: Lit { lit, negated } => {
631+ let ( start, end) = lit_search_pat ( & lit. node ) ;
632+ if negated { ( Pat :: Str ( "!" ) , end) } else { ( start, end) }
633+ } ,
634+ crate :: PatExprKind :: ConstBlock ( _block) => ( Pat :: Str ( "const {" ) , Pat :: Str ( "}" ) ) ,
635+ crate :: PatExprKind :: Path ( path) => qpath_search_pat ( & path) ,
636+ }
637+ }
638+
543639pub trait WithSearchPat < ' cx > {
544640 type Context : LintContext ;
545641 fn search_pat ( & self , cx : & Self :: Context ) -> ( Pat , Pat ) ;
@@ -568,6 +664,7 @@ impl_with_search_pat!((_cx: LateContext<'tcx>, self: Ty<'_>) => ty_search_pat(se
568664impl_with_search_pat ! ( ( _cx: LateContext <' tcx>, self : Ident ) => ident_search_pat( * self ) ) ;
569665impl_with_search_pat ! ( ( _cx: LateContext <' tcx>, self : Lit ) => lit_search_pat( & self . node) ) ;
570666impl_with_search_pat ! ( ( _cx: LateContext <' tcx>, self : Path <' _>) => path_search_pat( self ) ) ;
667+ impl_with_search_pat ! ( ( cx: LateContext <' tcx>, self : rustc_hir:: Pat <' _>) => pat_search_pat( cx. tcx, self ) ) ;
571668
572669impl_with_search_pat ! ( ( _cx: EarlyContext <' tcx>, self : Attribute ) => attr_search_pat( self ) ) ;
573670impl_with_search_pat ! ( ( _cx: EarlyContext <' tcx>, self : ast:: Ty ) => ast_ty_search_pat( self ) ) ;
0 commit comments