@@ -762,14 +762,11 @@ impl Item {
762
762
Some ( tcx. visibility ( def_id) )
763
763
}
764
764
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 > {
766
766
const ALLOWED_ATTRIBUTES : & [ Symbol ] =
767
767
& [ sym:: export_name, sym:: link_section, sym:: no_mangle, sym:: non_exhaustive] ;
768
768
769
- use rustc_abi:: IntegerType ;
770
-
771
- let mut attrs: Vec < String > = self
772
- . attrs
769
+ self . attrs
773
770
. other_attrs
774
771
. iter ( )
775
772
. filter_map ( |attr| {
@@ -806,73 +803,87 @@ impl Item {
806
803
None
807
804
}
808
805
} )
809
- . collect ( ) ;
806
+ . collect ( )
807
+ }
810
808
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) ;
839
816
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) ;
872
819
}
873
820
attrs
874
821
}
875
822
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
+
876
887
pub fn is_doc_hidden ( & self ) -> bool {
877
888
self . attrs . is_doc_hidden ( )
878
889
}
0 commit comments