From 3f450b547f299650097d73a06306e9696b12250e Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Thu, 9 Apr 2026 16:26:33 +0200 Subject: [PATCH] Remove `AttributeExt` --- compiler/rustc_ast/src/attr/mod.rs | 251 ++++-------------- .../rustc_attr_parsing/src/attributes/util.rs | 9 +- compiler/rustc_hir/src/hir.rs | 131 +++------ compiler/rustc_middle/src/ich/impls_syntax.rs | 2 +- compiler/rustc_resolve/src/rustdoc.rs | 16 +- 5 files changed, 96 insertions(+), 313 deletions(-) diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index 369fe12539fa8..ce3aedcf67670 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -3,7 +3,6 @@ pub mod data_structures; pub mod version; -use std::fmt::Debug; use std::sync::atomic::{AtomicU32, Ordering}; use rustc_index::bit_set::GrowableBitSet; @@ -83,12 +82,12 @@ impl Attribute { } } -impl AttributeExt for Attribute { - fn id(&self) -> AttrId { +impl Attribute { + pub fn id(&self) -> AttrId { self.id } - fn value_span(&self) -> Option { + pub fn value_span(&self) -> Option { match &self.kind { AttrKind::Normal(normal) => match &normal.item.args.unparsed_ref()? { AttrArgs::Eq { expr, .. } => Some(expr.span), @@ -101,15 +100,15 @@ impl AttributeExt for Attribute { /// Returns `true` if it is a sugared doc comment (`///` or `//!` for example). /// So `#[doc = "doc"]` (which is a doc comment) and `#[doc(...)]` (which is not /// a doc comment) will return `false`. - fn is_doc_comment(&self) -> Option { + pub fn is_doc_comment(&self) -> bool { match self.kind { - AttrKind::Normal(..) => None, - AttrKind::DocComment(..) => Some(self.span), + AttrKind::Normal(..) => false, + AttrKind::DocComment(..) => true, } } /// For a single-segment attribute, returns its name; otherwise, returns `None`. - fn name(&self) -> Option { + pub fn name(&self) -> Option { match &self.kind { AttrKind::Normal(normal) => { if let [ident] = &*normal.item.path.segments { @@ -122,7 +121,7 @@ impl AttributeExt for Attribute { } } - fn symbol_path(&self) -> Option> { + pub fn symbol_path(&self) -> Option> { match &self.kind { AttrKind::Normal(p) => { Some(p.item.path.segments.iter().map(|i| i.ident.name).collect()) @@ -131,14 +130,14 @@ impl AttributeExt for Attribute { } } - fn path_span(&self) -> Option { + pub fn path_span(&self) -> Option { match &self.kind { AttrKind::Normal(attr) => Some(attr.item.path.span), AttrKind::DocComment(_, _) => None, } } - fn path_matches(&self, name: &[Symbol]) -> bool { + pub fn path_matches(&self, name: &[Symbol]) -> bool { match &self.kind { AttrKind::Normal(normal) => { normal.item.path.segments.len() == name.len() @@ -154,11 +153,11 @@ impl AttributeExt for Attribute { } } - fn span(&self) -> Span { + pub fn span(&self) -> Span { self.span } - fn is_word(&self) -> bool { + pub fn is_word(&self) -> bool { if let AttrKind::Normal(normal) = &self.kind { matches!(normal.item.args, AttrItemKind::Unparsed(AttrArgs::Empty)) } else { @@ -173,7 +172,7 @@ impl AttributeExt for Attribute { /// #[attr = ""] // Returns `None`. /// #[attr] // Returns `None`. /// ``` - fn meta_item_list(&self) -> Option> { + pub fn meta_item_list(&self) -> Option> { match &self.kind { AttrKind::Normal(normal) => normal.item.meta_item_list(), AttrKind::DocComment(..) => None, @@ -195,7 +194,7 @@ impl AttributeExt for Attribute { /// ```text /// #[attr("value")] /// ``` - fn value_str(&self) -> Option { + pub fn value_str(&self) -> Option { match &self.kind { AttrKind::Normal(normal) => normal.item.value_str(), AttrKind::DocComment(..) => None, @@ -207,7 +206,7 @@ impl AttributeExt for Attribute { /// * `/** doc */` returns `Some(("doc", DocFragmentKind::Sugared(CommentKind::Block)))`. /// * `#[doc = "doc"]` returns `Some(("doc", DocFragmentKind::Raw))`. /// * `#[doc(...)]` returns `None`. - fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> { + pub fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> { match &self.kind { AttrKind::DocComment(kind, data) => Some((*data, DocFragmentKind::Sugared(*kind))), AttrKind::Normal(normal) if normal.item.path == sym::doc => { @@ -227,7 +226,7 @@ impl AttributeExt for Attribute { /// * `///doc` returns `Some("doc")`. /// * `#[doc = "doc"]` returns `Some("doc")`. /// * `#[doc(...)]` returns `None`. - fn doc_str(&self) -> Option { + pub fn doc_str(&self) -> Option { match &self.kind { AttrKind::DocComment(.., data) => Some(*data), AttrKind::Normal(normal) if normal.item.path == sym::doc => normal.item.value_str(), @@ -235,7 +234,7 @@ impl AttributeExt for Attribute { } } - fn deprecation_note(&self) -> Option { + pub fn deprecation_note(&self) -> Option { match &self.kind { AttrKind::Normal(normal) if normal.item.path == sym::deprecated => { let meta = &normal.item; @@ -263,7 +262,7 @@ impl AttributeExt for Attribute { } } - fn doc_resolution_scope(&self) -> Option { + pub fn doc_resolution_scope(&self) -> Option { match &self.kind { AttrKind::DocComment(..) => Some(self.style), AttrKind::Normal(normal) @@ -275,16 +274,16 @@ impl AttributeExt for Attribute { } } - fn is_automatically_derived_attr(&self) -> bool { + pub fn is_automatically_derived_attr(&self) -> bool { self.has_name(sym::automatically_derived) } - fn is_doc_hidden(&self) -> bool { + pub fn is_doc_hidden(&self) -> bool { self.has_name(sym::doc) && self.meta_item_list().is_some_and(|l| list_contains_name(&l, sym::hidden)) } - fn is_doc_keyword_or_attribute(&self) -> bool { + pub fn is_doc_keyword_or_attribute(&self) -> bool { if self.has_name(sym::doc) && let Some(items) = self.meta_item_list() { @@ -297,12 +296,37 @@ impl AttributeExt for Attribute { false } - fn is_rustc_doc_primitive(&self) -> bool { + pub fn is_rustc_doc_primitive(&self) -> bool { self.has_name(sym::rustc_doc_primitive) } -} -impl Attribute { + /// Returns whether this attribute is any of the proc macro attributes. + /// i.e. `proc_macro`, `proc_macro_attribute` or `proc_macro_derive`. + pub fn is_proc_macro_attr(&self) -> bool { + [sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive] + .iter() + .any(|kind| self.has_name(*kind)) + } + + /// Returns true if the attribute's first *and only* path segment is equal to the passed-in + /// symbol. + #[inline] + pub fn has_name(&self, name: Symbol) -> bool { + self.name().map(|x| x == name).unwrap_or(false) + } + + /// Returns true if the attribute's first *and only* path segment is any of the passed-in + /// symbols. + #[inline] + pub fn has_any_name(&self, names: &[Symbol]) -> bool { + names.iter().any(|&name| self.has_name(name)) + } + + #[inline] + pub fn path(&self) -> SmallVec<[Symbol; 1]> { + self.symbol_path().unwrap_or(smallvec![sym::doc]) + } + pub fn style(&self) -> AttrStyle { self.style } @@ -824,19 +848,19 @@ pub fn mk_attr_name_value_str( mk_attr(g, style, unsafety, path, args, span) } -pub fn filter_by_name(attrs: &[A], name: Symbol) -> impl Iterator { +pub fn filter_by_name(attrs: &[Attribute], name: Symbol) -> impl Iterator { attrs.iter().filter(move |attr| attr.has_name(name)) } -pub fn find_by_name(attrs: &[A], name: Symbol) -> Option<&A> { +pub fn find_by_name(attrs: &[Attribute], name: Symbol) -> Option<&Attribute> { filter_by_name(attrs, name).next() } -pub fn first_attr_value_str_by_name(attrs: &[impl AttributeExt], name: Symbol) -> Option { +pub fn first_attr_value_str_by_name(attrs: &[Attribute], name: Symbol) -> Option { find_by_name(attrs, name).and_then(|attr| attr.value_str()) } -pub fn contains_name(attrs: &[impl AttributeExt], name: Symbol) -> bool { +pub fn contains_name(attrs: &[Attribute], name: Symbol) -> bool { find_by_name(attrs, name).is_some() } @@ -849,172 +873,3 @@ impl MetaItemLit { LitKind::from_token_lit(self.as_token_lit()).ok().and_then(|lit| lit.str()) } } - -pub trait AttributeExt: Debug { - fn id(&self) -> AttrId; - - /// 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; - - /// Get the meta item list, `#[attr(meta item list)]` - fn meta_item_list(&self) -> Option>; - - /// Gets the value literal, as string, when using `#[attr = value]` - fn value_str(&self) -> Option; - - /// Gets the span of the value literal, as string, when using `#[attr = value]` - fn value_span(&self) -> Option; - - /// Checks whether the path of this attribute matches the name. - /// - /// Matches one segment of the path to each element in `name` - fn path_matches(&self, name: &[Symbol]) -> bool; - - /// Returns `true` if it is a sugared doc comment (`///` or `//!` for example). - /// So `#[doc = "doc"]` (which is a doc comment) and `#[doc(...)]` (which is not - /// a doc comment) will return `false`. - fn is_doc_comment(&self) -> Option; - - /// Returns true if the attribute's first *and only* path segment is equal to the passed-in - /// symbol. - #[inline] - fn has_name(&self, name: Symbol) -> bool { - self.name().map(|x| x == name).unwrap_or(false) - } - - /// Returns true if the attribute's first *and only* path segment is any of the passed-in - /// symbols. - #[inline] - fn has_any_name(&self, names: &[Symbol]) -> bool { - names.iter().any(|&name| self.has_name(name)) - } - - /// get the span of the entire attribute - fn span(&self) -> Span; - - /// Returns whether the attribute is a path, without any arguments. - fn is_word(&self) -> bool; - - fn path(&self) -> SmallVec<[Symbol; 1]> { - self.symbol_path().unwrap_or(smallvec![sym::doc]) - } - - fn path_span(&self) -> Option; - - /// Returns None for doc comments - fn symbol_path(&self) -> Option>; - - /// Returns the documentation if this is a doc comment or a sugared doc comment. - /// * `///doc` returns `Some("doc")`. - /// * `#[doc = "doc"]` returns `Some("doc")`. - /// * `#[doc(...)]` returns `None`. - fn doc_str(&self) -> Option; - - /// Returns the deprecation note if this is deprecation attribute. - /// * `#[deprecated = "note"]` returns `Some("note")`. - /// * `#[deprecated(note = "note", ...)]` returns `Some("note")`. - fn deprecation_note(&self) -> Option; - - /// Returns whether this attribute is any of the proc macro attributes. - /// i.e. `proc_macro`, `proc_macro_attribute` or `proc_macro_derive`. - fn is_proc_macro_attr(&self) -> bool { - [sym::proc_macro, sym::proc_macro_attribute, sym::proc_macro_derive] - .iter() - .any(|kind| self.has_name(*kind)) - } - /// Returns true if this attribute is `#[automatically_deived]`. - fn is_automatically_derived_attr(&self) -> bool; - - /// Returns the documentation and its kind if this is a doc comment or a sugared doc comment. - /// * `///doc` returns `Some(("doc", CommentKind::Line))`. - /// * `/** doc */` returns `Some(("doc", CommentKind::Block))`. - /// * `#[doc = "doc"]` returns `Some(("doc", CommentKind::Line))`. - /// * `#[doc(...)]` returns `None`. - fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)>; - - /// Returns outer or inner if this is a doc attribute or a sugared doc - /// comment, otherwise None. - /// - /// This is used in the case of doc comments on modules, to decide whether - /// to resolve intra-doc links against the symbols in scope within the - /// commented module (for inner doc) vs within its parent module (for outer - /// doc). - fn doc_resolution_scope(&self) -> Option; - - /// Returns `true` if this attribute contains `doc(hidden)`. - fn is_doc_hidden(&self) -> bool; - - /// Returns `true` is this attribute contains `doc(keyword)` or `doc(attribute)`. - fn is_doc_keyword_or_attribute(&self) -> bool; - - /// Returns `true` if this is a `#[rustc_doc_primitive]` attribute. - fn is_rustc_doc_primitive(&self) -> bool; -} - -// FIXME(fn_delegation): use function delegation instead of manually forwarding - -impl Attribute { - pub fn id(&self) -> AttrId { - AttributeExt::id(self) - } - - pub fn name(&self) -> Option { - AttributeExt::name(self) - } - - pub fn meta_item_list(&self) -> Option> { - AttributeExt::meta_item_list(self) - } - - pub fn value_str(&self) -> Option { - AttributeExt::value_str(self) - } - - pub fn value_span(&self) -> Option { - AttributeExt::value_span(self) - } - - pub fn path_matches(&self, name: &[Symbol]) -> bool { - AttributeExt::path_matches(self, name) - } - - // on ast attributes we return a bool since that's what most code already expects - pub fn is_doc_comment(&self) -> bool { - AttributeExt::is_doc_comment(self).is_some() - } - - #[inline] - pub fn has_name(&self, name: Symbol) -> bool { - AttributeExt::has_name(self, name) - } - - #[inline] - pub fn has_any_name(&self, names: &[Symbol]) -> bool { - AttributeExt::has_any_name(self, names) - } - - pub fn span(&self) -> Span { - AttributeExt::span(self) - } - - pub fn is_word(&self) -> bool { - AttributeExt::is_word(self) - } - - pub fn path(&self) -> SmallVec<[Symbol; 1]> { - AttributeExt::path(self) - } - - pub fn doc_str(&self) -> Option { - AttributeExt::doc_str(self) - } - - pub fn is_proc_macro_attr(&self) -> bool { - AttributeExt::is_proc_macro_attr(self) - } - - pub fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> { - AttributeExt::doc_str_and_fragment_kind(self) - } -} diff --git a/compiler/rustc_attr_parsing/src/attributes/util.rs b/compiler/rustc_attr_parsing/src/attributes/util.rs index 4bd9b2b963e9a..887ec3c905362 100644 --- a/compiler/rustc_attr_parsing/src/attributes/util.rs +++ b/compiler/rustc_attr_parsing/src/attributes/util.rs @@ -1,7 +1,6 @@ use std::num::IntErrorKind; -use rustc_ast::LitKind; -use rustc_ast::attr::AttributeExt; +use rustc_ast as ast; use rustc_feature::is_builtin_attr_name; use rustc_hir::RustcVersion; use rustc_hir::limit::Limit; @@ -27,8 +26,8 @@ pub fn parse_version(s: Symbol) -> Option { Some(RustcVersion { major, minor, patch }) } -pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool { - attr.is_doc_comment().is_some() || attr.name().is_some_and(|name| is_builtin_attr_name(name)) +pub fn is_builtin_attr(attr: &ast::Attribute) -> bool { + attr.is_doc_comment() || attr.name().is_some_and(|name| is_builtin_attr_name(name)) } /// Parse a single integer. @@ -54,7 +53,7 @@ pub(crate) fn parse_single_integer( cx.adcx().expected_integer_literal(single.span()); return None; }; - let LitKind::Int(num, _ty) = lit.kind else { + let ast::LitKind::Int(num, _ty) = lit.kind else { cx.adcx().expected_integer_literal(single.span()); return None; }; diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 71ef6c9a9c03c..67a767b3464b0 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -4,7 +4,6 @@ use std::fmt; use std::ops::Not; use rustc_abi::ExternAbi; -use rustc_ast::attr::AttributeExt; use rustc_ast::token::DocFragmentKind; use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::{ @@ -27,7 +26,7 @@ use rustc_span::{ BytePos, DUMMY_SP, DesugaringKind, ErrorGuaranteed, Ident, Span, Spanned, Symbol, kw, sym, }; use rustc_target::asm::InlineAsmRegOrRegClass; -use smallvec::SmallVec; +use smallvec::{SmallVec, smallvec}; use thin_vec::ThinVec; use tracing::debug; @@ -1257,8 +1256,6 @@ pub struct HashIgnoredAttrId { pub attr_id: AttrId, } -/// Many functions on this type have their documentation in the [`AttributeExt`] trait, -/// since they defer their implementation directly to that trait. #[derive(Clone, Debug, Encodable, Decodable, HashStable_Generic)] pub enum Attribute { /// A parsed built-in attribute. @@ -1319,9 +1316,9 @@ impl Attribute { } } -impl AttributeExt for Attribute { +impl Attribute { #[inline] - fn id(&self) -> AttrId { + pub fn id(&self) -> AttrId { match &self { Attribute::Unparsed(u) => u.id.attr_id, _ => panic!(), @@ -1329,7 +1326,7 @@ impl AttributeExt for Attribute { } #[inline] - fn meta_item_list(&self) -> Option> { + pub fn meta_item_list(&self) -> Option> { match &self { Attribute::Unparsed(n) => match n.as_ref() { AttrItem { args: AttrArgs::Delimited(d), .. } => { @@ -1342,18 +1339,18 @@ impl AttributeExt for Attribute { } #[inline] - fn value_str(&self) -> Option { + pub fn value_str(&self) -> Option { self.value_lit().and_then(|x| x.value_str()) } #[inline] - fn value_span(&self) -> Option { + pub fn value_span(&self) -> Option { self.value_lit().map(|i| i.span) } /// For a single-segment attribute, returns its name; otherwise, returns `None`. #[inline] - fn name(&self) -> Option { + pub fn name(&self) -> Option { match &self { Attribute::Unparsed(n) => { if let [ident] = n.path.segments.as_ref() { @@ -1367,7 +1364,12 @@ impl AttributeExt for Attribute { } #[inline] - fn path_matches(&self, name: &[Symbol]) -> bool { + pub fn has_name(&self, name: Symbol) -> bool { + self.name().map(|x| x == name).unwrap_or(false) + } + + #[inline] + pub fn path_matches(&self, name: &[Symbol]) -> bool { match &self { Attribute::Unparsed(n) => n.path.segments.iter().eq(name), _ => false, @@ -1375,16 +1377,12 @@ impl AttributeExt for Attribute { } #[inline] - fn is_doc_comment(&self) -> Option { - if let Attribute::Parsed(AttributeKind::DocComment { span, .. }) = self { - Some(*span) - } else { - None - } + pub fn is_doc_comment(&self) -> bool { + matches!(self, Attribute::Parsed(AttributeKind::DocComment { .. })) } #[inline] - fn span(&self) -> Span { + pub fn span(&self) -> Span { match &self { Attribute::Unparsed(u) => u.span, // FIXME: should not be needed anymore when all attrs are parsed @@ -1397,7 +1395,7 @@ impl AttributeExt for Attribute { } #[inline] - fn is_word(&self) -> bool { + pub fn is_word(&self) -> bool { match &self { Attribute::Unparsed(n) => { matches!(n.args, AttrArgs::Empty) @@ -1407,14 +1405,14 @@ impl AttributeExt for Attribute { } #[inline] - fn symbol_path(&self) -> Option> { + pub fn symbol_path(&self) -> Option> { match &self { Attribute::Unparsed(n) => Some(n.path.segments.iter().copied().collect()), _ => None, } } - fn path_span(&self) -> Option { + pub fn path_span(&self) -> Option { match &self { Attribute::Unparsed(attr) => Some(attr.path.span), Attribute::Parsed(_) => None, @@ -1422,7 +1420,7 @@ impl AttributeExt for Attribute { } #[inline] - fn doc_str(&self) -> Option { + pub fn doc_str(&self) -> Option { match &self { Attribute::Parsed(AttributeKind::DocComment { comment, .. }) => Some(*comment), _ => None, @@ -1430,19 +1428,19 @@ impl AttributeExt for Attribute { } #[inline] - fn deprecation_note(&self) -> Option { + pub fn deprecation_note(&self) -> Option { match &self { Attribute::Parsed(AttributeKind::Deprecated { deprecation, .. }) => deprecation.note, _ => None, } } - fn is_automatically_derived_attr(&self) -> bool { + pub fn is_automatically_derived_attr(&self) -> bool { matches!(self, Attribute::Parsed(AttributeKind::AutomaticallyDerived(..))) } #[inline] - fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> { + pub fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> { match &self { Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => { Some((*comment, *kind)) @@ -1451,7 +1449,7 @@ impl AttributeExt for Attribute { } } - fn doc_resolution_scope(&self) -> Option { + pub fn doc_resolution_scope(&self) -> Option { match self { Attribute::Parsed(AttributeKind::DocComment { style, .. }) => Some(*style), Attribute::Unparsed(attr) if self.has_name(sym::doc) && self.value_str().is_some() => { @@ -1461,7 +1459,7 @@ impl AttributeExt for Attribute { } } - fn is_proc_macro_attr(&self) -> bool { + pub fn is_proc_macro_attr(&self) -> bool { matches!( self, Attribute::Parsed( @@ -1472,94 +1470,25 @@ impl AttributeExt for Attribute { ) } - fn is_doc_hidden(&self) -> bool { + pub fn is_doc_hidden(&self) -> bool { matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.hidden.is_some()) } - fn is_doc_keyword_or_attribute(&self) -> bool { + pub fn is_doc_keyword_or_attribute(&self) -> bool { matches!(self, Attribute::Parsed(AttributeKind::Doc(d)) if d.attribute.is_some() || d.keyword.is_some()) } - fn is_rustc_doc_primitive(&self) -> bool { + pub fn is_rustc_doc_primitive(&self) -> bool { matches!(self, Attribute::Parsed(AttributeKind::RustcDocPrimitive(..))) } -} - -// FIXME(fn_delegation): use function delegation instead of manually forwarding -impl Attribute { - #[inline] - pub fn id(&self) -> AttrId { - AttributeExt::id(self) - } - - #[inline] - pub fn name(&self) -> Option { - AttributeExt::name(self) - } - - #[inline] - pub fn meta_item_list(&self) -> Option> { - AttributeExt::meta_item_list(self) - } - - #[inline] - pub fn value_str(&self) -> Option { - AttributeExt::value_str(self) - } - - #[inline] - pub fn value_span(&self) -> Option { - AttributeExt::value_span(self) - } - - #[inline] - pub fn path_matches(&self, name: &[Symbol]) -> bool { - AttributeExt::path_matches(self, name) - } - - #[inline] - pub fn is_doc_comment(&self) -> Option { - AttributeExt::is_doc_comment(self) - } - - #[inline] - pub fn has_name(&self, name: Symbol) -> bool { - AttributeExt::has_name(self, name) - } #[inline] pub fn has_any_name(&self, names: &[Symbol]) -> bool { - AttributeExt::has_any_name(self, names) - } - - #[inline] - pub fn span(&self) -> Span { - AttributeExt::span(self) + names.iter().any(|&name| self.has_name(name)) } - #[inline] - pub fn is_word(&self) -> bool { - AttributeExt::is_word(self) - } - - #[inline] pub fn path(&self) -> SmallVec<[Symbol; 1]> { - AttributeExt::path(self) - } - - #[inline] - pub fn doc_str(&self) -> Option { - AttributeExt::doc_str(self) - } - - #[inline] - pub fn is_proc_macro_attr(&self) -> bool { - AttributeExt::is_proc_macro_attr(self) - } - - #[inline] - pub fn doc_str_and_fragment_kind(&self) -> Option<(Symbol, DocFragmentKind)> { - AttributeExt::doc_str_and_fragment_kind(self) + self.symbol_path().unwrap_or(smallvec![sym::doc]) } } diff --git a/compiler/rustc_middle/src/ich/impls_syntax.rs b/compiler/rustc_middle/src/ich/impls_syntax.rs index d932bfdee6ef6..1d9b0044e8e75 100644 --- a/compiler/rustc_middle/src/ich/impls_syntax.rs +++ b/compiler/rustc_middle/src/ich/impls_syntax.rs @@ -27,7 +27,7 @@ impl<'a> HashStable> for [hir::Attribute] { let filtered: SmallVec<[&hir::Attribute; 8]> = self .iter() .filter(|attr| { - attr.is_doc_comment().is_none() + !attr.is_doc_comment() // FIXME(jdonszelmann) have a better way to handle ignored attrs && !attr.name().is_some_and(|ident| is_ignored_attr(ident)) }) diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 89b561bd2e901..e8547bb22a347 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -8,7 +8,6 @@ use pulldown_cmark::{ BrokenLink, BrokenLinkCallback, CowStr, Event, LinkType, Options, Parser, Tag, }; use rustc_ast as ast; -use rustc_ast::attr::AttributeExt; use rustc_ast::join_path_syms; use rustc_ast::token::DocFragmentKind; use rustc_ast::util::comments::beautify_doc_string; @@ -197,14 +196,15 @@ pub fn add_doc_fragment(out: &mut String, frag: &DocFragment) { } } -pub fn attrs_to_doc_fragments<'a, A: AttributeExt + Clone + 'a>( - attrs: impl Iterator)>, +pub fn attrs_to_doc_fragments<'a>( + attrs: impl Iterator)>, doc_only: bool, -) -> (Vec, ThinVec) { +) -> (Vec, ThinVec) { let (min_size, max_size) = attrs.size_hint(); let size_hint = max_size.unwrap_or(min_size); let mut doc_fragments = Vec::with_capacity(size_hint); - let mut other_attrs = ThinVec::::with_capacity(if doc_only { 0 } else { size_hint }); + let mut other_attrs = + ThinVec::::with_capacity(if doc_only { 0 } else { size_hint }); for (attr, item_id) in attrs { if let Some((doc_str, fragment_kind)) = attr.doc_str_and_fragment_kind() { let doc = beautify_doc_string(doc_str, fragment_kind.comment_kind()); @@ -355,7 +355,7 @@ pub fn strip_generics_from_path(path_str: &str) -> Result, MalformedGen /// /// If there are no doc-comments, return true. /// FIXME(#78591): Support both inner and outer attributes on the same item. -pub fn inner_docs(attrs: &[impl AttributeExt]) -> bool { +pub fn inner_docs(attrs: &[ast::Attribute]) -> bool { for attr in attrs { if let Some(attr_style) = attr.doc_resolution_scope() { return attr_style == ast::AttrStyle::Inner; @@ -365,7 +365,7 @@ pub fn inner_docs(attrs: &[impl AttributeExt]) -> bool { } /// Has `#[rustc_doc_primitive]` or `#[doc(keyword)]` or `#[doc(attribute)]`. -pub fn has_primitive_or_keyword_or_attribute_docs(attrs: &[impl AttributeExt]) -> bool { +pub fn has_primitive_or_keyword_or_attribute_docs(attrs: &[ast::Attribute]) -> bool { for attr in attrs { if attr.is_rustc_doc_primitive() || attr.is_doc_keyword_or_attribute() { return true; @@ -409,7 +409,7 @@ pub fn may_be_doc_link(link_type: LinkType) -> bool { /// Simplified version of `preprocessed_markdown_links` from rustdoc. /// Must return at least the same links as it, but may add some more links on top of that. -pub(crate) fn attrs_to_preprocessed_links(attrs: &[A]) -> Vec> { +pub(crate) fn attrs_to_preprocessed_links(attrs: &[ast::Attribute]) -> Vec> { let (doc_fragments, other_attrs) = attrs_to_doc_fragments(attrs.iter().map(|attr| (attr, None)), false); let mut doc =