@@ -825,7 +825,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
825
825
if let FfiUnsafe ( explanations) = ffires_accumulator {
826
826
// we assume the repr() of this ADT is either non-packed C or transparent.
827
827
debug_assert ! (
828
- def. repr( ) . c( )
828
+ ( def. repr( ) . c( ) && !def . repr ( ) . packed ( ) )
829
829
|| def. repr( ) . transparent( )
830
830
|| def. repr( ) . int. is_some( )
831
831
) ;
@@ -898,7 +898,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
898
898
) -> FfiResult < ' tcx > {
899
899
debug_assert ! ( matches!( def. adt_kind( ) , AdtKind :: Struct | AdtKind :: Union ) ) ;
900
900
901
- if !def. repr ( ) . c ( ) && !def. repr ( ) . transparent ( ) {
901
+ if !( ( def. repr ( ) . c ( ) && !def. repr ( ) . packed ( ) ) || def. repr ( ) . transparent ( ) ) {
902
+ // FIXME(ctypes) packed reprs prevent C compatibility, right?
902
903
return FfiResult :: new_with_reason (
903
904
ty,
904
905
if def. is_struct ( ) {
@@ -974,7 +975,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
974
975
}
975
976
// Check for a repr() attribute to specify the size of the
976
977
// discriminant.
977
- if !def. repr ( ) . c ( ) && !def. repr ( ) . transparent ( ) && def. repr ( ) . int . is_none ( ) {
978
+ if !( def. repr ( ) . c ( ) && !def. repr ( ) . packed ( ) )
979
+ && !def. repr ( ) . transparent ( )
980
+ && def. repr ( ) . int . is_none ( )
981
+ {
978
982
// Special-case types like `Option<extern fn()>` and `Result<extern fn(), ()>`
979
983
if let Some ( inner_ty) = repr_nullable_ptr ( self . cx . tcx , self . cx . typing_env ( ) , ty) {
980
984
return self . visit_type ( state, Some ( ty) , inner_ty) ;
@@ -1365,22 +1369,19 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1365
1369
item : & ' tcx hir:: Item < ' tcx > ,
1366
1370
adt_def : AdtDef < ' tcx > ,
1367
1371
) {
1368
- let tcx = cx. tcx ;
1369
1372
// repr(C) structs also with packed or aligned representation
1370
1373
// should be ignored.
1371
- if adt_def. repr ( ) . c ( )
1372
- && !adt_def. repr ( ) . packed ( )
1373
- && adt_def. repr ( ) . align . is_none ( )
1374
- && tcx. sess . target . os == "aix"
1375
- && !adt_def. all_fields ( ) . next ( ) . is_none ( )
1376
- {
1374
+ debug_assert ! (
1375
+ adt_def. repr( ) . c( ) && !adt_def. repr( ) . packed( ) && adt_def. repr( ) . align. is_none( )
1376
+ ) ;
1377
+ if cx. tcx . sess . target . os == "aix" && !adt_def. all_fields ( ) . next ( ) . is_none ( ) {
1377
1378
let struct_variant_data = item. expect_struct ( ) . 2 ;
1378
1379
for field_def in struct_variant_data. fields ( ) . iter ( ) . skip ( 1 ) {
1379
1380
// Struct fields (after the first field) are checked for the
1380
1381
// power alignment rule, as fields after the first are likely
1381
1382
// to be the fields that are misaligned.
1382
1383
let def_id = field_def. def_id ;
1383
- let ty = tcx. type_of ( def_id) . instantiate_identity ( ) ;
1384
+ let ty = cx . tcx . type_of ( def_id) . instantiate_identity ( ) ;
1384
1385
if Self :: check_arg_for_power_alignment ( cx, ty) {
1385
1386
cx. emit_span_lint ( USES_POWER_ALIGNMENT , field_def. span , UsesPowerAlignment ) ;
1386
1387
}
0 commit comments