@@ -610,6 +610,9 @@ impl Item {
610
610
UnionItem ( ref union_) => Some ( union_. has_stripped_entries ( ) ) ,
611
611
EnumItem ( ref enum_) => Some ( enum_. has_stripped_entries ( ) ) ,
612
612
VariantItem ( ref v) => v. has_stripped_entries ( ) ,
613
+ TypeAliasItem ( ref type_alias) => {
614
+ type_alias. inner_type . as_ref ( ) . and_then ( |t| t. has_stripped_entries ( ) )
615
+ }
613
616
_ => None ,
614
617
}
615
618
}
@@ -761,14 +764,11 @@ impl Item {
761
764
Some ( tcx. visibility ( def_id) )
762
765
}
763
766
764
- pub ( crate ) fn attributes ( & self , tcx : TyCtxt < ' _ > , cache : & Cache , is_json : bool ) -> Vec < String > {
767
+ pub ( crate ) fn attributes_without_repr ( & self , tcx : TyCtxt < ' _ > , is_json : bool ) -> Vec < String > {
765
768
const ALLOWED_ATTRIBUTES : & [ Symbol ] =
766
769
& [ sym:: export_name, sym:: link_section, sym:: no_mangle, sym:: non_exhaustive] ;
767
770
768
- use rustc_abi:: IntegerType ;
769
-
770
- let mut attrs: Vec < String > = self
771
- . attrs
771
+ self . attrs
772
772
. other_attrs
773
773
. iter ( )
774
774
. filter_map ( |attr| {
@@ -796,74 +796,28 @@ impl Item {
796
796
None
797
797
}
798
798
} )
799
- . collect ( ) ;
799
+ . collect ( )
800
+ }
800
801
801
- // Add #[repr(...)]
802
- if let Some ( def_id) = self . def_id ( )
803
- && let ItemType :: Struct | ItemType :: Enum | ItemType :: Union = self . type_ ( )
804
- {
805
- let adt = tcx. adt_def ( def_id) ;
806
- let repr = adt. repr ( ) ;
807
- let mut out = Vec :: new ( ) ;
808
- if repr. c ( ) {
809
- out. push ( "C" ) ;
810
- }
811
- if repr. transparent ( ) {
812
- // Render `repr(transparent)` iff the non-1-ZST field is public or at least one
813
- // field is public in case all fields are 1-ZST fields.
814
- let render_transparent = is_json
815
- || cache. document_private
816
- || adt
817
- . all_fields ( )
818
- . find ( |field| {
819
- let ty =
820
- field. ty ( tcx, ty:: GenericArgs :: identity_for_item ( tcx, field. did ) ) ;
821
- tcx. layout_of (
822
- ty:: TypingEnv :: post_analysis ( tcx, field. did ) . as_query_input ( ty) ,
823
- )
824
- . is_ok_and ( |layout| !layout. is_1zst ( ) )
825
- } )
826
- . map_or_else (
827
- || adt. all_fields ( ) . any ( |field| field. vis . is_public ( ) ) ,
828
- |field| field. vis . is_public ( ) ,
829
- ) ;
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_without_repr ( tcx, is_json) ;
830
809
831
- if render_transparent {
832
- out. push ( "transparent" ) ;
833
- }
834
- }
835
- if repr. simd ( ) {
836
- out. push ( "simd" ) ;
837
- }
838
- let pack_s;
839
- if let Some ( pack) = repr. pack {
840
- pack_s = format ! ( "packed({})" , pack. bytes( ) ) ;
841
- out. push ( & pack_s) ;
842
- }
843
- let align_s;
844
- if let Some ( align) = repr. align {
845
- align_s = format ! ( "align({})" , align. bytes( ) ) ;
846
- out. push ( & align_s) ;
847
- }
848
- let int_s;
849
- if let Some ( int) = repr. int {
850
- int_s = match int {
851
- IntegerType :: Pointer ( is_signed) => {
852
- format ! ( "{}size" , if is_signed { 'i' } else { 'u' } )
853
- }
854
- IntegerType :: Fixed ( size, is_signed) => {
855
- format ! ( "{}{}" , if is_signed { 'i' } else { 'u' } , size. size( ) . bytes( ) * 8 )
856
- }
857
- } ;
858
- out. push ( & int_s) ;
859
- }
860
- if !out. is_empty ( ) {
861
- attrs. push ( format ! ( "#[repr({})]" , out. join( ", " ) ) ) ;
862
- }
810
+ if let Some ( repr_attr) = self . repr ( tcx, cache, is_json) {
811
+ attrs. push ( repr_attr) ;
863
812
}
864
813
attrs
865
814
}
866
815
816
+ /// Returns a stringified `#[repr(...)]` attribute.
817
+ pub ( crate ) fn repr ( & self , tcx : TyCtxt < ' _ > , cache : & Cache , is_json : bool ) -> Option < String > {
818
+ repr_attributes ( tcx, cache, self . def_id ( ) ?, self . type_ ( ) , is_json)
819
+ }
820
+
867
821
pub fn is_doc_hidden ( & self ) -> bool {
868
822
self . attrs . is_doc_hidden ( )
869
823
}
@@ -873,6 +827,73 @@ impl Item {
873
827
}
874
828
}
875
829
830
+ pub ( crate ) fn repr_attributes (
831
+ tcx : TyCtxt < ' _ > ,
832
+ cache : & Cache ,
833
+ def_id : DefId ,
834
+ item_type : ItemType ,
835
+ is_json : bool ,
836
+ ) -> Option < String > {
837
+ use rustc_abi:: IntegerType ;
838
+
839
+ if !matches ! ( item_type, ItemType :: Struct | ItemType :: Enum | ItemType :: Union ) {
840
+ return None ;
841
+ }
842
+ let adt = tcx. adt_def ( def_id) ;
843
+ let repr = adt. repr ( ) ;
844
+ let mut out = Vec :: new ( ) ;
845
+ if repr. c ( ) {
846
+ out. push ( "C" ) ;
847
+ }
848
+ if repr. transparent ( ) {
849
+ // Render `repr(transparent)` iff the non-1-ZST field is public or at least one
850
+ // field is public in case all fields are 1-ZST fields.
851
+ let render_transparent = cache. document_private
852
+ || is_json
853
+ || adt
854
+ . all_fields ( )
855
+ . find ( |field| {
856
+ let ty = field. ty ( tcx, ty:: GenericArgs :: identity_for_item ( tcx, field. did ) ) ;
857
+ tcx. layout_of ( ty:: TypingEnv :: post_analysis ( tcx, field. did ) . as_query_input ( ty) )
858
+ . is_ok_and ( |layout| !layout. is_1zst ( ) )
859
+ } )
860
+ . map_or_else (
861
+ || adt. all_fields ( ) . any ( |field| field. vis . is_public ( ) ) ,
862
+ |field| field. vis . is_public ( ) ,
863
+ ) ;
864
+
865
+ if render_transparent {
866
+ out. push ( "transparent" ) ;
867
+ }
868
+ }
869
+ if repr. simd ( ) {
870
+ out. push ( "simd" ) ;
871
+ }
872
+ let pack_s;
873
+ if let Some ( pack) = repr. pack {
874
+ pack_s = format ! ( "packed({})" , pack. bytes( ) ) ;
875
+ out. push ( & pack_s) ;
876
+ }
877
+ let align_s;
878
+ if let Some ( align) = repr. align {
879
+ align_s = format ! ( "align({})" , align. bytes( ) ) ;
880
+ out. push ( & align_s) ;
881
+ }
882
+ let int_s;
883
+ if let Some ( int) = repr. int {
884
+ int_s = match int {
885
+ IntegerType :: Pointer ( is_signed) => {
886
+ format ! ( "{}size" , if is_signed { 'i' } else { 'u' } )
887
+ }
888
+ IntegerType :: Fixed ( size, is_signed) => {
889
+ format ! ( "{}{}" , if is_signed { 'i' } else { 'u' } , size. size( ) . bytes( ) * 8 )
890
+ }
891
+ } ;
892
+ out. push ( & int_s) ;
893
+ }
894
+ if !out. is_empty ( ) { Some ( format ! ( "#[repr({})]" , out. join( ", " ) ) ) } else { None }
895
+ }
896
+
876
897
#[ derive( Clone , Debug ) ]
877
898
pub ( crate ) enum ItemKind {
878
899
ExternCrateItem {
@@ -2107,7 +2128,7 @@ impl Enum {
2107
2128
self . variants . iter ( ) . any ( |f| f. is_stripped ( ) )
2108
2129
}
2109
2130
2110
- pub ( crate ) fn variants ( & self ) -> impl Iterator < Item = & Item > {
2131
+ pub ( crate ) fn non_stripped_variants ( & self ) -> impl Iterator < Item = & Item > {
2111
2132
self . variants . iter ( ) . filter ( |v| !v. is_stripped ( ) )
2112
2133
}
2113
2134
}
@@ -2345,6 +2366,17 @@ pub(crate) enum TypeAliasInnerType {
2345
2366
Struct { ctor_kind : Option < CtorKind > , fields : Vec < Item > } ,
2346
2367
}
2347
2368
2369
+ impl TypeAliasInnerType {
2370
+ fn has_stripped_entries ( & self ) -> Option < bool > {
2371
+ Some ( match self {
2372
+ Self :: Enum { variants, .. } => variants. iter ( ) . any ( |v| v. is_stripped ( ) ) ,
2373
+ Self :: Union { fields } | Self :: Struct { fields, .. } => {
2374
+ fields. iter ( ) . any ( |f| f. is_stripped ( ) )
2375
+ }
2376
+ } )
2377
+ }
2378
+ }
2379
+
2348
2380
#[ derive( Clone , Debug ) ]
2349
2381
pub ( crate ) struct TypeAlias {
2350
2382
pub ( crate ) type_ : Type ,
0 commit comments