@@ -29,12 +29,16 @@ use rustc_span::{Span, Symbol};
2929use rustc_target:: spec:: abi:: Abi ;
3030
3131/// The search pattern to look for. Used by `span_matches_pat`
32- #[ derive( Clone , Copy ) ]
32+ #[ derive( Clone ) ]
3333pub enum Pat {
3434 /// A single string.
3535 Str ( & ' static str ) ,
36+ /// A single string.
37+ OwnedStr ( String ) ,
3638 /// Any of the given strings.
3739 MultiStr ( & ' static [ & ' static str ] ) ,
40+ /// Any of the given strings.
41+ OwnedMultiStr ( Vec < String > ) ,
3842 /// The string representation of the symbol.
3943 Sym ( Symbol ) ,
4044 /// 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) ->
5559 let end_str = s. trim_end_matches ( |c : char | c. is_whitespace ( ) || c == ')' || c == ',' ) ;
5660 ( match start_pat {
5761 Pat :: Str ( text) => start_str. starts_with ( text) ,
62+ Pat :: OwnedStr ( text) => start_str. starts_with ( & text) ,
5863 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) ) ,
5965 Pat :: Sym ( sym) => start_str. starts_with ( sym. as_str ( ) ) ,
6066 Pat :: Num => start_str. as_bytes ( ) . first ( ) . map_or ( false , u8:: is_ascii_digit) ,
6167 } && match end_pat {
6268 Pat :: Str ( text) => end_str. ends_with ( text) ,
69+ Pat :: OwnedStr ( text) => end_str. starts_with ( & text) ,
6370 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) ) ,
6472 Pat :: Sym ( sym) => end_str. ends_with ( sym. as_str ( ) ) ,
6573 Pat :: Num => end_str. as_bytes ( ) . last ( ) . map_or ( false , u8:: is_ascii_hexdigit) ,
6674 } )
@@ -278,11 +286,21 @@ fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirI
278286fn attr_search_pat ( attr : & Attribute ) -> ( Pat , Pat ) {
279287 match attr. kind {
280288 AttrKind :: Normal ( ..) => {
281- if matches ! ( attr. style, AttrStyle :: Outer ) {
289+ let mut pat = if matches ! ( attr. style, AttrStyle :: Outer ) {
282290 ( Pat :: Str ( "#[" ) , Pat :: Str ( "]" ) )
283291 } else {
284292 ( 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 ( "" ) ;
285301 }
302+
303+ pat
286304 } ,
287305 AttrKind :: DocComment ( _kind @ CommentKind :: Line , ..) => {
288306 if matches ! ( attr. style, AttrStyle :: Outer ) {
0 commit comments