@@ -759,48 +759,9 @@ impl Item {
759759 Some ( tcx. visibility ( def_id) )
760760 }
761761
762- pub ( crate ) fn attributes ( & self , tcx : TyCtxt < ' _ > , cache : & Cache , is_json : bool ) -> Vec < String > {
763- const ALLOWED_ATTRIBUTES : & [ Symbol ] =
764- & [ sym:: export_name, sym:: link_section, sym:: no_mangle, sym:: non_exhaustive] ;
765-
762+ fn adt_item_extra_attrs ( & self , tcx : TyCtxt < ' _ > , document_private : bool ) -> Option < String > {
766763 use rustc_abi:: IntegerType ;
767764
768- let mut attrs: Vec < String > = self
769- . attrs
770- . other_attrs
771- . iter ( )
772- . filter_map ( |attr| {
773- if is_json {
774- match attr {
775- hir:: Attribute :: Parsed ( AttributeKind :: Deprecation { .. } ) => {
776- // rustdoc-json stores this in `Item::deprecation`, so we
777- // don't want it it `Item::attrs`.
778- None
779- }
780- rustc_hir:: Attribute :: Parsed ( rustc_attr_parsing:: AttributeKind :: Repr (
781- ..,
782- ) ) => {
783- // We have separate pretty-printing logic for `#[repr(..)]` attributes.
784- // For example, there are circumstances where `#[repr(transparent)]`
785- // is applied but should not be publicly shown in rustdoc
786- // because it isn't public API.
787- None
788- }
789- _ => Some ( rustc_hir_pretty:: attribute_to_string ( & tcx, attr) ) ,
790- }
791- } else if attr. has_any_name ( ALLOWED_ATTRIBUTES ) {
792- Some (
793- rustc_hir_pretty:: attribute_to_string ( & tcx, attr)
794- . replace ( "\\ \n " , "" )
795- . replace ( '\n' , "" )
796- . replace ( " " , " " ) ,
797- )
798- } else {
799- None
800- }
801- } )
802- . collect ( ) ;
803-
804765 // Add #[repr(...)]
805766 if let Some ( def_id) = self . def_id ( )
806767 && let ItemType :: Struct | ItemType :: Enum | ItemType :: Union = self . type_ ( )
@@ -814,7 +775,7 @@ impl Item {
814775 if repr. transparent ( ) {
815776 // Render `repr(transparent)` iff the non-1-ZST field is public or at least one
816777 // field is public in case all fields are 1-ZST fields.
817- let render_transparent = cache . document_private
778+ let render_transparent = document_private
818779 || adt
819780 . all_fields ( )
820781 . find ( |field| {
@@ -860,10 +821,55 @@ impl Item {
860821 out. push ( & int_s) ;
861822 }
862823 if !out. is_empty ( ) {
863- attrs . push ( format ! ( "#[repr({})]" , out. join( ", " ) ) ) ;
824+ return Some ( format ! ( "#[repr({})]" , out. join( ", " ) ) ) ;
864825 }
865826 }
866- attrs
827+ None
828+ }
829+
830+ pub ( crate ) fn attributes (
831+ & self ,
832+ tcx : TyCtxt < ' _ > ,
833+ cache : & Cache ,
834+ is_json : bool ,
835+ ) -> impl Iterator < Item = String > {
836+ const ALLOWED_ATTRIBUTES : & [ Symbol ] =
837+ & [ sym:: export_name, sym:: link_section, sym:: no_mangle, sym:: non_exhaustive] ;
838+
839+ self . attrs
840+ . other_attrs
841+ . iter ( )
842+ . filter_map ( move |attr| {
843+ if is_json {
844+ match attr {
845+ hir:: Attribute :: Parsed ( AttributeKind :: Deprecation { .. } ) => {
846+ // rustdoc-json stores this in `Item::deprecation`, so we
847+ // don't want it it `Item::attrs`.
848+ None
849+ }
850+ rustc_hir:: Attribute :: Parsed ( rustc_attr_parsing:: AttributeKind :: Repr (
851+ ..,
852+ ) ) => {
853+ // We have separate pretty-printing logic for `#[repr(..)]` attributes.
854+ // For example, there are circumstances where `#[repr(transparent)]`
855+ // is applied but should not be publicly shown in rustdoc
856+ // because it isn't public API.
857+ None
858+ }
859+ _ => Some ( rustc_hir_pretty:: attribute_to_string ( & tcx, attr) ) ,
860+ }
861+ } else if attr. has_any_name ( ALLOWED_ATTRIBUTES ) {
862+ let attr = rustc_hir_pretty:: attribute_to_string ( & tcx, attr) ;
863+ Some ( if attr. contains ( [ '\n' , '\\' ] ) || attr. contains ( " " ) {
864+ attr. replace ( "\\ \n " , "" ) . replace ( '\n' , "" ) . replace ( " " , " " )
865+ } else {
866+ attr
867+ } )
868+ } else {
869+ None
870+ }
871+ } )
872+ . chain ( AttrIterator :: new ( self , cache. document_private , tcx) )
867873 }
868874
869875 pub fn is_doc_hidden ( & self ) -> bool {
@@ -875,6 +881,32 @@ impl Item {
875881 }
876882}
877883
884+ struct AttrIterator < ' a , ' tcx > {
885+ item : & ' a Item ,
886+ document_private : bool ,
887+ tcx : TyCtxt < ' tcx > ,
888+ done : bool ,
889+ }
890+
891+ impl < ' a , ' tcx > AttrIterator < ' a , ' tcx > {
892+ fn new ( item : & ' a Item , document_private : bool , tcx : TyCtxt < ' tcx > ) -> Self {
893+ Self { item, document_private, tcx, done : false }
894+ }
895+ }
896+
897+ impl < ' a , ' tcx > Iterator for AttrIterator < ' a , ' tcx > {
898+ type Item = String ;
899+
900+ fn next ( & mut self ) -> Option < Self :: Item > {
901+ if self . done {
902+ None
903+ } else {
904+ self . done = true ;
905+ self . item . adt_item_extra_attrs ( self . tcx , self . document_private )
906+ }
907+ }
908+ }
909+
878910#[ derive( Clone , Debug ) ]
879911pub ( crate ) enum ItemKind {
880912 ExternCrateItem {
0 commit comments