@@ -764,14 +764,11 @@ impl Item {
764764 Some ( tcx. visibility ( def_id) )
765765 }
766766
767- pub ( crate ) fn attributes ( & self , tcx : TyCtxt < ' _ > , cache : & Cache , is_json : bool ) -> Vec < String > {
767+ pub ( crate ) fn attributes_witout_repr ( & self , tcx : TyCtxt < ' _ > , is_json : bool ) -> Vec < String > {
768768 const ALLOWED_ATTRIBUTES : & [ Symbol ] =
769769 & [ sym:: export_name, sym:: link_section, sym:: no_mangle, sym:: non_exhaustive] ;
770770
771- use rustc_abi:: IntegerType ;
772-
773- let mut attrs: Vec < String > = self
774- . attrs
771+ self . attrs
775772 . other_attrs
776773 . iter ( )
777774 . filter_map ( |attr| {
@@ -799,74 +796,88 @@ impl Item {
799796 None
800797 }
801798 } )
802- . collect ( ) ;
799+ . collect ( )
800+ }
803801
804- // Add #[repr(...)]
805- if let Some ( def_id) = self . def_id ( )
806- && let ItemType :: Struct | ItemType :: Enum | ItemType :: Union = self . type_ ( )
807- {
808- let adt = tcx. adt_def ( def_id) ;
809- let repr = adt. repr ( ) ;
810- let mut out = Vec :: new ( ) ;
811- if repr. c ( ) {
812- out. push ( "C" ) ;
813- }
814- if repr. transparent ( ) {
815- // Render `repr(transparent)` iff the non-1-ZST field is public or at least one
816- // field is public in case all fields are 1-ZST fields.
817- let render_transparent = is_json
818- || cache. document_private
819- || adt
820- . all_fields ( )
821- . find ( |field| {
822- let ty =
823- field. ty ( tcx, ty:: GenericArgs :: identity_for_item ( tcx, field. did ) ) ;
824- tcx. layout_of (
825- ty:: TypingEnv :: post_analysis ( tcx, field. did ) . as_query_input ( ty) ,
826- )
827- . is_ok_and ( |layout| !layout. is_1zst ( ) )
828- } )
829- . map_or_else (
830- || adt. all_fields ( ) . any ( |field| field. vis . is_public ( ) ) ,
831- |field| field. vis . is_public ( ) ,
832- ) ;
802+ pub ( crate ) fn attributes_and_repr (
803+ & self ,
804+ tcx : TyCtxt < ' _ > ,
805+ cache : & Cache ,
806+ is_json : bool ,
807+ ) -> Vec < String > {
808+ let mut attrs = self . attributes_witout_repr ( tcx, is_json) ;
833809
834- if render_transparent {
835- out. push ( "transparent" ) ;
836- }
837- }
838- if repr. simd ( ) {
839- out. push ( "simd" ) ;
840- }
841- let pack_s;
842- if let Some ( pack) = repr. pack {
843- pack_s = format ! ( "packed({})" , pack. bytes( ) ) ;
844- out. push ( & pack_s) ;
845- }
846- let align_s;
847- if let Some ( align) = repr. align {
848- align_s = format ! ( "align({})" , align. bytes( ) ) ;
849- out. push ( & align_s) ;
850- }
851- let int_s;
852- if let Some ( int) = repr. int {
853- int_s = match int {
854- IntegerType :: Pointer ( is_signed) => {
855- format ! ( "{}size" , if is_signed { 'i' } else { 'u' } )
856- }
857- IntegerType :: Fixed ( size, is_signed) => {
858- format ! ( "{}{}" , if is_signed { 'i' } else { 'u' } , size. size( ) . bytes( ) * 8 )
859- }
860- } ;
861- out. push ( & int_s) ;
862- }
863- if !out. is_empty ( ) {
864- attrs. push ( format ! ( "#[repr({})]" , out. join( ", " ) ) ) ;
865- }
810+ if let Some ( repr_attr) = self . repr ( tcx, cache) {
811+ attrs. push ( repr_attr) ;
866812 }
867813 attrs
868814 }
869815
816+ /// Returns a `#[repr(...)]` representation.
817+ pub ( crate ) fn repr ( & self , tcx : TyCtxt < ' _ > , cache : & Cache , is_json : bool ) -> Option < String > {
818+ use rustc_abi:: IntegerType ;
819+
820+ let def_id = self . def_id ( ) ?;
821+ if !matches ! ( self . type_( ) , ItemType :: Struct | ItemType :: Enum | ItemType :: Union ) {
822+ return None ;
823+ }
824+ let adt = tcx. adt_def ( def_id) ;
825+ let repr = adt. repr ( ) ;
826+ let mut out = Vec :: new ( ) ;
827+ if repr. c ( ) {
828+ out. push ( "C" ) ;
829+ }
830+ if repr. transparent ( ) {
831+ // Render `repr(transparent)` iff the non-1-ZST field is public or at least one
832+ // field is public in case all fields are 1-ZST fields.
833+ let render_transparent = is_json
834+ || cache. document_private
835+ || adt
836+ . all_fields ( )
837+ . find ( |field| {
838+ let ty = field. ty ( tcx, ty:: GenericArgs :: identity_for_item ( tcx, field. did ) ) ;
839+ tcx. layout_of (
840+ ty:: TypingEnv :: post_analysis ( tcx, field. did ) . as_query_input ( ty) ,
841+ )
842+ . is_ok_and ( |layout| !layout. is_1zst ( ) )
843+ } )
844+ . map_or_else (
845+ || adt. all_fields ( ) . any ( |field| field. vis . is_public ( ) ) ,
846+ |field| field. vis . is_public ( ) ,
847+ ) ;
848+
849+ if render_transparent {
850+ out. push ( "transparent" ) ;
851+ }
852+ }
853+ if repr. simd ( ) {
854+ out. push ( "simd" ) ;
855+ }
856+ let pack_s;
857+ if let Some ( pack) = repr. pack {
858+ pack_s = format ! ( "packed({})" , pack. bytes( ) ) ;
859+ out. push ( & pack_s) ;
860+ }
861+ let align_s;
862+ if let Some ( align) = repr. align {
863+ align_s = format ! ( "align({})" , align. bytes( ) ) ;
864+ out. push ( & align_s) ;
865+ }
866+ let int_s;
867+ if let Some ( int) = repr. int {
868+ int_s = match int {
869+ IntegerType :: Pointer ( is_signed) => {
870+ format ! ( "{}size" , if is_signed { 'i' } else { 'u' } )
871+ }
872+ IntegerType :: Fixed ( size, is_signed) => {
873+ format ! ( "{}{}" , if is_signed { 'i' } else { 'u' } , size. size( ) . bytes( ) * 8 )
874+ }
875+ } ;
876+ out. push ( & int_s) ;
877+ }
878+ if !out. is_empty ( ) { Some ( format ! ( "#[repr({})]" , out. join( ", " ) ) ) } else { None }
879+ }
880+
870881 pub fn is_doc_hidden ( & self ) -> bool {
871882 self . attrs . is_doc_hidden ( )
872883 }
0 commit comments