@@ -228,15 +228,28 @@ impl ExternalCrate {
228
228
}
229
229
230
230
pub ( crate ) fn keywords ( & self , tcx : TyCtxt < ' _ > ) -> impl Iterator < Item = ( DefId , Symbol ) > {
231
- fn as_keyword ( did : DefId , tcx : TyCtxt < ' _ > ) -> Option < ( DefId , Symbol ) > {
231
+ self . retrieve_keywords_or_documented_attributes ( tcx, sym:: keyword)
232
+ }
233
+ pub ( crate ) fn documented_attributes (
234
+ & self ,
235
+ tcx : TyCtxt < ' _ > ,
236
+ ) -> impl Iterator < Item = ( DefId , Symbol ) > {
237
+ self . retrieve_keywords_or_documented_attributes ( tcx, sym:: attribute)
238
+ }
239
+
240
+ fn retrieve_keywords_or_documented_attributes (
241
+ & self ,
242
+ tcx : TyCtxt < ' _ > ,
243
+ name : Symbol ,
244
+ ) -> impl Iterator < Item = ( DefId , Symbol ) > {
245
+ let as_target = move |did : DefId , tcx : TyCtxt < ' _ > | -> Option < ( DefId , Symbol ) > {
232
246
tcx. get_attrs ( did, sym:: doc)
233
247
. flat_map ( |attr| attr. meta_item_list ( ) . unwrap_or_default ( ) )
234
- . filter ( |meta| meta. has_name ( sym :: keyword ) )
248
+ . filter ( |meta| meta. has_name ( name ) )
235
249
. find_map ( |meta| meta. value_str ( ) )
236
250
. map ( |value| ( did, value) )
237
- }
238
-
239
- self . mapped_root_modules ( tcx, as_keyword)
251
+ } ;
252
+ self . mapped_root_modules ( tcx, as_target)
240
253
}
241
254
242
255
pub ( crate ) fn primitives (
@@ -579,6 +592,9 @@ impl Item {
579
592
pub ( crate ) fn is_keyword ( & self ) -> bool {
580
593
self . type_ ( ) == ItemType :: Keyword
581
594
}
595
+ pub ( crate ) fn is_attribute ( & self ) -> bool {
596
+ self . type_ ( ) == ItemType :: Attribute
597
+ }
582
598
pub ( crate ) fn is_stripped ( & self ) -> bool {
583
599
match self . kind {
584
600
StrippedItem ( ..) => true ,
@@ -722,7 +738,9 @@ impl Item {
722
738
// Primitives and Keywords are written in the source code as private modules.
723
739
// The modules need to be private so that nobody actually uses them, but the
724
740
// keywords and primitives that they are documenting are public.
725
- ItemKind :: KeywordItem | ItemKind :: PrimitiveItem ( _) => return Some ( Visibility :: Public ) ,
741
+ ItemKind :: KeywordItem | ItemKind :: PrimitiveItem ( _) | ItemKind :: AttributeItem => {
742
+ return Some ( Visibility :: Public ) ;
743
+ }
726
744
// Variant fields inherit their enum's visibility.
727
745
StructFieldItem ( ..) if is_field_vis_inherited ( tcx, def_id) => {
728
746
return None ;
@@ -959,7 +977,12 @@ pub(crate) enum ItemKind {
959
977
AssocTypeItem ( Box < TypeAlias > , Vec < GenericBound > ) ,
960
978
/// An item that has been stripped by a rustdoc pass
961
979
StrippedItem ( Box < ItemKind > ) ,
980
+ /// This item represents a module with a `#[doc(keyword = "...")]` attribute which is used
981
+ /// to generate documentation for Rust keywords.
962
982
KeywordItem ,
983
+ /// This item represents a module with a `#[doc(attribute = "...")]` attribute which is used
984
+ /// to generate documentation for Rust builtin attributes.
985
+ AttributeItem ,
963
986
}
964
987
965
988
impl ItemKind {
@@ -1000,7 +1023,8 @@ impl ItemKind {
1000
1023
| RequiredAssocTypeItem ( ..)
1001
1024
| AssocTypeItem ( ..)
1002
1025
| StrippedItem ( _)
1003
- | KeywordItem => [ ] . iter ( ) ,
1026
+ | KeywordItem
1027
+ | AttributeItem => [ ] . iter ( ) ,
1004
1028
}
1005
1029
}
1006
1030
0 commit comments