@@ -226,15 +226,28 @@ impl ExternalCrate {
226
226
}
227
227
228
228
pub ( crate ) fn keywords ( & self , tcx : TyCtxt < ' _ > ) -> impl Iterator < Item = ( DefId , Symbol ) > {
229
- fn as_keyword ( did : DefId , tcx : TyCtxt < ' _ > ) -> Option < ( DefId , Symbol ) > {
229
+ self . retrieve_keywords_or_documented_attributes ( tcx, sym:: keyword)
230
+ }
231
+ pub ( crate ) fn documented_attributes (
232
+ & self ,
233
+ tcx : TyCtxt < ' _ > ,
234
+ ) -> impl Iterator < Item = ( DefId , Symbol ) > {
235
+ self . retrieve_keywords_or_documented_attributes ( tcx, sym:: attribute)
236
+ }
237
+
238
+ fn retrieve_keywords_or_documented_attributes (
239
+ & self ,
240
+ tcx : TyCtxt < ' _ > ,
241
+ name : Symbol ,
242
+ ) -> impl Iterator < Item = ( DefId , Symbol ) > {
243
+ let as_target = move |did : DefId , tcx : TyCtxt < ' _ > | -> Option < ( DefId , Symbol ) > {
230
244
tcx. get_attrs ( did, sym:: doc)
231
245
. flat_map ( |attr| attr. meta_item_list ( ) . unwrap_or_default ( ) )
232
- . filter ( |meta| meta. has_name ( sym :: keyword ) )
246
+ . filter ( |meta| meta. has_name ( name ) )
233
247
. find_map ( |meta| meta. value_str ( ) )
234
248
. map ( |value| ( did, value) )
235
- }
236
-
237
- self . mapped_root_modules ( tcx, as_keyword)
249
+ } ;
250
+ self . mapped_root_modules ( tcx, as_target)
238
251
}
239
252
240
253
pub ( crate ) fn primitives (
@@ -592,6 +605,9 @@ impl Item {
592
605
pub ( crate ) fn is_keyword ( & self ) -> bool {
593
606
self . type_ ( ) == ItemType :: Keyword
594
607
}
608
+ pub ( crate ) fn is_attribute ( & self ) -> bool {
609
+ self . type_ ( ) == ItemType :: Attribute
610
+ }
595
611
pub ( crate ) fn is_stripped ( & self ) -> bool {
596
612
match self . kind {
597
613
StrippedItem ( ..) => true ,
@@ -735,7 +751,9 @@ impl Item {
735
751
// Primitives and Keywords are written in the source code as private modules.
736
752
// The modules need to be private so that nobody actually uses them, but the
737
753
// keywords and primitives that they are documenting are public.
738
- ItemKind :: KeywordItem | ItemKind :: PrimitiveItem ( _) => return Some ( Visibility :: Public ) ,
754
+ ItemKind :: KeywordItem | ItemKind :: PrimitiveItem ( _) | ItemKind :: AttributeItem => {
755
+ return Some ( Visibility :: Public ) ;
756
+ }
739
757
// Variant fields inherit their enum's visibility.
740
758
StructFieldItem ( ..) if is_field_vis_inherited ( tcx, def_id) => {
741
759
return None ;
@@ -942,7 +960,12 @@ pub(crate) enum ItemKind {
942
960
AssocTypeItem ( Box < TypeAlias > , Vec < GenericBound > ) ,
943
961
/// An item that has been stripped by a rustdoc pass
944
962
StrippedItem ( Box < ItemKind > ) ,
963
+ /// This item represents a module with a `#[doc(keyword = "...")]` attribute which is used
964
+ /// to generate documentation for Rust keywords.
945
965
KeywordItem ,
966
+ /// This item represents a module with a `#[doc(attribute = "...")]` attribute which is used
967
+ /// to generate documentation for Rust builtin attributes.
968
+ AttributeItem ,
946
969
}
947
970
948
971
impl ItemKind {
@@ -983,7 +1006,8 @@ impl ItemKind {
983
1006
| RequiredAssocTypeItem ( ..)
984
1007
| AssocTypeItem ( ..)
985
1008
| StrippedItem ( _)
986
- | KeywordItem => [ ] . iter ( ) ,
1009
+ | KeywordItem
1010
+ | AttributeItem => [ ] . iter ( ) ,
987
1011
}
988
1012
}
989
1013
0 commit comments