@@ -940,30 +940,6 @@ pub(crate) fn repr_nullable_ptr<'tcx>(
940940}
941941
942942impl < ' a , ' tcx > ImproperCTypesVisitor < ' a , ' tcx > {
943- // Returns `true` if `ty` is a `()`, or a `repr(transparent)` type whose only non-ZST field
944- // is a generic substituted for `()` - in either case, the type is FFI-safe when used as a
945- // return type.
946- pub fn is_unit_or_equivalent ( & self , ty : Ty < ' tcx > ) -> bool {
947- if ty. is_unit ( ) {
948- return true ;
949- }
950-
951- if let ty:: Adt ( def, substs) = ty. kind ( ) && def. repr ( ) . transparent ( ) {
952- return def. variants ( )
953- . iter ( )
954- . filter_map ( |variant| transparent_newtype_field ( self . cx . tcx , variant) )
955- . all ( |field| {
956- let field_ty = field. ty ( self . cx . tcx , substs) ;
957- !field_ty. has_opaque_types ( ) && {
958- let field_ty = self . cx . tcx . normalize_erasing_regions ( self . cx . param_env , field_ty) ;
959- self . is_unit_or_equivalent ( field_ty)
960- }
961- } ) ;
962- }
963-
964- false
965- }
966-
967943 /// Check if the type is array and emit an unsafe type lint.
968944 fn check_for_array_ty ( & mut self , sp : Span , ty : Ty < ' tcx > ) -> bool {
969945 if let ty:: Array ( ..) = ty. kind ( ) {
@@ -1007,14 +983,19 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
1007983 use FfiResult :: * ;
1008984
1009985 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..
1011986 if let Some ( field) = transparent_newtype_field ( self . cx . tcx , variant) {
1012- return self . check_field_type_for_ffi ( cache, field, substs) ;
1013- }
987+ // Transparent newtypes have at most one non-ZST field which needs to be checked..
988+ match self . check_field_type_for_ffi ( cache, field, substs) {
989+ FfiUnsafe { ty, .. } if ty. is_unit ( ) => ( ) ,
990+ r => return r,
991+ }
1014992
1015- // ..or have only ZST fields, which is FFI-unsafe (unless those fields are all
1016- // `PhantomData`).
1017- true
993+ false
994+ } else {
995+ // ..or have only ZST fields, which is FFI-unsafe (unless those fields are all
996+ // `PhantomData`).
997+ true
998+ }
1018999 } else {
10191000 false
10201001 } ;
@@ -1024,6 +1005,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
10241005 for field in & variant. fields {
10251006 all_phantom &= match self . check_field_type_for_ffi ( cache, & field, substs) {
10261007 FfiSafe => false ,
1008+ // `()` fields are FFI-safe!
1009+ FfiUnsafe { ty, .. } if ty. is_unit ( ) => false ,
10271010 FfiPhantom ( ..) => true ,
10281011 r @ FfiUnsafe { .. } => return r,
10291012 }
@@ -1246,7 +1229,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
12461229 }
12471230
12481231 let ret_ty = sig. output ( ) ;
1249- if self . is_unit_or_equivalent ( ret_ty ) {
1232+ if ret_ty . is_unit ( ) {
12501233 return FfiSafe ;
12511234 }
12521235
@@ -1371,7 +1354,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
13711354 // Don't report FFI errors for unit return types. This check exists here, and not in
13721355 // the caller (where it would make more sense) so that normalization has definitely
13731356 // happened.
1374- if is_return_type && self . is_unit_or_equivalent ( ty ) {
1357+ if is_return_type && ty . is_unit ( ) {
13751358 return ;
13761359 }
13771360
0 commit comments