@@ -610,6 +610,9 @@ impl Item {
610610 UnionItem ( ref union_) => Some ( union_. has_stripped_entries ( ) ) ,
611611 EnumItem ( ref enum_) => Some ( enum_. has_stripped_entries ( ) ) ,
612612 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+ }
613616 _ => None ,
614617 }
615618 }
@@ -761,14 +764,11 @@ impl Item {
761764 Some ( tcx. visibility ( def_id) )
762765 }
763766
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 > {
765768 const ALLOWED_ATTRIBUTES : & [ Symbol ] =
766769 & [ sym:: export_name, sym:: link_section, sym:: no_mangle, sym:: non_exhaustive] ;
767770
768- use rustc_abi:: IntegerType ;
769-
770- let mut attrs: Vec < String > = self
771- . attrs
771+ self . attrs
772772 . other_attrs
773773 . iter ( )
774774 . filter_map ( |attr| {
@@ -796,74 +796,28 @@ impl Item {
796796 None
797797 }
798798 } )
799- . collect ( ) ;
799+ . collect ( )
800+ }
800801
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) ;
830809
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) ;
863812 }
864813 attrs
865814 }
866815
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+
867821 pub fn is_doc_hidden ( & self ) -> bool {
868822 self . attrs . is_doc_hidden ( )
869823 }
@@ -873,6 +827,73 @@ impl Item {
873827 }
874828}
875829
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+
876897#[ derive( Clone , Debug ) ]
877898pub ( crate ) enum ItemKind {
878899 ExternCrateItem {
@@ -2107,7 +2128,7 @@ impl Enum {
21072128 self . variants . iter ( ) . any ( |f| f. is_stripped ( ) )
21082129 }
21092130
2110- pub ( crate ) fn variants ( & self ) -> impl Iterator < Item = & Item > {
2131+ pub ( crate ) fn non_stripped_variants ( & self ) -> impl Iterator < Item = & Item > {
21112132 self . variants . iter ( ) . filter ( |v| !v. is_stripped ( ) )
21122133 }
21132134}
@@ -2345,6 +2366,17 @@ pub(crate) enum TypeAliasInnerType {
23452366 Struct { ctor_kind : Option < CtorKind > , fields : Vec < Item > } ,
23462367}
23472368
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+
23482380#[ derive( Clone , Debug ) ]
23492381pub ( crate ) struct TypeAlias {
23502382 pub ( crate ) type_ : Type ,
0 commit comments