@@ -946,7 +946,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
946
946
}
947
947
}
948
948
949
- fn check_type_for_ffi_and_report_errors ( & mut self , sp : Span , ty : Ty < ' tcx > , is_static : bool ) {
949
+ fn check_type_for_ffi_and_report_errors (
950
+ & mut self ,
951
+ sp : Span ,
952
+ ty : Ty < ' tcx > ,
953
+ is_static : bool ,
954
+ is_return_type : bool ,
955
+ ) {
950
956
// We have to check for opaque types before `normalize_erasing_regions`,
951
957
// which will replace opaque types with their underlying concrete type.
952
958
if self . check_for_opaque_ty ( sp, ty) {
@@ -957,14 +963,21 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
957
963
// it is only OK to use this function because extern fns cannot have
958
964
// any generic types right now:
959
965
let ty = self . cx . tcx . normalize_erasing_regions ( ParamEnv :: reveal_all ( ) , ty) ;
960
- // C doesn't really support passing arrays by value.
961
- // The only way to pass an array by value is through a struct.
962
- // So we first test that the top level isn't an array,
963
- // and then recursively check the types inside.
966
+
967
+ // C doesn't really support passing arrays by value - the only way to pass an array by value
968
+ // is through a struct. So, first test that the top level isn't an array, and then
969
+ // recursively check the types inside.
964
970
if !is_static && self . check_for_array_ty ( sp, ty) {
965
971
return ;
966
972
}
967
973
974
+ // Don't report FFI errors for unit return types. This check exists here, and not in
975
+ // `check_foreign_fn` (where it would make more sense) so that normalization has definitely
976
+ // happened.
977
+ if is_return_type && ty. is_unit ( ) {
978
+ return ;
979
+ }
980
+
968
981
match self . check_type_for_ffi ( & mut FxHashSet :: default ( ) , ty) {
969
982
FfiResult :: FfiSafe => { }
970
983
FfiResult :: FfiPhantom ( ty) => {
@@ -982,21 +995,19 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
982
995
let sig = self . cx . tcx . erase_late_bound_regions ( & sig) ;
983
996
984
997
for ( input_ty, input_hir) in sig. inputs ( ) . iter ( ) . zip ( decl. inputs ) {
985
- self . check_type_for_ffi_and_report_errors ( input_hir. span , input_ty, false ) ;
998
+ self . check_type_for_ffi_and_report_errors ( input_hir. span , input_ty, false , false ) ;
986
999
}
987
1000
988
1001
if let hir:: FnRetTy :: Return ( ref ret_hir) = decl. output {
989
1002
let ret_ty = sig. output ( ) ;
990
- if !ret_ty. is_unit ( ) {
991
- self . check_type_for_ffi_and_report_errors ( ret_hir. span , ret_ty, false ) ;
992
- }
1003
+ self . check_type_for_ffi_and_report_errors ( ret_hir. span , ret_ty, false , true ) ;
993
1004
}
994
1005
}
995
1006
996
1007
fn check_foreign_static ( & mut self , id : hir:: HirId , span : Span ) {
997
1008
let def_id = self . cx . tcx . hir ( ) . local_def_id ( id) ;
998
1009
let ty = self . cx . tcx . type_of ( def_id) ;
999
- self . check_type_for_ffi_and_report_errors ( span, ty, true ) ;
1010
+ self . check_type_for_ffi_and_report_errors ( span, ty, true , false ) ;
1000
1011
}
1001
1012
}
1002
1013
0 commit comments