@@ -1016,7 +1016,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10161016 // takes priority over transparent_with_all_zst_fields
10171017 if let FfiUnsafe ( explanations) = ffires_accumulator {
10181018 // we assume the repr() of this ADT is either non-packed C or transparent.
1019- debug_assert ! ( def. repr( ) . c( ) || def. repr( ) . transparent( ) || def. repr( ) . int. is_some( ) ) ;
1019+ debug_assert ! (
1020+ ( def. repr( ) . c( ) && !def. repr( ) . packed( ) )
1021+ || def. repr( ) . transparent( )
1022+ || def. repr( ) . int. is_some( )
1023+ ) ;
10201024
10211025 if def. repr ( ) . transparent ( ) || matches ! ( def. adt_kind( ) , AdtKind :: Enum ) {
10221026 let field_ffires = FfiUnsafe ( explanations) . wrap_all (
@@ -1086,7 +1090,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10861090 ) -> FfiResult < ' tcx > {
10871091 debug_assert ! ( matches!( def. adt_kind( ) , AdtKind :: Struct | AdtKind :: Union ) ) ;
10881092
1089- if !def. repr ( ) . c ( ) && !def. repr ( ) . transparent ( ) {
1093+ if !( ( def. repr ( ) . c ( ) && !def. repr ( ) . packed ( ) ) || def. repr ( ) . transparent ( ) ) {
1094+ // FIXME(ctypes) packed reprs prevent C compatibility, right?
10901095 return FfiResult :: new_with_reason (
10911096 ty,
10921097 if def. is_struct ( ) {
@@ -1162,7 +1167,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
11621167 }
11631168 // Check for a repr() attribute to specify the size of the
11641169 // discriminant.
1165- if !def. repr ( ) . c ( ) && !def. repr ( ) . transparent ( ) && def. repr ( ) . int . is_none ( ) {
1170+ if !( def. repr ( ) . c ( ) && !def. repr ( ) . packed ( ) )
1171+ && !def. repr ( ) . transparent ( )
1172+ && def. repr ( ) . int . is_none ( )
1173+ {
11661174 // Special-case types like `Option<extern fn()>` and `Result<extern fn(), ()>`
11671175 if let Some ( inner_ty) = repr_nullable_ptr ( self . cx . tcx , self . cx . typing_env ( ) , ty) {
11681176 return self . visit_type ( state, Some ( ty) , inner_ty) ;
@@ -1558,22 +1566,19 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
15581566 item : & ' tcx hir:: Item < ' tcx > ,
15591567 adt_def : AdtDef < ' tcx > ,
15601568 ) {
1561- let tcx = cx. tcx ;
15621569 // repr(C) structs also with packed or aligned representation
15631570 // should be ignored.
1564- if adt_def. repr ( ) . c ( )
1565- && !adt_def. repr ( ) . packed ( )
1566- && adt_def. repr ( ) . align . is_none ( )
1567- && tcx. sess . target . os == "aix"
1568- && !adt_def. all_fields ( ) . next ( ) . is_none ( )
1569- {
1571+ debug_assert ! (
1572+ adt_def. repr( ) . c( ) && !adt_def. repr( ) . packed( ) && adt_def. repr( ) . align. is_none( )
1573+ ) ;
1574+ if cx. tcx . sess . target . os == "aix" && !adt_def. all_fields ( ) . next ( ) . is_none ( ) {
15701575 let struct_variant_data = item. expect_struct ( ) . 2 ;
15711576 for field_def in struct_variant_data. fields ( ) . iter ( ) . skip ( 1 ) {
15721577 // Struct fields (after the first field) are checked for the
15731578 // power alignment rule, as fields after the first are likely
15741579 // to be the fields that are misaligned.
15751580 let def_id = field_def. def_id ;
1576- let ty = tcx. type_of ( def_id) . instantiate_identity ( ) ;
1581+ let ty = cx . tcx . type_of ( def_id) . instantiate_identity ( ) ;
15771582 if Self :: check_arg_for_power_alignment ( cx, ty) {
15781583 cx. emit_span_lint ( USES_POWER_ALIGNMENT , field_def. span , UsesPowerAlignment ) ;
15791584 }
0 commit comments