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