@@ -943,30 +943,6 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
943943}
944944
945945impl < ' 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-
970946 /// Check if the type is array and emit an unsafe type lint.
971947 fn check_for_array_ty ( & mut self , sp : Span , ty : Ty < ' tcx > ) -> bool {
972948 if let ty:: Array ( ..) = ty. kind ( ) {
@@ -1010,14 +986,19 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1010986 use FfiResult :: * ;
1011987
1012988 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..
1014989 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+ }
1017995
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+ }
10211002 } else {
10221003 false
10231004 } ;
@@ -1027,6 +1008,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10271008 for field in & variant. fields {
10281009 all_phantom &= match self . check_field_type_for_ffi ( cache, & field, args) {
10291010 FfiSafe => false ,
1011+ // `()` fields are FFI-safe!
1012+ FfiUnsafe { ty, .. } if ty. is_unit ( ) => false ,
10301013 FfiPhantom ( ..) => true ,
10311014 r @ FfiUnsafe { .. } => return r,
10321015 }
@@ -1249,7 +1232,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
12491232 }
12501233
12511234 let ret_ty = sig. output ( ) ;
1252- if self . is_unit_or_equivalent ( ret_ty ) {
1235+ if ret_ty . is_unit ( ) {
12531236 return FfiSafe ;
12541237 }
12551238
@@ -1374,7 +1357,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
13741357 // Don't report FFI errors for unit return types. This check exists here, and not in
13751358 // the caller (where it would make more sense) so that normalization has definitely
13761359 // happened.
1377- if is_return_type && self . is_unit_or_equivalent ( ty ) {
1360+ if is_return_type && ty . is_unit ( ) {
13781361 return ;
13791362 }
13801363
0 commit comments