diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index a5e630a09afe2..8aca076d937d3 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -96,11 +96,11 @@ impl AttributeExt for Attribute { } /// For a single-segment attribute, returns its name; otherwise, returns `None`. - fn ident(&self) -> Option { + fn name(&self) -> Option { 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> { + fn symbol_path(&self) -> Option> { 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 { + match &self.kind { + AttrKind::Normal(attr) => Some(attr.item.path.span), AttrKind::DocComment(_, _) => None, } } @@ -797,9 +806,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 { - self.ident().map(|ident| ident.name) - } + fn name(&self) -> Option; /// Get the meta item list, `#[attr(meta item list)]` fn meta_item_list(&self) -> Option>; @@ -810,9 +817,6 @@ pub trait AttributeExt: Debug { /// Gets the span of the value literal, as string, when using `#[attr = value]` fn value_span(&self) -> Option; - /// For a single-segment attribute, returns its ident; otherwise, returns `None`. - fn ident(&self) -> Option; - /// Checks whether the path of this attribute matches the name. /// /// Matches one segment of the path to each element in `name` @@ -825,7 +829,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] @@ -839,13 +843,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; + /// Returns None for doc comments - fn ident_path(&self) -> Option>; + fn symbol_path(&self) -> Option>; /// Returns the documentation if this is a doc comment or a sugared doc comment. /// * `///doc` returns `Some("doc")`. @@ -906,10 +910,6 @@ impl Attribute { AttributeExt::value_span(self) } - pub fn ident(&self) -> Option { - AttributeExt::ident(self) - } - pub fn path_matches(&self, name: &[Symbol]) -> bool { AttributeExt::path_matches(self, name) } @@ -941,10 +941,6 @@ impl Attribute { AttributeExt::path(self) } - pub fn ident_path(&self) -> Option> { - AttributeExt::ident_path(self) - } - pub fn doc_str(&self) -> Option { AttributeExt::doc_str(self) } diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 88e9bbd710601..6b48c0583bc7d 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -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, .. }, diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg.rs b/compiler/rustc_attr_parsing/src/attributes/cfg.rs index 6ffe25098308a..4498b8df24f23 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg.rs @@ -369,13 +369,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, diff --git a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs index 0c0915558089e..523f2f8c6fa78 100644 --- a/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs +++ b/compiler/rustc_attr_parsing/src/attributes/cfg_select.rs @@ -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}; @@ -59,10 +59,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, diff --git a/compiler/rustc_attr_parsing/src/attributes/util.rs b/compiler/rustc_attr_parsing/src/attributes/util.rs index 105f7164bf3b3..75fbfc142a6fb 100644 --- a/compiler/rustc_attr_parsing/src/attributes/util.rs +++ b/compiler/rustc_attr_parsing/src/attributes/util.rs @@ -28,8 +28,7 @@ pub fn parse_version(s: Symbol) -> Option { } 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. diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs index 819e5630561d0..3820f804d8e7b 100644 --- a/compiler/rustc_attr_parsing/src/parser.rs +++ b/compiler/rustc_attr_parsing/src/parser.rs @@ -31,7 +31,7 @@ pub struct PathParser<'a>(pub Cow<'a, Path>); impl<'a> PathParser<'a> { pub fn get_attribute_path(&self) -> hir::AttrPath { AttrPath { - segments: self.segments().copied().collect::>().into_boxed_slice(), + segments: self.segments().map(|s| s.name).collect::>().into_boxed_slice(), span: self.span(), } } diff --git a/compiler/rustc_attr_parsing/src/safety.rs b/compiler/rustc_attr_parsing/src/safety.rs index 817785108a1ed..68aeca2bbda92 100644 --- a/compiler/rustc_attr_parsing/src/safety.rs +++ b/compiler/rustc_attr_parsing/src/safety.rs @@ -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) { diff --git a/compiler/rustc_attr_parsing/src/target_checking.rs b/compiler/rustc_attr_parsing/src/target_checking.rs index 88efb910c1601..e86ecb451fc28 100644 --- a/compiler/rustc_attr_parsing/src/target_checking.rs +++ b/compiler/rustc_attr_parsing/src/target_checking.rs @@ -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, diff --git a/compiler/rustc_attr_parsing/src/validate_attr.rs b/compiler/rustc_attr_parsing/src/validate_attr.rs index cd28677b6a8fd..4ccdf2fbaaad3 100644 --- a/compiler/rustc_attr_parsing/src/validate_attr.rs +++ b/compiler/rustc_attr_parsing/src/validate_attr.rs @@ -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 { diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index 7bc9080ba0229..557daa94b98ee 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -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 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(()) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 0ab0cb0ef88a5..89df7921c3b30 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -15,7 +15,7 @@ use rustc_middle::span_bug; use rustc_middle::ty::{self as ty, TyCtxt}; use rustc_session::lint; use rustc_session::parse::feature_err; -use rustc_span::{Ident, Span, sym}; +use rustc_span::{Span, sym}; use rustc_target::spec::Os; use crate::errors; @@ -314,7 +314,7 @@ fn process_builtin_attrs( } } - let Some(Ident { name, .. }) = attr.ident() else { + let Some(name) = attr.name() else { continue; }; diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 33431556c76ca..d2f3f3f30a313 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -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::::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 { diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f5470adb87e03..3d75cfd6168b1 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -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::>() .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 { + fn name(&self) -> Option { 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> { + fn symbol_path(&self) -> Option> { match &self { Attribute::Unparsed(n) => Some(n.path.segments.iter().copied().collect()), _ => None, } } + fn path_span(&self) -> Option { + match &self { + Attribute::Unparsed(attr) => Some(attr.path.span), + Attribute::Parsed(_) => None, + } + } + #[inline] fn doc_str(&self) -> Option { match &self { @@ -1451,11 +1462,6 @@ impl Attribute { AttributeExt::value_span(self) } - #[inline] - pub fn ident(&self) -> Option { - 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> { - AttributeExt::ident_path(self) - } - #[inline] pub fn doc_str(&self) -> Option { AttributeExt::doc_str(self) diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index b3b416955230f..80e8bcb9a93a6 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -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, }; diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs index 44fdf146f9c73..e04178645fdd8 100644 --- a/compiler/rustc_parse/src/parser/attr_wrapper.rs +++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs @@ -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), }) } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 030839baad9b9..06b6ddeb0689e 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -393,7 +393,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 => { @@ -430,7 +430,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, diff --git a/compiler/rustc_query_system/src/ich/impls_syntax.rs b/compiler/rustc_query_system/src/ich/impls_syntax.rs index 118229ffc9902..fe6fb3d651946 100644 --- a/compiler/rustc_query_system/src/ich/impls_syntax.rs +++ b/compiler/rustc_query_system/src/ich/impls_syntax.rs @@ -24,7 +24,7 @@ impl<'a> HashStable> 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(); diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs index 7ab2a72d75b5c..61ebc73182c0d 100644 --- a/src/librustdoc/clean/cfg.rs +++ b/src/librustdoc/clean/cfg.rs @@ -859,8 +859,8 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator } 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) { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index dd5c50d2ba37c..9ea361c5e6195 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2679,8 +2679,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)); } diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs index 95f5537f394c0..d4bf74c295142 100644 --- a/src/librustdoc/passes/propagate_doc_cfg.rs +++ b/src/librustdoc/passes/propagate_doc_cfg.rs @@ -40,8 +40,8 @@ fn add_only_cfg_attributes(attrs: &mut Vec, 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()); diff --git a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs index 53d9725703c3d..84b65d3185e35 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes.rs @@ -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, diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs index 91c2dc7f3dc6c..679ccfb8de3a1 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs @@ -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; diff --git a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs index 1cebc18edc90a..aa9a6654bee32 100644 --- a/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs +++ b/src/tools/clippy/clippy_lints/src/attrs/useless_attribute.rs @@ -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 { diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs index c3bc9048c23a8..28ea2e4fa1f0a 100644 --- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs +++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs @@ -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) ) }) diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index ac221743cfd64..375b275cd113a 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -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 { .. }) }, diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs index 2fd773b06781d..94e4ede140486 100644 --- a/src/tools/clippy/clippy_utils/src/attrs.rs +++ b/src/tools/clippy/clippy_utils/src/attrs.rs @@ -20,10 +20,11 @@ pub fn get_builtin_attr<'a, A: AttributeExt + 'a>( name: Symbol, ) -> impl Iterator { 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 diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs index d9254fca9453d..7fb8616072a59 100644 --- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs +++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs @@ -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]), diff --git a/src/tools/clippy/tests/ui/cognitive_complexity.stderr b/src/tools/clippy/tests/ui/cognitive_complexity.stderr index 67ef4e5655bd6..55d4b95d1ea5c 100644 --- a/src/tools/clippy/tests/ui/cognitive_complexity.stderr +++ b/src/tools/clippy/tests/ui/cognitive_complexity.stderr @@ -16,6 +16,14 @@ LL | fn kaboom() { | = help: you could split it up into multiple smaller functions +error: the function has a cognitive complexity of (2/1) + --> tests/ui/cognitive_complexity.rs:121:4 + | +LL | fn bloo() { + | ^^^^ + | + = help: you could split it up into multiple smaller functions + error: the function has a cognitive complexity of (2/1) --> tests/ui/cognitive_complexity.rs:158:4 | @@ -176,5 +184,5 @@ LL | fn bar() { | = help: you could split it up into multiple smaller functions -error: aborting due to 22 previous errors +error: aborting due to 23 previous errors diff --git a/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr b/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr index fb51313dab69a..0ebc43739d6b7 100644 --- a/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr +++ b/src/tools/clippy/tests/ui/renamed_builtin_attr.stderr @@ -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 diff --git a/src/tools/clippy/tests/ui/unknown_attribute.stderr b/src/tools/clippy/tests/ui/unknown_attribute.stderr index b306abe0a9d1f..1d4d50ffc02a4 100644 --- a/src/tools/clippy/tests/ui/unknown_attribute.stderr +++ b/src/tools/clippy/tests/ui/unknown_attribute.stderr @@ -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 diff --git a/src/tools/rustfmt/src/attr.rs b/src/tools/rustfmt/src/attr.rs index 381c938ae8062..d03d33514046e 100644 --- a/src/tools/rustfmt/src/attr.rs +++ b/src/tools/rustfmt/src/attr.rs @@ -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);