@@ -412,6 +412,102 @@ fn ident_search_pat(ident: Ident) -> (Pat, Pat) {
412412 ( Pat :: Sym ( ident. name ) , Pat :: Sym ( ident. name ) )
413413}
414414
415+ fn pat_search_pat ( tcx : TyCtxt < ' _ > , pat : & rustc_hir:: Pat < ' _ > ) -> ( Pat , Pat ) {
416+ match pat. kind {
417+ rustc_hir:: PatKind :: Missing | rustc_hir:: PatKind :: Err ( _) => ( Pat :: Str ( "" ) , Pat :: Str ( "" ) ) ,
418+ rustc_hir:: PatKind :: Wild => ( Pat :: Sym ( kw:: Underscore ) , Pat :: Sym ( kw:: Underscore ) ) ,
419+ rustc_hir:: PatKind :: Binding ( binding_mode, _, ident, Some ( end_pat) ) => {
420+ let start = match binding_mode. 0 {
421+ rustc_hir:: ByRef :: Yes ( rustc_hir:: Mutability :: Not ) => Pat :: Str ( "ref" ) ,
422+ rustc_hir:: ByRef :: Yes ( rustc_hir:: Mutability :: Mut ) => Pat :: Str ( "ref mut" ) ,
423+ rustc_hir:: ByRef :: No => {
424+ let ( s, _) = ident_search_pat ( ident) ;
425+ s
426+ } ,
427+ } ;
428+
429+ let ( _, end) = pat_search_pat ( tcx, end_pat) ;
430+ ( start, end)
431+ } ,
432+ rustc_hir:: PatKind :: Binding ( binding_mode, _, ident, None ) => {
433+ let ( s, end) = ident_search_pat ( ident) ;
434+ let start = match binding_mode. 0 {
435+ rustc_hir:: ByRef :: Yes ( rustc_hir:: Mutability :: Not ) => Pat :: Str ( "ref" ) ,
436+ rustc_hir:: ByRef :: Yes ( rustc_hir:: Mutability :: Mut ) => Pat :: Str ( "ref mut" ) ,
437+ rustc_hir:: ByRef :: No => s,
438+ } ;
439+
440+ ( start, end)
441+ } ,
442+ rustc_hir:: PatKind :: Struct ( path, _, _) => {
443+ let ( start, _) = qpath_search_pat ( & path) ;
444+ ( start, Pat :: Str ( "}" ) )
445+ } ,
446+ rustc_hir:: PatKind :: TupleStruct ( path, _, _) => {
447+ let ( start, _) = qpath_search_pat ( & path) ;
448+ ( start, Pat :: Str ( ")" ) )
449+ } ,
450+ rustc_hir:: PatKind :: Or ( plist) => {
451+ // documented invariant
452+ debug_assert ! ( plist. len( ) >= 2 ) ;
453+ let ( start, _) = pat_search_pat ( tcx, plist. first ( ) . unwrap ( ) ) ;
454+ let ( _, end) = pat_search_pat ( tcx, plist. last ( ) . unwrap ( ) ) ;
455+ ( start, end)
456+ } ,
457+ rustc_hir:: PatKind :: Never => ( Pat :: Str ( "!" ) , Pat :: Str ( "" ) ) ,
458+ rustc_hir:: PatKind :: Tuple ( _, _) => ( Pat :: Str ( "(" ) , Pat :: Str ( ")" ) ) ,
459+ rustc_hir:: PatKind :: Box ( p) => {
460+ let ( _, end) = pat_search_pat ( tcx, p) ;
461+ ( Pat :: Str ( "box" ) , end)
462+ } ,
463+ rustc_hir:: PatKind :: Deref ( _) => ( Pat :: Str ( "deref!(" ) , Pat :: Str ( ")" ) ) ,
464+ rustc_hir:: PatKind :: Ref ( p, _) => {
465+ let ( _, end) = pat_search_pat ( tcx, p) ;
466+ ( Pat :: Str ( "&" ) , end)
467+ } ,
468+ rustc_hir:: PatKind :: Expr ( expr) => pat_search_pat_expr_kind ( expr) ,
469+ rustc_hir:: PatKind :: Guard ( pat, guard) => {
470+ let ( start, _) = pat_search_pat ( tcx, pat) ;
471+ let ( _, end) = expr_search_pat ( tcx, guard) ;
472+ ( start, end)
473+ } ,
474+ rustc_hir:: PatKind :: Range ( None , None , range) => match range {
475+ rustc_hir:: RangeEnd :: Included => ( Pat :: Str ( "..=" ) , Pat :: Str ( "" ) ) ,
476+ rustc_hir:: RangeEnd :: Excluded => ( Pat :: Str ( ".." ) , Pat :: Str ( "" ) ) ,
477+ } ,
478+ rustc_hir:: PatKind :: Range ( r_start, r_end, range) => {
479+ let ( start, _) = match r_start {
480+ Some ( e) => pat_search_pat_expr_kind ( e) ,
481+ None => match range {
482+ rustc_hir:: RangeEnd :: Included => ( Pat :: Str ( "..=" ) , Pat :: Str ( "" ) ) ,
483+ rustc_hir:: RangeEnd :: Excluded => ( Pat :: Str ( ".." ) , Pat :: Str ( "" ) ) ,
484+ } ,
485+ } ;
486+
487+ let ( _, end) = match r_end {
488+ Some ( e) => pat_search_pat_expr_kind ( e) ,
489+ None => match range {
490+ rustc_hir:: RangeEnd :: Included => ( Pat :: Str ( "" ) , Pat :: Str ( "..=" ) ) ,
491+ rustc_hir:: RangeEnd :: Excluded => ( Pat :: Str ( "" ) , Pat :: Str ( ".." ) ) ,
492+ } ,
493+ } ;
494+ ( start, end)
495+ } ,
496+ rustc_hir:: PatKind :: Slice ( _, _, _) => ( Pat :: Str ( "[" ) , Pat :: Str ( "]" ) ) ,
497+ }
498+ }
499+
500+ fn pat_search_pat_expr_kind ( expr : & crate :: PatExpr < ' _ > ) -> ( Pat , Pat ) {
501+ match expr. kind {
502+ crate :: PatExprKind :: Lit { lit, negated } => {
503+ let ( start, end) = lit_search_pat ( & lit. node ) ;
504+ if negated { ( Pat :: Str ( "!" ) , end) } else { ( start, end) }
505+ } ,
506+ crate :: PatExprKind :: ConstBlock ( _block) => ( Pat :: Str ( "const {" ) , Pat :: Str ( "}" ) ) ,
507+ crate :: PatExprKind :: Path ( path) => qpath_search_pat ( & path) ,
508+ }
509+ }
510+
415511pub trait WithSearchPat < ' cx > {
416512 type Context : LintContext ;
417513 fn search_pat ( & self , cx : & Self :: Context ) -> ( Pat , Pat ) ;
@@ -440,6 +536,7 @@ impl_with_search_pat!((_cx: LateContext<'tcx>, self: Ty<'_>) => ty_search_pat(se
440536impl_with_search_pat ! ( ( _cx: LateContext <' tcx>, self : Ident ) => ident_search_pat( * self ) ) ;
441537impl_with_search_pat ! ( ( _cx: LateContext <' tcx>, self : Lit ) => lit_search_pat( & self . node) ) ;
442538impl_with_search_pat ! ( ( _cx: LateContext <' tcx>, self : Path <' _>) => path_search_pat( self ) ) ;
539+ impl_with_search_pat ! ( ( cx: LateContext <' tcx>, self : rustc_hir:: Pat <' _>) => pat_search_pat( cx. tcx, self ) ) ;
443540
444541impl_with_search_pat ! ( ( _cx: EarlyContext <' tcx>, self : Attribute ) => attr_search_pat( self ) ) ;
445542
0 commit comments