@@ -29,12 +29,16 @@ use rustc_span::{Span, Symbol};
29
29
use rustc_target:: spec:: abi:: Abi ;
30
30
31
31
/// The search pattern to look for. Used by `span_matches_pat`
32
- #[ derive( Clone , Copy ) ]
32
+ #[ derive( Clone ) ]
33
33
pub enum Pat {
34
34
/// A single string.
35
35
Str ( & ' static str ) ,
36
+ /// A single string.
37
+ OwnedStr ( String ) ,
36
38
/// Any of the given strings.
37
39
MultiStr ( & ' static [ & ' static str ] ) ,
40
+ /// Any of the given strings.
41
+ OwnedMultiStr ( Vec < String > ) ,
38
42
/// The string representation of the symbol.
39
43
Sym ( Symbol ) ,
40
44
/// Any decimal or hexadecimal digit depending on the location.
@@ -55,12 +59,16 @@ fn span_matches_pat(sess: &Session, span: Span, start_pat: Pat, end_pat: Pat) ->
55
59
let end_str = s. trim_end_matches ( |c : char | c. is_whitespace ( ) || c == ')' || c == ',' ) ;
56
60
( match start_pat {
57
61
Pat :: Str ( text) => start_str. starts_with ( text) ,
62
+ Pat :: OwnedStr ( text) => start_str. starts_with ( & text) ,
58
63
Pat :: MultiStr ( texts) => texts. iter ( ) . any ( |s| start_str. starts_with ( s) ) ,
64
+ Pat :: OwnedMultiStr ( texts) => texts. iter ( ) . any ( |s| start_str. starts_with ( s) ) ,
59
65
Pat :: Sym ( sym) => start_str. starts_with ( sym. as_str ( ) ) ,
60
66
Pat :: Num => start_str. as_bytes ( ) . first ( ) . map_or ( false , u8:: is_ascii_digit) ,
61
67
} && match end_pat {
62
68
Pat :: Str ( text) => end_str. ends_with ( text) ,
69
+ Pat :: OwnedStr ( text) => end_str. starts_with ( & text) ,
63
70
Pat :: MultiStr ( texts) => texts. iter ( ) . any ( |s| start_str. ends_with ( s) ) ,
71
+ Pat :: OwnedMultiStr ( texts) => texts. iter ( ) . any ( |s| start_str. starts_with ( s) ) ,
64
72
Pat :: Sym ( sym) => end_str. ends_with ( sym. as_str ( ) ) ,
65
73
Pat :: Num => end_str. as_bytes ( ) . last ( ) . map_or ( false , u8:: is_ascii_hexdigit) ,
66
74
} )
@@ -278,11 +286,21 @@ fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirI
278
286
fn attr_search_pat ( attr : & Attribute ) -> ( Pat , Pat ) {
279
287
match attr. kind {
280
288
AttrKind :: Normal ( ..) => {
281
- if matches ! ( attr. style, AttrStyle :: Outer ) {
289
+ let mut pat = if matches ! ( attr. style, AttrStyle :: Outer ) {
282
290
( Pat :: Str ( "#[" ) , Pat :: Str ( "]" ) )
283
291
} else {
284
292
( Pat :: Str ( "#![" ) , Pat :: Str ( "]" ) )
293
+ } ;
294
+
295
+ if let Some ( ident) = attr. ident ( ) && let Pat :: Str ( old_pat) = pat. 0 {
296
+ // TODO: I feel like it's likely we can use `Cow` instead but this will require quite a bit of
297
+ // refactoring
298
+ // 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 ( "" ) ;
285
301
}
302
+
303
+ pat
286
304
} ,
287
305
AttrKind :: DocComment ( _kind @ CommentKind :: Line , ..) => {
288
306
if matches ! ( attr. style, AttrStyle :: Outer ) {
0 commit comments