Skip to content

Commit 497f377

Browse files
committed
Fix attr_search_pat for #[cfg_attr]
1 parent ab70553 commit 497f377

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

clippy_utils/src/check_proc_macro.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,16 @@ use rustc_span::{Span, Symbol};
2929
use 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)]
3333
pub 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
278286
fn 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) {

tests/ui/allow_attributes.fixed

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ struct T3;
2020
#[warn(clippy::needless_borrow)] // Should not lint
2121
struct T4;
2222
// `panic = "unwind"` should always be true
23-
#[cfg_attr(panic = "unwind", allow(dead_code))]
23+
#[cfg_attr(panic = "unwind", expect(dead_code))]
2424
struct CfgT;
2525

2626
fn ignore_external() {

tests/ui/allow_attributes.stderr

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,11 @@ LL | #[allow(dead_code)]
66
|
77
= note: `-D clippy::allow-attributes` implied by `-D warnings`
88

9-
error: aborting due to previous error
9+
error: #[allow] attribute found
10+
--> $DIR/allow_attributes.rs:23:30
11+
|
12+
LL | #[cfg_attr(panic = "unwind", allow(dead_code))]
13+
| ^^^^^ help: replace it with: `expect`
14+
15+
error: aborting due to 2 previous errors
1016

0 commit comments

Comments
 (0)