12
12
//! code was written, and check if the span contains that text. Note this will only work correctly
13
13
//! if the span is not from a `macro_rules` based macro.
14
14
15
- use rustc_ast:: ast:: { AttrKind , Attribute , IntTy , LitIntType , LitKind , StrStyle , UintTy } ;
15
+ use rustc_ast:: ast:: { AttrKind , Attribute , IntTy , LitIntType , LitKind , StrStyle , TraitObjectSyntax , UintTy } ;
16
16
use rustc_ast:: token:: CommentKind ;
17
17
use rustc_ast:: AttrStyle ;
18
18
use rustc_hir:: intravisit:: FnKind ;
19
19
use rustc_hir:: {
20
- Block , BlockCheckMode , Body , Closure , Destination , Expr , ExprKind , FieldDef , FnHeader , HirId , Impl , ImplItem ,
21
- ImplItemKind , IsAuto , Item , ItemKind , LoopSource , MatchSource , MutTy , Node , QPath , TraitItem , TraitItemKind , Ty ,
22
- TyKind , UnOp , UnsafeSource , Unsafety , Variant , VariantData , YieldSource ,
20
+ Block , BlockCheckMode , Body , Closure , Destination , Expr , ExprKind , FieldDef , FnHeader , FnRetTy , HirId , Impl ,
21
+ ImplItem , ImplItemKind , IsAuto , Item , ItemKind , LoopSource , MatchSource , MutTy , Node , QPath , TraitItem ,
22
+ TraitItemKind , Ty , TyKind , UnOp , UnsafeSource , Unsafety , Variant , VariantData , YieldSource ,
23
23
} ;
24
24
use rustc_lint:: { LateContext , LintContext } ;
25
25
use rustc_middle:: ty:: TyCtxt ;
@@ -33,8 +33,6 @@ use rustc_target::spec::abi::Abi;
33
33
pub enum Pat {
34
34
/// A single string.
35
35
Str ( & ' static str ) ,
36
- /// A single string.
37
- OwnedStr ( String ) ,
38
36
/// Any of the given strings.
39
37
MultiStr ( & ' static [ & ' static str ] ) ,
40
38
/// Any of the given strings.
@@ -59,14 +57,12 @@ fn span_matches_pat(sess: &Session, span: Span, start_pat: Pat, end_pat: Pat) ->
59
57
let end_str = s. trim_end_matches ( |c : char | c. is_whitespace ( ) || c == ')' || c == ',' ) ;
60
58
( match start_pat {
61
59
Pat :: Str ( text) => start_str. starts_with ( text) ,
62
- Pat :: OwnedStr ( text) => start_str. starts_with ( & text) ,
63
60
Pat :: MultiStr ( texts) => texts. iter ( ) . any ( |s| start_str. starts_with ( s) ) ,
64
61
Pat :: OwnedMultiStr ( texts) => texts. iter ( ) . any ( |s| start_str. starts_with ( s) ) ,
65
62
Pat :: Sym ( sym) => start_str. starts_with ( sym. as_str ( ) ) ,
66
63
Pat :: Num => start_str. as_bytes ( ) . first ( ) . map_or ( false , u8:: is_ascii_digit) ,
67
64
} && match end_pat {
68
65
Pat :: Str ( text) => end_str. ends_with ( text) ,
69
- Pat :: OwnedStr ( text) => end_str. starts_with ( & text) ,
70
66
Pat :: MultiStr ( texts) => texts. iter ( ) . any ( |s| start_str. ends_with ( s) ) ,
71
67
Pat :: OwnedMultiStr ( texts) => texts. iter ( ) . any ( |s| start_str. starts_with ( s) ) ,
72
68
Pat :: Sym ( sym) => end_str. ends_with ( sym. as_str ( ) ) ,
@@ -125,6 +121,7 @@ fn qpath_search_pat(path: &QPath<'_>) -> (Pat, Pat) {
125
121
fn expr_search_pat ( tcx : TyCtxt < ' _ > , e : & Expr < ' _ > ) -> ( Pat , Pat ) {
126
122
match e. kind {
127
123
ExprKind :: ConstBlock ( _) => ( Pat :: Str ( "const" ) , Pat :: Str ( "}" ) ) ,
124
+ // Parenthesis are skipped before the patterns are matched.
128
125
ExprKind :: Tup ( [ ] ) => ( Pat :: Str ( ")" ) , Pat :: Str ( "(" ) ) ,
129
126
ExprKind :: Unary ( UnOp :: Deref , e) => ( Pat :: Str ( "*" ) , expr_search_pat ( tcx, e) . 1 ) ,
130
127
ExprKind :: Unary ( UnOp :: Not , e) => ( Pat :: Str ( "!" ) , expr_search_pat ( tcx, e) . 1 ) ,
@@ -286,21 +283,17 @@ fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirI
286
283
fn attr_search_pat ( attr : & Attribute ) -> ( Pat , Pat ) {
287
284
match attr. kind {
288
285
AttrKind :: Normal ( ..) => {
289
- let mut pat = if matches ! ( attr. style, AttrStyle :: Outer ) {
290
- ( Pat :: Str ( "#[" ) , Pat :: Str ( "]" ) )
291
- } else {
292
- ( Pat :: Str ( "#![" ) , Pat :: Str ( "]" ) )
293
- } ;
294
-
295
- if let Some ( ident) = attr. ident ( ) && let Pat :: Str ( old_pat) = pat. 0 {
286
+ if let Some ( ident) = attr. ident ( ) {
296
287
// TODO: I feel like it's likely we can use `Cow` instead but this will require quite a bit of
297
288
// refactoring
298
289
// NOTE: This will likely have false positives, like `allow = 1`
299
- pat. 0 = Pat :: OwnedMultiStr ( vec ! [ ident. to_string( ) , old_pat. to_owned( ) ] ) ;
300
- pat. 1 = Pat :: Str ( "" ) ;
290
+ (
291
+ Pat :: OwnedMultiStr ( vec ! [ ident. to_string( ) , "#" . to_owned( ) ] ) ,
292
+ Pat :: Str ( "" ) ,
293
+ )
294
+ } else {
295
+ ( Pat :: Str ( "#" ) , Pat :: Str ( "]" ) )
301
296
}
302
-
303
- pat
304
297
} ,
305
298
AttrKind :: DocComment ( _kind @ CommentKind :: Line , ..) => {
306
299
if matches ! ( attr. style, AttrStyle :: Outer ) {
@@ -322,32 +315,41 @@ fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) {
322
315
fn ty_search_pat ( ty : & Ty < ' _ > ) -> ( Pat , Pat ) {
323
316
match ty. kind {
324
317
TyKind :: Slice ( ..) | TyKind :: Array ( ..) => ( Pat :: Str ( "[" ) , Pat :: Str ( "]" ) ) ,
325
- TyKind :: Ptr ( MutTy { mutbl, ty } ) => (
326
- if mutbl. is_mut ( ) {
327
- Pat :: Str ( "*const" )
328
- } else {
329
- Pat :: Str ( "*mut" )
330
- } ,
331
- ty_search_pat ( ty) . 1 ,
332
- ) ,
318
+ TyKind :: Ptr ( MutTy { ty, .. } ) => ( Pat :: Str ( "*" ) , ty_search_pat ( ty) . 1 ) ,
333
319
TyKind :: Ref ( _, MutTy { ty, .. } ) => ( Pat :: Str ( "&" ) , ty_search_pat ( ty) . 1 ) ,
334
320
TyKind :: BareFn ( bare_fn) => (
335
- Pat :: OwnedStr ( format ! ( "{}{} fn" , bare_fn. unsafety. prefix_str( ) , bare_fn. abi. name( ) ) ) ,
336
- ty_search_pat ( ty) . 1 ,
321
+ if bare_fn. unsafety == Unsafety :: Unsafe {
322
+ Pat :: Str ( "unsafe" )
323
+ } else if bare_fn. abi != Abi :: Rust {
324
+ Pat :: Str ( "extern" )
325
+ } else {
326
+ Pat :: MultiStr ( & [ "fn" , "extern" ] )
327
+ } ,
328
+ match bare_fn. decl . output {
329
+ FnRetTy :: DefaultReturn ( _) => {
330
+ if let [ .., ty] = bare_fn. decl . inputs {
331
+ ty_search_pat ( ty) . 1
332
+ } else {
333
+ Pat :: Str ( "(" )
334
+ }
335
+ } ,
336
+ FnRetTy :: Return ( ty) => ty_search_pat ( ty) . 1 ,
337
+ } ,
337
338
) ,
338
- TyKind :: Never => ( Pat :: Str ( "!" ) , Pat :: Str ( "" ) ) ,
339
- TyKind :: Tup ( ..) => ( Pat :: Str ( "(" ) , Pat :: Str ( ")" ) ) ,
339
+ TyKind :: Never => ( Pat :: Str ( "!" ) , Pat :: Str ( "!" ) ) ,
340
+ // Parenthesis are skipped before the patterns are matched.
341
+ TyKind :: Tup ( [ ] ) => ( Pat :: Str ( ")" ) , Pat :: Str ( "(" ) ) ,
342
+ TyKind :: Tup ( [ ty] ) => ty_search_pat ( ty) ,
343
+ TyKind :: Tup ( [ head, .., tail] ) => ( ty_search_pat ( head) . 0 , ty_search_pat ( tail) . 1 ) ,
340
344
TyKind :: OpaqueDef ( ..) => ( Pat :: Str ( "impl" ) , Pat :: Str ( "" ) ) ,
341
345
TyKind :: Path ( qpath) => qpath_search_pat ( & qpath) ,
342
- // NOTE: This is missing `TraitObject`. It will always return true then.
346
+ TyKind :: Infer => ( Pat :: Str ( "_" ) , Pat :: Str ( "_" ) ) ,
347
+ TyKind :: TraitObject ( _, _, TraitObjectSyntax :: Dyn ) => ( Pat :: Str ( "dyn" ) , Pat :: Str ( "" ) ) ,
348
+ // NOTE: `TraitObject` is incomplete. It will always return true then.
343
349
_ => ( Pat :: Str ( "" ) , Pat :: Str ( "" ) ) ,
344
350
}
345
351
}
346
352
347
- fn ident_search_pat ( ident : Ident ) -> ( Pat , Pat ) {
348
- ( Pat :: OwnedStr ( ident. name . as_str ( ) . to_owned ( ) ) , Pat :: Str ( "" ) )
349
- }
350
-
351
353
pub trait WithSearchPat < ' cx > {
352
354
type Context : LintContext ;
353
355
fn search_pat ( & self , cx : & Self :: Context ) -> ( Pat , Pat ) ;
@@ -406,7 +408,7 @@ impl<'cx> WithSearchPat<'cx> for Ident {
406
408
type Context = LateContext < ' cx > ;
407
409
408
410
fn search_pat ( & self , _cx : & Self :: Context ) -> ( Pat , Pat ) {
409
- ident_search_pat ( * self )
411
+ ( Pat :: Sym ( self . name ) , Pat :: Sym ( self . name ) )
410
412
}
411
413
412
414
fn span ( & self ) -> Span {
0 commit comments