about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCentri3 <114838443+Centri3@users.noreply.github.com>2023-06-01 21:26:41 -0500
committerCentri3 <114838443+Centri3@users.noreply.github.com>2023-06-01 21:26:41 -0500
commit497f37793e54a689d24983c2fbbc40d1255c4755 (patch)
treebb8da91e45bce28ee2bee6dd4e24cf627555ee60
parentab70553a387a5689170d2f075849ee345bc72a90 (diff)
downloadrust-497f37793e54a689d24983c2fbbc40d1255c4755.tar.gz
rust-497f37793e54a689d24983c2fbbc40d1255c4755.zip
Fix `attr_search_pat` for `#[cfg_attr]`
-rw-r--r--clippy_utils/src/check_proc_macro.rs22
-rw-r--r--tests/ui/allow_attributes.fixed2
-rw-r--r--tests/ui/allow_attributes.stderr8
3 files changed, 28 insertions, 4 deletions
diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs
index e0dbc1c9701..fd04f2ddf7c 100644
--- a/clippy_utils/src/check_proc_macro.rs
+++ b/clippy_utils/src/check_proc_macro.rs
@@ -29,12 +29,16 @@ use rustc_span::{Span, Symbol};
 use rustc_target::spec::abi::Abi;
 
 /// The search pattern to look for. Used by `span_matches_pat`
-#[derive(Clone, Copy)]
+#[derive(Clone)]
 pub enum Pat {
     /// A single string.
     Str(&'static str),
+    /// A single string.
+    OwnedStr(String),
     /// Any of the given strings.
     MultiStr(&'static [&'static str]),
+    /// Any of the given strings.
+    OwnedMultiStr(Vec<String>),
     /// The string representation of the symbol.
     Sym(Symbol),
     /// 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) ->
         let end_str = s.trim_end_matches(|c: char| c.is_whitespace() || c == ')' || c == ',');
         (match start_pat {
             Pat::Str(text) => start_str.starts_with(text),
+            Pat::OwnedStr(text) => start_str.starts_with(&text),
             Pat::MultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)),
+            Pat::OwnedMultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)),
             Pat::Sym(sym) => start_str.starts_with(sym.as_str()),
             Pat::Num => start_str.as_bytes().first().map_or(false, u8::is_ascii_digit),
         } && match end_pat {
             Pat::Str(text) => end_str.ends_with(text),
+            Pat::OwnedStr(text) => end_str.starts_with(&text),
             Pat::MultiStr(texts) => texts.iter().any(|s| start_str.ends_with(s)),
+            Pat::OwnedMultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)),
             Pat::Sym(sym) => end_str.ends_with(sym.as_str()),
             Pat::Num => end_str.as_bytes().last().map_or(false, u8::is_ascii_hexdigit),
         })
@@ -278,11 +286,21 @@ fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirI
 fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) {
     match attr.kind {
         AttrKind::Normal(..) => {
-            if matches!(attr.style, AttrStyle::Outer) {
+            let mut pat = if matches!(attr.style, AttrStyle::Outer) {
                 (Pat::Str("#["), Pat::Str("]"))
             } else {
                 (Pat::Str("#!["), Pat::Str("]"))
+            };
+
+            if let Some(ident) = attr.ident() && let Pat::Str(old_pat) = pat.0 {
+                // TODO: I feel like it's likely we can use `Cow` instead but this will require quite a bit of
+                // refactoring
+                // NOTE: This will likely have false positives, like `allow = 1`
+                pat.0 = Pat::OwnedMultiStr(vec![ident.to_string(), old_pat.to_owned()]);
+                pat.1 = Pat::Str("");
             }
+
+            pat
         },
         AttrKind::DocComment(_kind @ CommentKind::Line, ..) => {
             if matches!(attr.style, AttrStyle::Outer) {
diff --git a/tests/ui/allow_attributes.fixed b/tests/ui/allow_attributes.fixed
index 5c30a9d2941..fa04f53ca91 100644
--- a/tests/ui/allow_attributes.fixed
+++ b/tests/ui/allow_attributes.fixed
@@ -20,7 +20,7 @@ struct T3;
 #[warn(clippy::needless_borrow)] // Should not lint
 struct T4;
 // `panic = "unwind"` should always be true
-#[cfg_attr(panic = "unwind", allow(dead_code))]
+#[cfg_attr(panic = "unwind", expect(dead_code))]
 struct CfgT;
 
 fn ignore_external() {
diff --git a/tests/ui/allow_attributes.stderr b/tests/ui/allow_attributes.stderr
index 37149104a47..d17fd86cb86 100644
--- a/tests/ui/allow_attributes.stderr
+++ b/tests/ui/allow_attributes.stderr
@@ -6,5 +6,11 @@ LL | #[allow(dead_code)]
    |
    = note: `-D clippy::allow-attributes` implied by `-D warnings`
 
-error: aborting due to previous error
+error: #[allow] attribute found
+  --> $DIR/allow_attributes.rs:23:30
+   |
+LL | #[cfg_attr(panic = "unwind", allow(dead_code))]
+   |                              ^^^^^ help: replace it with: `expect`
+
+error: aborting due to 2 previous errors