Make attr path symbols rather than idents

This commit is contained in:
Jonathan Brouwer 2025-12-09 09:49:50 +01:00
parent acfd264f4d
commit 7afba2977d
No known key found for this signature in database
GPG key ID: 13619B051B673C52
31 changed files with 103 additions and 115 deletions

View file

@ -96,11 +96,11 @@ impl AttributeExt for Attribute {
}
/// For a single-segment attribute, returns its name; otherwise, returns `None`.
fn ident(&self) -> Option<Ident> {
fn name(&self) -> Option<Symbol> {
match &self.kind {
AttrKind::Normal(normal) => {
if let [ident] = &*normal.item.path.segments {
Some(ident.ident)
Some(ident.ident.name)
} else {
None
}
@ -109,9 +109,18 @@ impl AttributeExt for Attribute {
}
}
fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
fn symbol_path(&self) -> Option<SmallVec<[Symbol; 1]>> {
match &self.kind {
AttrKind::Normal(p) => Some(p.item.path.segments.iter().map(|i| i.ident).collect()),
AttrKind::Normal(p) => {
Some(p.item.path.segments.iter().map(|i| i.ident.name).collect())
}
AttrKind::DocComment(_, _) => None,
}
}
fn path_span(&self) -> Option<Span> {
match &self.kind {
AttrKind::Normal(attr) => Some(attr.item.path.span),
AttrKind::DocComment(_, _) => None,
}
}
@ -794,9 +803,7 @@ pub trait AttributeExt: Debug {
/// For a single-segment attribute (i.e., `#[attr]` and not `#[path::atrr]`),
/// return the name of the attribute; otherwise, returns `None`.
fn name(&self) -> Option<Symbol> {
self.ident().map(|ident| ident.name)
}
fn name(&self) -> Option<Symbol>;
/// Get the meta item list, `#[attr(meta item list)]`
fn meta_item_list(&self) -> Option<ThinVec<MetaItemInner>>;
@ -807,9 +814,6 @@ pub trait AttributeExt: Debug {
/// Gets the span of the value literal, as string, when using `#[attr = value]`
fn value_span(&self) -> Option<Span>;
/// For a single-segment attribute, returns its ident; otherwise, returns `None`.
fn ident(&self) -> Option<Ident>;
/// Checks whether the path of this attribute matches the name.
///
/// Matches one segment of the path to each element in `name`
@ -822,7 +826,7 @@ pub trait AttributeExt: Debug {
#[inline]
fn has_name(&self, name: Symbol) -> bool {
self.ident().map(|x| x.name == name).unwrap_or(false)
self.name().map(|x| x == name).unwrap_or(false)
}
#[inline]
@ -836,13 +840,13 @@ pub trait AttributeExt: Debug {
fn is_word(&self) -> bool;
fn path(&self) -> SmallVec<[Symbol; 1]> {
self.ident_path()
.map(|i| i.into_iter().map(|i| i.name).collect())
.unwrap_or(smallvec![sym::doc])
self.symbol_path().unwrap_or(smallvec![sym::doc])
}
fn path_span(&self) -> Option<Span>;
/// Returns None for doc comments
fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>>;
fn symbol_path(&self) -> Option<SmallVec<[Symbol; 1]>>;
/// Returns the documentation if this is a doc comment or a sugared doc comment.
/// * `///doc` returns `Some("doc")`.
@ -903,10 +907,6 @@ impl Attribute {
AttributeExt::value_span(self)
}
pub fn ident(&self) -> Option<Ident> {
AttributeExt::ident(self)
}
pub fn path_matches(&self, name: &[Symbol]) -> bool {
AttributeExt::path_matches(self, name)
}
@ -938,10 +938,6 @@ impl Attribute {
AttributeExt::path(self)
}
pub fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
AttributeExt::ident_path(self)
}
pub fn doc_str(&self) -> Option<Symbol> {
AttributeExt::doc_str(self)
}

View file

@ -160,7 +160,7 @@ impl<'a> PostExpansionVisitor<'a> {
impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
fn visit_attribute(&mut self, attr: &ast::Attribute) {
let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
let attr_info = attr.name().and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name));
// Check feature gates for built-in attributes.
if let Some(BuiltinAttribute {
gate: AttributeGate::Gated { feature, message, check, notes, .. },

View file

@ -371,13 +371,7 @@ fn parse_cfg_attr_internal<'a>(
attribute.span,
attribute.get_normal_item().span(),
attribute.style,
AttrPath {
segments: attribute
.ident_path()
.expect("cfg_attr is not a doc comment")
.into_boxed_slice(),
span: attribute.span,
},
AttrPath { segments: attribute.path().into_boxed_slice(), span: attribute.span },
Some(attribute.get_normal_item().unsafety),
ParsedDescription::Attribute,
pred_span,

View file

@ -7,7 +7,7 @@ use rustc_hir::attrs::CfgEntry;
use rustc_parse::exp;
use rustc_parse::parser::Parser;
use rustc_session::Session;
use rustc_span::{ErrorGuaranteed, Ident, Span};
use rustc_span::{ErrorGuaranteed, Span, sym};
use crate::parser::MetaItemOrLitParser;
use crate::{AttributeParser, ParsedDescription, ShouldEmit, parse_cfg_entry};
@ -86,10 +86,7 @@ pub fn parse_cfg_select(
cfg_span,
cfg_span,
AttrStyle::Inner,
AttrPath {
segments: vec![Ident::from_str("cfg_select")].into_boxed_slice(),
span: cfg_span,
},
AttrPath { segments: vec![sym::cfg_select].into_boxed_slice(), span: cfg_span },
None,
ParsedDescription::Macro,
cfg_span,

View file

@ -28,8 +28,7 @@ pub fn parse_version(s: Symbol) -> Option<RustcVersion> {
}
pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool {
attr.is_doc_comment().is_some()
|| attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name))
attr.is_doc_comment().is_some() || attr.name().is_some_and(|name| is_builtin_attr_name(name))
}
/// Parse a single integer.

View file

@ -34,7 +34,7 @@ pub type RefPathParser<'p> = PathParser<&'p Path>;
impl<P: Borrow<Path>> PathParser<P> {
pub fn get_attribute_path(&self) -> hir::AttrPath {
AttrPath {
segments: self.segments().copied().collect::<Vec<_>>().into_boxed_slice(),
segments: self.segments().map(|s| s.name).collect::<Vec<_>>().into_boxed_slice(),
span: self.span(),
}
}

View file

@ -22,7 +22,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
return;
}
let name = (attr_path.segments.len() == 1).then_some(attr_path.segments[0].name);
let name = (attr_path.segments.len() == 1).then_some(attr_path.segments[0]);
if let Some(name) = name
&& [sym::cfg_trace, sym::cfg_attr_trace].contains(&name)
{

View file

@ -104,7 +104,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
let (applied, only) = allowed_targets_applied(allowed_targets, target, cx.features);
let name = cx.attr_path.clone();
let lint = if name.segments[0].name == sym::deprecated
let lint = if name.segments[0] == sym::deprecated
&& ![
Target::Closure,
Target::Expression,

View file

@ -27,7 +27,7 @@ pub fn check_attr(psess: &ParseSess, attr: &Attribute) {
return;
}
let builtin_attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
let builtin_attr_info = attr.name().and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name));
// Check input tokens for built-in and key-value attributes.
match builtin_attr_info {

View file

@ -13,7 +13,7 @@ use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpa
use rustc_hir::AttrPath;
use rustc_hir::attrs::CfgEntry;
use rustc_parse::exp;
use rustc_span::{ErrorGuaranteed, Ident, Span};
use rustc_span::{ErrorGuaranteed, Span, sym};
use crate::errors;
@ -47,7 +47,7 @@ fn parse_cfg(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream) -> Result<CfgEntry,
span,
span,
AttrStyle::Inner,
AttrPath { segments: vec![Ident::from_str("cfg")].into_boxed_slice(), span },
AttrPath { segments: vec![sym::cfg].into_boxed_slice(), span },
None,
ParsedDescription::Macro,
span,

View file

@ -47,10 +47,7 @@ fn has_cfg_or_cfg_attr(annotatable: &Annotatable) -> bool {
impl<'ast> visit::Visitor<'ast> for CfgFinder {
type Result = ControlFlow<()>;
fn visit_attribute(&mut self, attr: &'ast Attribute) -> ControlFlow<()> {
if attr
.ident()
.is_some_and(|ident| ident.name == sym::cfg || ident.name == sym::cfg_attr)
{
if attr.name().is_some_and(|name| name == sym::cfg || name == sym::cfg_attr) {
ControlFlow::Break(())
} else {
ControlFlow::Continue(())

View file

@ -18,7 +18,7 @@ use rustc_middle::span_bug;
use rustc_middle::ty::{self as ty, Instance, TyCtxt};
use rustc_session::lint;
use rustc_session::parse::feature_err;
use rustc_span::{Ident, Span, Symbol, sym};
use rustc_span::{Span, Symbol, sym};
use rustc_target::spec::Os;
use crate::errors;
@ -357,7 +357,7 @@ fn process_builtin_attrs(
}
}
let Some(Ident { name, .. }) = attr.ident() else {
let Some(name) = attr.name() else {
continue;
};

View file

@ -2110,7 +2110,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
let mut attr_pos = None;
for (pos, attr) in item.attrs().iter().enumerate() {
if !attr.is_doc_comment() && !self.cx.expanded_inert_attrs.is_marked(attr) {
let name = attr.ident().map(|ident| ident.name);
let name = attr.name();
if name == Some(sym::cfg) || name == Some(sym::cfg_attr) {
cfg_pos = Some(pos); // a cfg attr found, no need to search anymore
break;
@ -2187,7 +2187,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
} else if rustc_attr_parsing::is_builtin_attr(attr)
&& !AttributeParser::<Early>::is_parsed_attribute(&attr.path())
{
let attr_name = attr.ident().unwrap().name;
let attr_name = attr.name().unwrap();
// `#[cfg]` and `#[cfg_attr]` are special - they are
// eagerly evaluated.
if attr_name != sym::cfg_trace && attr_name != sym::cfg_attr_trace {

View file

@ -1182,7 +1182,7 @@ pub enum AttrArgs {
#[derive(Clone, Debug, HashStable_Generic, Encodable, Decodable)]
pub struct AttrPath {
pub segments: Box<[Ident]>,
pub segments: Box<[Symbol]>,
pub span: Span,
}
@ -1198,7 +1198,7 @@ impl AttrPath {
segments: path
.segments
.iter()
.map(|i| Ident { name: i.ident.name, span: lower_span(i.ident.span) })
.map(|i| i.ident.name)
.collect::<Vec<_>>()
.into_boxed_slice(),
span: lower_span(path.span),
@ -1208,7 +1208,11 @@ impl AttrPath {
impl fmt::Display for AttrPath {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", join_path_idents(&self.segments))
write!(
f,
"{}",
join_path_idents(self.segments.iter().map(|i| Ident { name: *i, span: DUMMY_SP }))
)
}
}
@ -1313,7 +1317,7 @@ impl AttributeExt for Attribute {
/// For a single-segment attribute, returns its name; otherwise, returns `None`.
#[inline]
fn ident(&self) -> Option<Ident> {
fn name(&self) -> Option<Symbol> {
match &self {
Attribute::Unparsed(n) => {
if let [ident] = n.path.segments.as_ref() {
@ -1329,7 +1333,7 @@ impl AttributeExt for Attribute {
#[inline]
fn path_matches(&self, name: &[Symbol]) -> bool {
match &self {
Attribute::Unparsed(n) => n.path.segments.iter().map(|ident| &ident.name).eq(name),
Attribute::Unparsed(n) => n.path.segments.iter().eq(name),
_ => false,
}
}
@ -1365,13 +1369,20 @@ impl AttributeExt for Attribute {
}
#[inline]
fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
fn symbol_path(&self) -> Option<SmallVec<[Symbol; 1]>> {
match &self {
Attribute::Unparsed(n) => Some(n.path.segments.iter().copied().collect()),
_ => None,
}
}
fn path_span(&self) -> Option<Span> {
match &self {
Attribute::Unparsed(attr) => Some(attr.path.span),
Attribute::Parsed(_) => None,
}
}
#[inline]
fn doc_str(&self) -> Option<Symbol> {
match &self {
@ -1451,11 +1462,6 @@ impl Attribute {
AttributeExt::value_span(self)
}
#[inline]
pub fn ident(&self) -> Option<Ident> {
AttributeExt::ident(self)
}
#[inline]
pub fn path_matches(&self, name: &[Symbol]) -> bool {
AttributeExt::path_matches(self, name)
@ -1491,11 +1497,6 @@ impl Attribute {
AttributeExt::path(self)
}
#[inline]
pub fn ident_path(&self) -> Option<SmallVec<[Ident; 1]>> {
AttributeExt::ident_path(self)
}
#[inline]
pub fn doc_str(&self) -> Option<Symbol> {
AttributeExt::doc_str(self)

View file

@ -22,7 +22,7 @@ use rustc_hir::{
TyPatKind,
};
use rustc_span::source_map::SourceMap;
use rustc_span::{FileName, Ident, Span, Symbol, kw, sym};
use rustc_span::{DUMMY_SP, FileName, Ident, Span, Symbol, kw, sym};
use {rustc_ast as ast, rustc_hir as hir};
pub fn id_to_string(cx: &dyn rustc_hir::intravisit::HirTyCtxt<'_>, hir_id: HirId) -> String {
@ -136,7 +136,11 @@ impl<'a> State<'a> {
.path
.segments
.iter()
.map(|i| ast::PathSegment { ident: *i, args: None, id: DUMMY_NODE_ID })
.map(|i| ast::PathSegment {
ident: Ident { name: *i, span: DUMMY_SP },
args: None,
id: DUMMY_NODE_ID,
})
.collect(),
tokens: None,
};

View file

@ -86,9 +86,9 @@ fn has_cfg_or_cfg_attr(attrs: &[Attribute]) -> bool {
// NOTE: Builtin attributes like `cfg` and `cfg_attr` cannot be renamed via imports.
// Therefore, the absence of a literal `cfg` or `cfg_attr` guarantees that
// we don't need to do any eager expansion.
attrs.iter().any(|attr| {
attr.ident().is_some_and(|ident| ident.name == sym::cfg || ident.name == sym::cfg_attr)
})
attrs
.iter()
.any(|attr| attr.name().is_some_and(|ident| ident == sym::cfg || ident == sym::cfg_attr))
}
impl<'a> Parser<'a> {
@ -398,10 +398,8 @@ impl<'a> Parser<'a> {
/// - any single-segment, non-builtin attributes are present, e.g. `derive`,
/// `test`, `global_allocator`.
fn needs_tokens(attrs: &[ast::Attribute]) -> bool {
attrs.iter().any(|attr| match attr.ident() {
attrs.iter().any(|attr| match attr.name() {
None => !attr.is_doc_comment(),
Some(ident) => {
ident.name == sym::cfg_attr || !rustc_feature::is_builtin_attr_name(ident.name)
}
Some(name) => name == sym::cfg_attr || !rustc_feature::is_builtin_attr_name(name),
})
}

View file

@ -388,7 +388,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
attr.path
.segments
.first()
.and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name))
.and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name))
{
match attr.style {
ast::AttrStyle::Outer => {
@ -425,7 +425,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
if let Attribute::Unparsed(unparsed_attr) = attr
&& let Some(BuiltinAttribute { duplicates, .. }) =
attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name))
attr.name().and_then(|name| BUILTIN_ATTRIBUTE_MAP.get(&name))
{
check_duplicates(
self.tcx,

View file

@ -24,7 +24,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for [hir::Attribute] {
.filter(|attr| {
attr.is_doc_comment().is_none()
// FIXME(jdonszelmann) have a better way to handle ignored attrs
&& !attr.ident().is_some_and(|ident| hcx.is_ignored_attr(ident.name))
&& !attr.name().is_some_and(|ident| hcx.is_ignored_attr(ident))
})
.collect();

View file

@ -859,8 +859,8 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
}
continue;
} else if !cfg_info.parent_is_doc_cfg
&& let Some(ident) = attr.ident()
&& matches!(ident.name, sym::cfg | sym::cfg_trace)
&& let Some(name) = attr.name()
&& matches!(name, sym::cfg | sym::cfg_trace)
&& let Some(attr) = single(attr.meta_item_list()?)
&& let Ok(new_cfg) = Cfg::parse(&attr)
{

View file

@ -2673,8 +2673,8 @@ fn add_without_unwanted_attributes<'hir>(
import_parent,
));
}
hir::Attribute::Unparsed(normal) if let [ident] = &*normal.path.segments => {
if is_inline || ident.name != sym::cfg_trace {
hir::Attribute::Unparsed(normal) if let [name] = &*normal.path.segments => {
if is_inline || *name != sym::cfg_trace {
// If it's not a `cfg()` attribute, we keep it.
attrs.push((Cow::Borrowed(attr), import_parent));
}

View file

@ -40,8 +40,8 @@ fn add_only_cfg_attributes(attrs: &mut Vec<Attribute>, new_attrs: &[Attribute])
new_attr.cfg = d.cfg.clone();
attrs.push(Attribute::Parsed(AttributeKind::Doc(Box::new(new_attr))));
} else if let Attribute::Unparsed(normal) = attr
&& let [ident] = &*normal.path.segments
&& ident.name == sym::cfg_trace
&& let [name] = &*normal.path.segments
&& *name == sym::cfg_trace
{
// If it's a `cfg()` attribute, we keep it.
attrs.push(attr.clone());

View file

@ -4,18 +4,19 @@ use clippy_utils::is_from_proc_macro;
use rustc_ast::{AttrStyle, Attribute};
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, LintContext};
use rustc_ast::attr::AttributeExt;
// Separate each crate's features.
pub fn check<'cx>(cx: &EarlyContext<'cx>, attr: &'cx Attribute) {
if !attr.span.in_external_macro(cx.sess().source_map())
&& let AttrStyle::Outer = attr.style
&& let Some(ident) = attr.ident()
&& let Some(path_span) = attr.path_span()
&& !is_from_proc_macro(cx, attr)
{
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
span_lint_and_then(cx, ALLOW_ATTRIBUTES, ident.span, "#[allow] attribute found", |diag| {
span_lint_and_then(cx, ALLOW_ATTRIBUTES, path_span, "#[allow] attribute found", |diag| {
diag.span_suggestion(
ident.span,
path_span,
"replace it with",
"expect",
Applicability::MachineApplicable,

View file

@ -574,16 +574,16 @@ impl EarlyLintPass for PostExpansionEarlyAttributes {
fn check_attribute(&mut self, cx: &EarlyContext<'_>, attr: &Attribute) {
if let Some(items) = &attr.meta_item_list()
&& let Some(ident) = attr.ident()
&& let Some(name) = attr.name()
{
if matches!(ident.name, sym::allow) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) {
if matches!(name, sym::allow) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) {
allow_attributes::check(cx, attr);
}
if matches!(ident.name, sym::allow | sym::expect) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) {
allow_attributes_without_reason::check(cx, ident.name, items, attr);
if matches!(name, sym::allow | sym::expect) && self.msrv.meets(msrvs::LINT_REASONS_STABILIZATION) {
allow_attributes_without_reason::check(cx, name, items, attr);
}
if is_lint_level(ident.name, attr.id) {
blanket_clippy_restriction_lints::check(cx, ident.name, items);
if is_lint_level(name, attr.id) {
blanket_clippy_restriction_lints::check(cx, name, items);
}
if items.is_empty() || !attr.has_name(sym::deprecated) {
return;

View file

@ -15,7 +15,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, item: &Item, attrs: &[Attribute]) {
return;
}
if let Some(lint_list) = &attr.meta_item_list()
&& attr.ident().is_some_and(|ident| is_lint_level(ident.name, attr.id))
&& attr.name().is_some_and(|name| is_lint_level(name, attr.id))
{
for lint in lint_list {
match item.kind {

View file

@ -270,7 +270,7 @@ fn is_under_cfg_attribute(cx: &LateContext<'_>, hir_id: HirId) -> bool {
cx.tcx.hir_parent_id_iter(hir_id).any(|id| {
cx.tcx.hir_attrs(id).iter().any(|attr| {
matches!(
attr.ident().map(|ident| ident.name),
attr.name(),
Some(sym::cfg_trace | sym::cfg_attr_trace)
)
})

View file

@ -287,8 +287,8 @@ fn is_doc_attr(attr: &Attribute) -> bool {
match attr {
Attribute::Parsed(AttributeKind::DocComment { .. }) => true,
Attribute::Unparsed(attr)
if let [ident] = &*attr.path.segments
&& ident.name == sym::doc =>
if let [name] = &*attr.path.segments
&& *name == sym::doc =>
{
matches!(attr.args, AttrArgs::Eq { .. })
},

View file

@ -20,10 +20,11 @@ pub fn get_builtin_attr<'a, A: AttributeExt + 'a>(
name: Symbol,
) -> impl Iterator<Item = &'a A> {
attrs.iter().filter(move |attr| {
if let Some([clippy, segment2]) = attr.ident_path().as_deref()
&& clippy.name == sym::clippy
if let [clippy, segment2] = &*attr.path()
&& *clippy == sym::clippy
{
let new_name = match segment2.name {
let path_span = attr.path_span().expect("Clippy attributes are unparsed and have a span");
let new_name = match *segment2 {
sym::cyclomatic_complexity => Some("cognitive_complexity"),
sym::author
| sym::version
@ -35,7 +36,7 @@ pub fn get_builtin_attr<'a, A: AttributeExt + 'a>(
| sym::has_significant_drop
| sym::format_args => None,
_ => {
sess.dcx().span_err(segment2.span, "usage of unknown attribute");
sess.dcx().span_err(path_span, "usage of unknown attribute");
return false;
},
};
@ -43,17 +44,17 @@ pub fn get_builtin_attr<'a, A: AttributeExt + 'a>(
match new_name {
Some(new_name) => {
sess.dcx()
.struct_span_err(segment2.span, "usage of deprecated attribute")
.struct_span_err(path_span, "usage of deprecated attribute")
.with_span_suggestion(
segment2.span,
path_span,
"consider using",
new_name,
format!("clippy::{}", new_name),
Applicability::MachineApplicable,
)
.emit();
false
},
None => segment2.name == name,
None => *segment2 == name,
}
} else {
false

View file

@ -348,9 +348,9 @@ 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 let Some(ident) = attr.ident() {
if let Some(name) = attr.name() {
// NOTE: This will likely have false positives, like `allow = 1`
let ident_string = ident.to_string();
let ident_string = name.to_string();
if attr.style == AttrStyle::Outer {
(
Pat::OwnedMultiStr(vec!["#[".to_owned() + &ident_string, ident_string]),

View file

@ -1,8 +1,8 @@
error: usage of deprecated attribute
--> tests/ui/renamed_builtin_attr.rs:3:11
--> tests/ui/renamed_builtin_attr.rs:3:3
|
LL | #[clippy::cyclomatic_complexity = "1"]
| ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `cognitive_complexity`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `clippy::cognitive_complexity`
error: aborting due to 1 previous error

View file

@ -1,8 +1,8 @@
error: usage of unknown attribute
--> tests/ui/unknown_attribute.rs:3:11
--> tests/ui/unknown_attribute.rs:3:3
|
LL | #[clippy::unknown]
| ^^^^^^^
| ^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View file

@ -336,8 +336,8 @@ impl Rewrite for ast::Attribute {
rewrite_doc_comment(snippet, shape.comment(context.config), context.config)
} else {
let should_skip = self
.ident()
.map(|s| context.skip_context.attributes.skip(s.name.as_str()))
.name()
.map(|s| context.skip_context.attributes.skip(s.as_str()))
.unwrap_or(false);
let prefix = attr_prefix(self);