@@ -1009,39 +1009,36 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1009
1009
) -> FfiResult < ' tcx > {
1010
1010
use FfiResult :: * ;
1011
1011
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..
1015
1014
if let Some ( field) = transparent_newtype_field ( self . cx . tcx , variant) {
1016
1015
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 }
1022
1016
}
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.
1026
1026
let mut all_phantom = !variant. fields . is_empty ( ) ;
1027
1027
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,
1041
1032
}
1042
1033
}
1043
1034
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
+ }
1045
1042
}
1046
1043
1047
1044
/// Checks if the given type is "ffi-safe" (has a stable, well-defined
0 commit comments