diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2025-06-13 21:01:59 +0200 |
|---|---|---|
| committer | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2025-08-28 15:56:29 +0200 |
| commit | ab0ee84eac9732e4e81e559c688846b4c1bd400a (patch) | |
| tree | c0da1c969d5c0729532b1bc435cb6147cb4e0dcf /src/librustdoc/clean | |
| parent | b41634205b549a62cfa55363d1e00c4143d30033 (diff) | |
| download | rust-ab0ee84eac9732e4e81e559c688846b4c1bd400a.tar.gz rust-ab0ee84eac9732e4e81e559c688846b4c1bd400a.zip | |
Add new `doc(attribute = "...")` attribute
Diffstat (limited to 'src/librustdoc/clean')
| -rw-r--r-- | src/librustdoc/clean/types.rs | 38 | ||||
| -rw-r--r-- | src/librustdoc/clean/utils.rs | 4 |
2 files changed, 35 insertions, 7 deletions
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 92bd4a498ca..1502ec9bd78 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -226,15 +226,28 @@ impl ExternalCrate { } pub(crate) fn keywords(&self, tcx: TyCtxt<'_>) -> impl Iterator<Item = (DefId, Symbol)> { - fn as_keyword(did: DefId, tcx: TyCtxt<'_>) -> Option<(DefId, Symbol)> { + self.retrieve_keywords_or_documented_attributes(tcx, sym::keyword) + } + pub(crate) fn documented_attributes( + &self, + tcx: TyCtxt<'_>, + ) -> impl Iterator<Item = (DefId, Symbol)> { + self.retrieve_keywords_or_documented_attributes(tcx, sym::attribute) + } + + fn retrieve_keywords_or_documented_attributes( + &self, + tcx: TyCtxt<'_>, + name: Symbol, + ) -> impl Iterator<Item = (DefId, Symbol)> { + let as_target = move |did: DefId, tcx: TyCtxt<'_>| -> Option<(DefId, Symbol)> { tcx.get_attrs(did, sym::doc) .flat_map(|attr| attr.meta_item_list().unwrap_or_default()) - .filter(|meta| meta.has_name(sym::keyword)) + .filter(|meta| meta.has_name(name)) .find_map(|meta| meta.value_str()) .map(|value| (did, value)) - } - - self.mapped_root_modules(tcx, as_keyword) + }; + self.mapped_root_modules(tcx, as_target) } pub(crate) fn primitives( @@ -592,6 +605,9 @@ impl Item { pub(crate) fn is_keyword(&self) -> bool { self.type_() == ItemType::Keyword } + pub(crate) fn is_attribute(&self) -> bool { + self.type_() == ItemType::Attribute + } pub(crate) fn is_stripped(&self) -> bool { match self.kind { StrippedItem(..) => true, @@ -735,7 +751,9 @@ impl Item { // Primitives and Keywords are written in the source code as private modules. // The modules need to be private so that nobody actually uses them, but the // keywords and primitives that they are documenting are public. - ItemKind::KeywordItem | ItemKind::PrimitiveItem(_) => return Some(Visibility::Public), + ItemKind::KeywordItem | ItemKind::PrimitiveItem(_) | ItemKind::AttributeItem => { + return Some(Visibility::Public); + } // Variant fields inherit their enum's visibility. StructFieldItem(..) if is_field_vis_inherited(tcx, def_id) => { return None; @@ -942,7 +960,12 @@ pub(crate) enum ItemKind { AssocTypeItem(Box<TypeAlias>, Vec<GenericBound>), /// An item that has been stripped by a rustdoc pass StrippedItem(Box<ItemKind>), + /// This item represents a module with a `#[doc(keyword = "...")]` attribute which is used + /// to generate documentation for Rust keywords. KeywordItem, + /// This item represents a module with a `#[doc(attribute = "...")]` attribute which is used + /// to generate documentation for Rust builtin attributes. + AttributeItem, } impl ItemKind { @@ -983,7 +1006,8 @@ impl ItemKind { | RequiredAssocTypeItem(..) | AssocTypeItem(..) | StrippedItem(_) - | KeywordItem => [].iter(), + | KeywordItem + | AttributeItem => [].iter(), } } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 813fdee57e1..6fc1e43c724 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -60,6 +60,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate { let local_crate = ExternalCrate { crate_num: LOCAL_CRATE }; let primitives = local_crate.primitives(cx.tcx); let keywords = local_crate.keywords(cx.tcx); + let documented_attributes = local_crate.documented_attributes(cx.tcx); { let ItemKind::ModuleItem(m) = &mut module.inner.kind else { unreachable!() }; m.items.extend(primitives.map(|(def_id, prim)| { @@ -73,6 +74,9 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate { m.items.extend(keywords.map(|(def_id, kw)| { Item::from_def_id_and_parts(def_id, Some(kw), ItemKind::KeywordItem, cx) })); + m.items.extend(documented_attributes.into_iter().map(|(def_id, kw)| { + Item::from_def_id_and_parts(def_id, Some(kw), ItemKind::AttributeItem, cx) + })); } Crate { module, external_traits: Box::new(mem::take(&mut cx.external_traits)) } |
