@@ -4,7 +4,7 @@ use rustc::hir::{ExprKind, Node};
4
4
use crate :: hir:: def_id:: DefId ;
5
5
use rustc:: hir:: lowering:: is_range_literal;
6
6
use rustc:: ty:: subst:: SubstsRef ;
7
- use rustc:: ty:: { self , AdtKind , ParamEnv , Ty , TyCtxt , TypeFoldable } ;
7
+ use rustc:: ty:: { self , AdtKind , ParamEnv , Ty , TyCtxt } ;
8
8
use rustc:: ty:: layout:: { self , IntegerExt , LayoutOf , VariantIdx , SizeSkeleton } ;
9
9
use rustc:: { lint, util} ;
10
10
use rustc_index:: vec:: Idx ;
@@ -837,13 +837,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
837
837
ty:: Array ( ty, _) => self . check_type_for_ffi ( cache, ty) ,
838
838
839
839
ty:: FnPtr ( sig) => {
840
- if self . is_internal_abi ( sig. abi ( ) ) {
841
- return FfiUnsafe {
842
- ty,
843
- reason : "this function pointer has Rust-specific calling convention" ,
844
- help : Some ( "consider using an `extern fn(...) -> ...` \
845
- function pointer instead") ,
846
- } ;
840
+ match sig. abi ( ) {
841
+ Abi :: Rust | Abi :: RustIntrinsic | Abi :: PlatformIntrinsic | Abi :: RustCall => {
842
+ return FfiUnsafe {
843
+ ty,
844
+ reason : "this function pointer has Rust-specific calling convention" ,
845
+ help : Some ( "consider using an `extern fn(...) -> ...` \
846
+ function pointer instead") ,
847
+ }
848
+ }
849
+ _ => { }
847
850
}
848
851
849
852
let sig = cx. erase_late_bound_regions ( & sig) ;
@@ -870,10 +873,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
870
873
871
874
ty:: Foreign ( ..) => FfiSafe ,
872
875
873
- // `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe,
874
- // so they are currently ignored for the purposes of this lint, see #65134.
875
- ty:: Param ( ..) | ty:: Projection ( ..) => FfiSafe ,
876
-
876
+ ty:: Param ( ..) |
877
877
ty:: Infer ( ..) |
878
878
ty:: Bound ( ..) |
879
879
ty:: Error |
@@ -882,6 +882,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
882
882
ty:: GeneratorWitness ( ..) |
883
883
ty:: Placeholder ( ..) |
884
884
ty:: UnnormalizedProjection ( ..) |
885
+ ty:: Projection ( ..) |
885
886
ty:: Opaque ( ..) |
886
887
ty:: FnDef ( ..) => bug ! ( "unexpected type in foreign function: {:?}" , ty) ,
887
888
}
@@ -893,16 +894,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
893
894
sp : Span ,
894
895
note : & str ,
895
896
help : Option < & str > ,
896
- is_foreign_item : bool ,
897
897
) {
898
898
let mut diag = self . cx . struct_span_lint (
899
899
IMPROPER_CTYPES ,
900
900
sp,
901
- & format ! (
902
- "`extern` {} uses type `{}`, which is not FFI-safe" ,
903
- if is_foreign_item { "block" } else { "fn" } ,
904
- ty,
905
- ) ,
901
+ & format ! ( "`extern` block uses type `{}`, which is not FFI-safe" , ty) ,
906
902
) ;
907
903
diag. span_label ( sp, "not FFI-safe" ) ;
908
904
if let Some ( help) = help {
@@ -917,7 +913,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
917
913
diag. emit ( ) ;
918
914
}
919
915
920
- fn check_for_opaque_ty ( & mut self , sp : Span , ty : Ty < ' tcx > , is_foreign_item : bool ) -> bool {
916
+ fn check_for_opaque_ty ( & mut self , sp : Span , ty : Ty < ' tcx > ) -> bool {
917
+ use crate :: rustc:: ty:: TypeFoldable ;
918
+
921
919
struct ProhibitOpaqueTypes < ' tcx > {
922
920
ty : Option < Ty < ' tcx > > ,
923
921
} ;
@@ -941,81 +939,70 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
941
939
sp,
942
940
"opaque types have no C equivalent" ,
943
941
None ,
944
- is_foreign_item,
945
942
) ;
946
943
true
947
944
} else {
948
945
false
949
946
}
950
947
}
951
948
952
- fn check_type_for_ffi_and_report_errors (
953
- & mut self ,
954
- sp : Span ,
955
- ty : Ty < ' tcx > ,
956
- is_foreign_item : bool ,
957
- ) {
949
+ fn check_type_for_ffi_and_report_errors ( & mut self , sp : Span , ty : Ty < ' tcx > ) {
958
950
// We have to check for opaque types before `normalize_erasing_regions`,
959
951
// which will replace opaque types with their underlying concrete type.
960
- if self . check_for_opaque_ty ( sp, ty, is_foreign_item ) {
952
+ if self . check_for_opaque_ty ( sp, ty) {
961
953
// We've already emitted an error due to an opaque type.
962
954
return ;
963
955
}
964
956
965
- let ty = self . cx . tcx . normalize_erasing_regions ( self . cx . param_env , ty) ;
957
+ // it is only OK to use this function because extern fns cannot have
958
+ // any generic types right now:
959
+ let ty = self . cx . tcx . normalize_erasing_regions ( ParamEnv :: reveal_all ( ) , ty) ;
960
+
966
961
match self . check_type_for_ffi ( & mut FxHashSet :: default ( ) , ty) {
967
962
FfiResult :: FfiSafe => { }
968
963
FfiResult :: FfiPhantom ( ty) => {
969
- self . emit_ffi_unsafe_type_lint (
970
- ty, sp, "composed only of `PhantomData`" , None , is_foreign_item) ;
964
+ self . emit_ffi_unsafe_type_lint ( ty, sp, "composed only of `PhantomData`" , None ) ;
971
965
}
972
966
FfiResult :: FfiUnsafe { ty, reason, help } => {
973
- self . emit_ffi_unsafe_type_lint (
974
- ty, sp, reason, help, is_foreign_item) ;
967
+ self . emit_ffi_unsafe_type_lint ( ty, sp, reason, help) ;
975
968
}
976
969
}
977
970
}
978
971
979
- fn check_foreign_fn ( & mut self , id : hir:: HirId , decl : & hir:: FnDecl , is_foreign_item : bool ) {
972
+ fn check_foreign_fn ( & mut self , id : hir:: HirId , decl : & hir:: FnDecl ) {
980
973
let def_id = self . cx . tcx . hir ( ) . local_def_id ( id) ;
981
974
let sig = self . cx . tcx . fn_sig ( def_id) ;
982
975
let sig = self . cx . tcx . erase_late_bound_regions ( & sig) ;
983
976
984
977
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, is_foreign_item ) ;
978
+ self . check_type_for_ffi_and_report_errors ( input_hir. span , input_ty) ;
986
979
}
987
980
988
981
if let hir:: Return ( ref ret_hir) = decl. output {
989
982
let ret_ty = sig. output ( ) ;
990
983
if !ret_ty. is_unit ( ) {
991
- self . check_type_for_ffi_and_report_errors ( ret_hir. span , ret_ty, is_foreign_item ) ;
984
+ self . check_type_for_ffi_and_report_errors ( ret_hir. span , ret_ty) ;
992
985
}
993
986
}
994
987
}
995
988
996
989
fn check_foreign_static ( & mut self , id : hir:: HirId , span : Span ) {
997
990
let def_id = self . cx . tcx . hir ( ) . local_def_id ( id) ;
998
991
let ty = self . cx . tcx . type_of ( def_id) ;
999
- self . check_type_for_ffi_and_report_errors ( span, ty, true ) ;
1000
- }
1001
-
1002
- fn is_internal_abi ( & self , abi : Abi ) -> bool {
1003
- if let Abi :: Rust | Abi :: RustCall | Abi :: RustIntrinsic | Abi :: PlatformIntrinsic = abi {
1004
- true
1005
- } else {
1006
- false
1007
- }
992
+ self . check_type_for_ffi_and_report_errors ( span, ty) ;
1008
993
}
1009
994
}
1010
995
1011
996
impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for ImproperCTypes {
1012
997
fn check_foreign_item ( & mut self , cx : & LateContext < ' _ , ' _ > , it : & hir:: ForeignItem ) {
1013
998
let mut vis = ImproperCTypesVisitor { cx } ;
1014
999
let abi = cx. tcx . hir ( ) . get_foreign_abi ( it. hir_id ) ;
1015
- if !vis. is_internal_abi ( abi) {
1000
+ if let Abi :: Rust | Abi :: RustCall | Abi :: RustIntrinsic | Abi :: PlatformIntrinsic = abi {
1001
+ // Don't worry about types in internal ABIs.
1002
+ } else {
1016
1003
match it. kind {
1017
1004
hir:: ForeignItemKind :: Fn ( ref decl, _, _) => {
1018
- vis. check_foreign_fn ( it. hir_id , decl, true ) ;
1005
+ vis. check_foreign_fn ( it. hir_id , decl) ;
1019
1006
}
1020
1007
hir:: ForeignItemKind :: Static ( ref ty, _) => {
1021
1008
vis. check_foreign_static ( it. hir_id , ty. span ) ;
@@ -1024,29 +1011,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
1024
1011
}
1025
1012
}
1026
1013
}
1027
-
1028
- fn check_fn (
1029
- & mut self ,
1030
- cx : & LateContext < ' a , ' tcx > ,
1031
- kind : hir:: intravisit:: FnKind < ' tcx > ,
1032
- decl : & ' tcx hir:: FnDecl ,
1033
- _: & ' tcx hir:: Body ,
1034
- _: Span ,
1035
- hir_id : hir:: HirId ,
1036
- ) {
1037
- use hir:: intravisit:: FnKind ;
1038
-
1039
- let abi = match kind {
1040
- FnKind :: ItemFn ( _, _, header, ..) => ( header. abi ) ,
1041
- FnKind :: Method ( _, sig, ..) => ( sig. header . abi ) ,
1042
- _ => return ,
1043
- } ;
1044
-
1045
- let mut vis = ImproperCTypesVisitor { cx } ;
1046
- if !vis. is_internal_abi ( abi) {
1047
- vis. check_foreign_fn ( hir_id, decl, false ) ;
1048
- }
1049
- }
1050
1014
}
1051
1015
1052
1016
declare_lint_pass ! ( VariantSizeDifferences => [ VARIANT_SIZE_DIFFERENCES ] ) ;
0 commit comments