@@ -1009,39 +1009,36 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10091009 ) -> FfiResult < ' tcx > {
10101010 use FfiResult :: * ;
10111011
1012- let transparent_safety = def. repr ( ) . transparent ( ) . then ( || {
1013- // Can assume that at most one field is not a ZST, so only check
1014- // that field's type for FFI-safety.
1012+ let transparent_with_all_zst_fields = if def. repr ( ) . transparent ( ) {
1013+ // Transparent newtypes have at most one non-ZST field which needs to be checked..
10151014 if let Some ( field) = transparent_newtype_field ( self . cx . tcx , variant) {
10161015 return self . check_field_type_for_ffi ( cache, field, args) ;
1017- } else {
1018- // All fields are ZSTs; this means that the type should behave
1019- // like (), which is FFI-unsafe... except if all fields are PhantomData,
1020- // which is tested for below
1021- FfiUnsafe { ty, reason : fluent:: lint_improper_ctypes_struct_zst, help : None }
10221016 }
1023- } ) ;
1024- // We can't completely trust repr(C) markings; make sure the fields are
1025- // actually safe.
1017+
1018+ // ..or have only ZST fields, which is FFI-unsafe (unless those fields are all
1019+ // `PhantomData`).
1020+ true
1021+ } else {
1022+ false
1023+ } ;
1024+
1025+ // We can't completely trust `repr(C)` markings, so make sure the fields are actually safe.
10261026 let mut all_phantom = !variant. fields . is_empty ( ) ;
10271027 for field in & variant. fields {
1028- match self . check_field_type_for_ffi ( cache, & field, args) {
1029- FfiSafe => {
1030- all_phantom = false ;
1031- }
1032- FfiPhantom ( ..) if !def. repr ( ) . transparent ( ) && def. is_enum ( ) => {
1033- return FfiUnsafe {
1034- ty,
1035- reason : fluent:: lint_improper_ctypes_enum_phantomdata,
1036- help : None ,
1037- } ;
1038- }
1039- FfiPhantom ( ..) => { }
1040- r => return transparent_safety. unwrap_or ( r) ,
1028+ all_phantom &= match self . check_field_type_for_ffi ( cache, & field, args) {
1029+ FfiSafe => false ,
1030+ FfiPhantom ( ..) => true ,
1031+ r @ FfiUnsafe { .. } => return r,
10411032 }
10421033 }
10431034
1044- if all_phantom { FfiPhantom ( ty) } else { transparent_safety. unwrap_or ( FfiSafe ) }
1035+ if all_phantom {
1036+ FfiPhantom ( ty)
1037+ } else if transparent_with_all_zst_fields {
1038+ FfiUnsafe { ty, reason : fluent:: lint_improper_ctypes_struct_zst, help : None }
1039+ } else {
1040+ FfiSafe
1041+ }
10451042 }
10461043
10471044 /// Checks if the given type is "ffi-safe" (has a stable, well-defined
0 commit comments