Fix attr_search_pat for #[cfg_attr]

This commit is contained in:
Centri3 2023-06-01 21:26:41 -05:00
parent ab70553a38
commit 497f37793e
3 changed files with 28 additions and 4 deletions

View file

@ -29,12 +29,16 @@ use rustc_span::{Span, Symbol};
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
/// The search pattern to look for. Used by `span_matches_pat` /// The search pattern to look for. Used by `span_matches_pat`
#[derive(Clone, Copy)] #[derive(Clone)]
pub enum Pat { pub enum Pat {
/// A single string. /// A single string.
Str(&'static str), Str(&'static str),
/// A single string.
OwnedStr(String),
/// Any of the given strings. /// Any of the given strings.
MultiStr(&'static [&'static str]), MultiStr(&'static [&'static str]),
/// Any of the given strings.
OwnedMultiStr(Vec<String>),
/// The string representation of the symbol. /// The string representation of the symbol.
Sym(Symbol), Sym(Symbol),
/// Any decimal or hexadecimal digit depending on the location. /// 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 == ','); let end_str = s.trim_end_matches(|c: char| c.is_whitespace() || c == ')' || c == ',');
(match start_pat { (match start_pat {
Pat::Str(text) => start_str.starts_with(text), 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::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::Sym(sym) => start_str.starts_with(sym.as_str()),
Pat::Num => start_str.as_bytes().first().map_or(false, u8::is_ascii_digit), Pat::Num => start_str.as_bytes().first().map_or(false, u8::is_ascii_digit),
} && match end_pat { } && match end_pat {
Pat::Str(text) => end_str.ends_with(text), 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::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::Sym(sym) => end_str.ends_with(sym.as_str()),
Pat::Num => end_str.as_bytes().last().map_or(false, u8::is_ascii_hexdigit), 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) { fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) {
match attr.kind { match attr.kind {
AttrKind::Normal(..) => { AttrKind::Normal(..) => {
if matches!(attr.style, AttrStyle::Outer) { let mut pat = if matches!(attr.style, AttrStyle::Outer) {
(Pat::Str("#["), Pat::Str("]")) (Pat::Str("#["), Pat::Str("]"))
} else { } else {
(Pat::Str("#!["), Pat::Str("]")) (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, ..) => { AttrKind::DocComment(_kind @ CommentKind::Line, ..) => {
if matches!(attr.style, AttrStyle::Outer) { if matches!(attr.style, AttrStyle::Outer) {

View file

@ -20,7 +20,7 @@ struct T3;
#[warn(clippy::needless_borrow)] // Should not lint #[warn(clippy::needless_borrow)] // Should not lint
struct T4; struct T4;
// `panic = "unwind"` should always be true // `panic = "unwind"` should always be true
#[cfg_attr(panic = "unwind", allow(dead_code))] #[cfg_attr(panic = "unwind", expect(dead_code))]
struct CfgT; struct CfgT;
fn ignore_external() { fn ignore_external() {

View file

@ -6,5 +6,11 @@ LL | #[allow(dead_code)]
| |
= note: `-D clippy::allow-attributes` implied by `-D warnings` = 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