@@ -943,30 +943,6 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
943
943
}
944
944
945
945
impl < ' a , ' tcx > ImproperCTypesVisitor < ' a , ' tcx > {
946
- // Returns `true` if `ty` is a `()`, or a `repr(transparent)` type whose only non-ZST field
947
- // is a generic substituted for `()` - in either case, the type is FFI-safe when used as a
948
- // return type.
949
- pub fn is_unit_or_equivalent ( & self , ty : Ty < ' tcx > ) -> bool {
950
- if ty. is_unit ( ) {
951
- return true ;
952
- }
953
-
954
- if let ty:: Adt ( def, substs) = ty. kind ( ) && def. repr ( ) . transparent ( ) {
955
- return def. variants ( )
956
- . iter ( )
957
- . filter_map ( |variant| transparent_newtype_field ( self . cx . tcx , variant) )
958
- . all ( |field| {
959
- let field_ty = field. ty ( self . cx . tcx , substs) ;
960
- !field_ty. has_opaque_types ( ) && {
961
- let field_ty = self . cx . tcx . normalize_erasing_regions ( self . cx . param_env , field_ty) ;
962
- self . is_unit_or_equivalent ( field_ty)
963
- }
964
- } ) ;
965
- }
966
-
967
- false
968
- }
969
-
970
946
/// Check if the type is array and emit an unsafe type lint.
971
947
fn check_for_array_ty ( & mut self , sp : Span , ty : Ty < ' tcx > ) -> bool {
972
948
if let ty:: Array ( ..) = ty. kind ( ) {
@@ -1010,14 +986,19 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1010
986
use FfiResult :: * ;
1011
987
1012
988
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..
1014
989
if let Some ( field) = transparent_newtype_field ( self . cx . tcx , variant) {
1015
- return self . check_field_type_for_ffi ( cache, field, args) ;
1016
- }
990
+ // Transparent newtypes have at most one non-ZST field which needs to be checked..
991
+ match self . check_field_type_for_ffi ( cache, field, args) {
992
+ FfiUnsafe { ty, .. } if ty. is_unit ( ) => ( ) ,
993
+ r => return r,
994
+ }
1017
995
1018
- // ..or have only ZST fields, which is FFI-unsafe (unless those fields are all
1019
- // `PhantomData`).
1020
- true
996
+ false
997
+ } else {
998
+ // ..or have only ZST fields, which is FFI-unsafe (unless those fields are all
999
+ // `PhantomData`).
1000
+ true
1001
+ }
1021
1002
} else {
1022
1003
false
1023
1004
} ;
@@ -1027,6 +1008,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1027
1008
for field in & variant. fields {
1028
1009
all_phantom &= match self . check_field_type_for_ffi ( cache, & field, args) {
1029
1010
FfiSafe => false ,
1011
+ // `()` fields are FFI-safe!
1012
+ FfiUnsafe { ty, .. } if ty. is_unit ( ) => false ,
1030
1013
FfiPhantom ( ..) => true ,
1031
1014
r @ FfiUnsafe { .. } => return r,
1032
1015
}
@@ -1249,7 +1232,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1249
1232
}
1250
1233
1251
1234
let ret_ty = sig. output ( ) ;
1252
- if self . is_unit_or_equivalent ( ret_ty ) {
1235
+ if ret_ty . is_unit ( ) {
1253
1236
return FfiSafe ;
1254
1237
}
1255
1238
@@ -1374,7 +1357,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1374
1357
// Don't report FFI errors for unit return types. This check exists here, and not in
1375
1358
// the caller (where it would make more sense) so that normalization has definitely
1376
1359
// happened.
1377
- if is_return_type && self . is_unit_or_equivalent ( ty ) {
1360
+ if is_return_type && ty . is_unit ( ) {
1378
1361
return ;
1379
1362
}
1380
1363
0 commit comments