@@ -811,7 +811,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
811811 if let FfiUnsafe ( explanations) = ffires_accumulator {
812812 // we assume the repr() of this ADT is either non-packed C or transparent.
813813 debug_assert ! (
814- def. repr( ) . c( )
814+ ( def. repr( ) . c( ) && !def . repr ( ) . packed ( ) )
815815 || def. repr( ) . transparent( )
816816 || def. repr( ) . int. is_some( )
817817 ) ;
@@ -884,7 +884,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
884884 ) -> FfiResult < ' tcx > {
885885 debug_assert ! ( matches!( def. adt_kind( ) , AdtKind :: Struct | AdtKind :: Union ) ) ;
886886
887- if !def. repr ( ) . c ( ) && !def. repr ( ) . transparent ( ) {
887+ if !( ( def. repr ( ) . c ( ) && !def. repr ( ) . packed ( ) ) || def. repr ( ) . transparent ( ) ) {
888+ // FIXME(ctypes) packed reprs prevent C compatibility, right?
888889 return FfiResult :: new_with_reason (
889890 ty,
890891 if def. is_struct ( ) {
@@ -960,7 +961,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
960961 }
961962 // Check for a repr() attribute to specify the size of the
962963 // discriminant.
963- if !def. repr ( ) . c ( ) && !def. repr ( ) . transparent ( ) && def. repr ( ) . int . is_none ( ) {
964+ if !( def. repr ( ) . c ( ) && !def. repr ( ) . packed ( ) )
965+ && !def. repr ( ) . transparent ( )
966+ && def. repr ( ) . int . is_none ( )
967+ {
964968 // Special-case types like `Option<extern fn()>` and `Result<extern fn(), ()>`
965969 if let Some ( inner_ty) = repr_nullable_ptr ( self . cx . tcx , self . cx . typing_env ( ) , ty) {
966970 return self . visit_type ( state, Some ( ty) , inner_ty) ;
@@ -1351,22 +1355,19 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
13511355 item : & ' tcx hir:: Item < ' tcx > ,
13521356 adt_def : AdtDef < ' tcx > ,
13531357 ) {
1354- let tcx = cx. tcx ;
13551358 // repr(C) structs also with packed or aligned representation
13561359 // should be ignored.
1357- if adt_def. repr ( ) . c ( )
1358- && !adt_def. repr ( ) . packed ( )
1359- && adt_def. repr ( ) . align . is_none ( )
1360- && tcx. sess . target . os == "aix"
1361- && !adt_def. all_fields ( ) . next ( ) . is_none ( )
1362- {
1360+ debug_assert ! (
1361+ adt_def. repr( ) . c( ) && !adt_def. repr( ) . packed( ) && adt_def. repr( ) . align. is_none( )
1362+ ) ;
1363+ if cx. tcx . sess . target . os == "aix" && !adt_def. all_fields ( ) . next ( ) . is_none ( ) {
13631364 let struct_variant_data = item. expect_struct ( ) . 2 ;
13641365 for field_def in struct_variant_data. fields ( ) . iter ( ) . skip ( 1 ) {
13651366 // Struct fields (after the first field) are checked for the
13661367 // power alignment rule, as fields after the first are likely
13671368 // to be the fields that are misaligned.
13681369 let def_id = field_def. def_id ;
1369- let ty = tcx. type_of ( def_id) . instantiate_identity ( ) ;
1370+ let ty = cx . tcx . type_of ( def_id) . instantiate_identity ( ) ;
13701371 if Self :: check_arg_for_power_alignment ( cx, ty) {
13711372 cx. emit_span_lint ( USES_POWER_ALIGNMENT , field_def. span , UsesPowerAlignment ) ;
13721373 }
0 commit comments