@@ -762,14 +762,11 @@ impl Item {
762762 Some ( tcx. visibility ( def_id) )
763763 }
764764
765- pub ( crate ) fn attributes ( & self , tcx : TyCtxt < ' _ > , cache : & Cache , is_json : bool ) -> Vec < String > {
765+ pub ( crate ) fn attributes_witout_repr ( & self , tcx : TyCtxt < ' _ > , is_json : bool ) -> Vec < String > {
766766 const ALLOWED_ATTRIBUTES : & [ Symbol ] =
767767 & [ sym:: export_name, sym:: link_section, sym:: no_mangle, sym:: non_exhaustive] ;
768768
769- use rustc_abi:: IntegerType ;
770-
771- let mut attrs: Vec < String > = self
772- . attrs
769+ self . attrs
773770 . other_attrs
774771 . iter ( )
775772 . filter_map ( |attr| {
@@ -806,73 +803,87 @@ impl Item {
806803 None
807804 }
808805 } )
809- . collect ( ) ;
806+ . collect ( )
807+ }
810808
811- // Add #[repr(...)]
812- if let Some ( def_id) = self . def_id ( )
813- && let ItemType :: Struct | ItemType :: Enum | ItemType :: Union = self . type_ ( )
814- {
815- let adt = tcx. adt_def ( def_id) ;
816- let repr = adt. repr ( ) ;
817- let mut out = Vec :: new ( ) ;
818- if repr. c ( ) {
819- out. push ( "C" ) ;
820- }
821- if repr. transparent ( ) {
822- // Render `repr(transparent)` iff the non-1-ZST field is public or at least one
823- // field is public in case all fields are 1-ZST fields.
824- let render_transparent = cache. document_private
825- || adt
826- . all_fields ( )
827- . find ( |field| {
828- let ty =
829- field. ty ( tcx, ty:: GenericArgs :: identity_for_item ( tcx, field. did ) ) ;
830- tcx. layout_of (
831- ty:: TypingEnv :: post_analysis ( tcx, field. did ) . as_query_input ( ty) ,
832- )
833- . is_ok_and ( |layout| !layout. is_1zst ( ) )
834- } )
835- . map_or_else (
836- || adt. all_fields ( ) . any ( |field| field. vis . is_public ( ) ) ,
837- |field| field. vis . is_public ( ) ,
838- ) ;
809+ pub ( crate ) fn attributes_and_repr (
810+ & self ,
811+ tcx : TyCtxt < ' _ > ,
812+ cache : & Cache ,
813+ is_json : bool ,
814+ ) -> Vec < String > {
815+ let mut attrs = self . attributes_witout_repr ( tcx, is_json) ;
839816
840- if render_transparent {
841- out. push ( "transparent" ) ;
842- }
843- }
844- if repr. simd ( ) {
845- out. push ( "simd" ) ;
846- }
847- let pack_s;
848- if let Some ( pack) = repr. pack {
849- pack_s = format ! ( "packed({})" , pack. bytes( ) ) ;
850- out. push ( & pack_s) ;
851- }
852- let align_s;
853- if let Some ( align) = repr. align {
854- align_s = format ! ( "align({})" , align. bytes( ) ) ;
855- out. push ( & align_s) ;
856- }
857- let int_s;
858- if let Some ( int) = repr. int {
859- int_s = match int {
860- IntegerType :: Pointer ( is_signed) => {
861- format ! ( "{}size" , if is_signed { 'i' } else { 'u' } )
862- }
863- IntegerType :: Fixed ( size, is_signed) => {
864- format ! ( "{}{}" , if is_signed { 'i' } else { 'u' } , size. size( ) . bytes( ) * 8 )
865- }
866- } ;
867- out. push ( & int_s) ;
868- }
869- if !out. is_empty ( ) {
870- attrs. push ( format ! ( "#[repr({})]" , out. join( ", " ) ) ) ;
871- }
817+ if let Some ( repr_attr) = self . repr ( tcx, cache) {
818+ attrs. push ( repr_attr) ;
872819 }
873820 attrs
874821 }
875822
823+ /// Returns a `#[repr(...)]` representation.
824+ pub ( crate ) fn repr ( & self , tcx : TyCtxt < ' _ > , cache : & Cache ) -> Option < String > {
825+ use rustc_abi:: IntegerType ;
826+
827+ let def_id = self . def_id ( ) ?;
828+ if !matches ! ( self . type_( ) , ItemType :: Struct | ItemType :: Enum | ItemType :: Union ) {
829+ return None ;
830+ }
831+ let adt = tcx. adt_def ( def_id) ;
832+ let repr = adt. repr ( ) ;
833+ let mut out = Vec :: new ( ) ;
834+ if repr. c ( ) {
835+ out. push ( "C" ) ;
836+ }
837+ if repr. transparent ( ) {
838+ // Render `repr(transparent)` iff the non-1-ZST field is public or at least one
839+ // field is public in case all fields are 1-ZST fields.
840+ let render_transparent = cache. document_private
841+ || adt
842+ . all_fields ( )
843+ . find ( |field| {
844+ let ty = field. ty ( tcx, ty:: GenericArgs :: identity_for_item ( tcx, field. did ) ) ;
845+ tcx. layout_of (
846+ ty:: TypingEnv :: post_analysis ( tcx, field. did ) . as_query_input ( ty) ,
847+ )
848+ . is_ok_and ( |layout| !layout. is_1zst ( ) )
849+ } )
850+ . map_or_else (
851+ || adt. all_fields ( ) . any ( |field| field. vis . is_public ( ) ) ,
852+ |field| field. vis . is_public ( ) ,
853+ ) ;
854+
855+ if render_transparent {
856+ out. push ( "transparent" ) ;
857+ }
858+ }
859+ if repr. simd ( ) {
860+ out. push ( "simd" ) ;
861+ }
862+ let pack_s;
863+ if let Some ( pack) = repr. pack {
864+ pack_s = format ! ( "packed({})" , pack. bytes( ) ) ;
865+ out. push ( & pack_s) ;
866+ }
867+ let align_s;
868+ if let Some ( align) = repr. align {
869+ align_s = format ! ( "align({})" , align. bytes( ) ) ;
870+ out. push ( & align_s) ;
871+ }
872+ let int_s;
873+ if let Some ( int) = repr. int {
874+ int_s = match int {
875+ IntegerType :: Pointer ( is_signed) => {
876+ format ! ( "{}size" , if is_signed { 'i' } else { 'u' } )
877+ }
878+ IntegerType :: Fixed ( size, is_signed) => {
879+ format ! ( "{}{}" , if is_signed { 'i' } else { 'u' } , size. size( ) . bytes( ) * 8 )
880+ }
881+ } ;
882+ out. push ( & int_s) ;
883+ }
884+ if !out. is_empty ( ) { Some ( format ! ( "#[repr({})]" , out. join( ", " ) ) ) } else { None }
885+ }
886+
876887 pub fn is_doc_hidden ( & self ) -> bool {
877888 self . attrs . is_doc_hidden ( )
878889 }
0 commit comments