@@ -4,7 +4,7 @@ use rustc::hir::{ExprKind, Node};
44use crate :: hir:: def_id:: DefId ;
55use rustc:: hir:: lowering:: is_range_literal;
66use rustc:: ty:: subst:: SubstsRef ;
7- use rustc:: ty:: { self , AdtKind , ParamEnv , Ty , TyCtxt , TypeFoldable } ;
7+ use rustc:: ty:: { self , AdtKind , ParamEnv , Ty , TyCtxt } ;
88use rustc:: ty:: layout:: { self , IntegerExt , LayoutOf , VariantIdx , SizeSkeleton } ;
99use rustc:: { lint, util} ;
1010use rustc_index:: vec:: Idx ;
@@ -837,13 +837,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
837837 ty:: Array ( ty, _) => self . check_type_for_ffi ( cache, ty) ,
838838
839839 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+ _ => { }
847850 }
848851
849852 let sig = cx. erase_late_bound_regions ( & sig) ;
@@ -870,10 +873,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
870873
871874 ty:: Foreign ( ..) => FfiSafe ,
872875
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 ( ..) |
877877 ty:: Infer ( ..) |
878878 ty:: Bound ( ..) |
879879 ty:: Error |
@@ -882,6 +882,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
882882 ty:: GeneratorWitness ( ..) |
883883 ty:: Placeholder ( ..) |
884884 ty:: UnnormalizedProjection ( ..) |
885+ ty:: Projection ( ..) |
885886 ty:: Opaque ( ..) |
886887 ty:: FnDef ( ..) => bug ! ( "unexpected type in foreign function: {:?}" , ty) ,
887888 }
@@ -893,16 +894,11 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
893894 sp : Span ,
894895 note : & str ,
895896 help : Option < & str > ,
896- is_foreign_item : bool ,
897897 ) {
898898 let mut diag = self . cx . struct_span_lint (
899899 IMPROPER_CTYPES ,
900900 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) ,
906902 ) ;
907903 diag. span_label ( sp, "not FFI-safe" ) ;
908904 if let Some ( help) = help {
@@ -917,7 +913,9 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
917913 diag. emit ( ) ;
918914 }
919915
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+
921919 struct ProhibitOpaqueTypes < ' tcx > {
922920 ty : Option < Ty < ' tcx > > ,
923921 } ;
@@ -941,81 +939,70 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
941939 sp,
942940 "opaque types have no C equivalent" ,
943941 None ,
944- is_foreign_item,
945942 ) ;
946943 true
947944 } else {
948945 false
949946 }
950947 }
951948
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 > ) {
958950 // We have to check for opaque types before `normalize_erasing_regions`,
959951 // 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) {
961953 // We've already emitted an error due to an opaque type.
962954 return ;
963955 }
964956
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+
966961 match self . check_type_for_ffi ( & mut FxHashSet :: default ( ) , ty) {
967962 FfiResult :: FfiSafe => { }
968963 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 ) ;
971965 }
972966 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) ;
975968 }
976969 }
977970 }
978971
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 ) {
980973 let def_id = self . cx . tcx . hir ( ) . local_def_id ( id) ;
981974 let sig = self . cx . tcx . fn_sig ( def_id) ;
982975 let sig = self . cx . tcx . erase_late_bound_regions ( & sig) ;
983976
984977 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) ;
986979 }
987980
988981 if let hir:: Return ( ref ret_hir) = decl. output {
989982 let ret_ty = sig. output ( ) ;
990983 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) ;
992985 }
993986 }
994987 }
995988
996989 fn check_foreign_static ( & mut self , id : hir:: HirId , span : Span ) {
997990 let def_id = self . cx . tcx . hir ( ) . local_def_id ( id) ;
998991 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) ;
1008993 }
1009994}
1010995
1011996impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for ImproperCTypes {
1012997 fn check_foreign_item ( & mut self , cx : & LateContext < ' _ , ' _ > , it : & hir:: ForeignItem ) {
1013998 let mut vis = ImproperCTypesVisitor { cx } ;
1014999 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 {
10161003 match it. kind {
10171004 hir:: ForeignItemKind :: Fn ( ref decl, _, _) => {
1018- vis. check_foreign_fn ( it. hir_id , decl, true ) ;
1005+ vis. check_foreign_fn ( it. hir_id , decl) ;
10191006 }
10201007 hir:: ForeignItemKind :: Static ( ref ty, _) => {
10211008 vis. check_foreign_static ( it. hir_id , ty. span ) ;
@@ -1024,29 +1011,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
10241011 }
10251012 }
10261013 }
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- }
10501014}
10511015
10521016declare_lint_pass ! ( VariantSizeDifferences => [ VARIANT_SIZE_DIFFERENCES ] ) ;
0 commit comments