@@ -764,14 +764,11 @@ impl Item {
764
764
Some ( tcx. visibility ( def_id) )
765
765
}
766
766
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 > {
768
768
const ALLOWED_ATTRIBUTES : & [ Symbol ] =
769
769
& [ sym:: export_name, sym:: link_section, sym:: no_mangle, sym:: non_exhaustive] ;
770
770
771
- use rustc_abi:: IntegerType ;
772
-
773
- let mut attrs: Vec < String > = self
774
- . attrs
771
+ self . attrs
775
772
. other_attrs
776
773
. iter ( )
777
774
. filter_map ( |attr| {
@@ -799,74 +796,88 @@ impl Item {
799
796
None
800
797
}
801
798
} )
802
- . collect ( ) ;
799
+ . collect ( )
800
+ }
803
801
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) ;
833
809
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) ;
866
812
}
867
813
attrs
868
814
}
869
815
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
+
870
881
pub fn is_doc_hidden ( & self ) -> bool {
871
882
self . attrs . is_doc_hidden ( )
872
883
}
0 commit comments