@@ -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 } ;
7+ use rustc:: ty:: { self , AdtKind , ParamEnv , Ty , TyCtxt , TypeFoldable } ;
88use rustc:: ty:: layout:: { self , IntegerExt , LayoutOf , VariantIdx , SizeSkeleton } ;
99use rustc:: { lint, util} ;
1010use rustc_index:: vec:: Idx ;
@@ -835,16 +835,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
835835 ty:: Array ( ty, _) => self . check_type_for_ffi ( cache, ty) ,
836836
837837 ty:: FnPtr ( sig) => {
838- match sig. abi ( ) {
839- Abi :: Rust | Abi :: RustIntrinsic | Abi :: PlatformIntrinsic | Abi :: RustCall => {
840- return FfiUnsafe {
841- ty,
842- reason : "this function pointer has Rust-specific calling convention" ,
843- help : Some ( "consider using an `extern fn(...) -> ...` \
844- function pointer instead") ,
845- }
846- }
847- _ => { }
838+ if self . is_internal_abi ( sig. abi ( ) ) {
839+ return FfiUnsafe {
840+ ty,
841+ reason : "this function pointer has Rust-specific calling convention" ,
842+ help : Some ( "consider using an `extern fn(...) -> ...` \
843+ function pointer instead") ,
844+ } ;
848845 }
849846
850847 let sig = cx. erase_late_bound_regions ( & sig) ;
@@ -871,7 +868,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
871868
872869 ty:: Foreign ( ..) => FfiSafe ,
873870
874- ty:: Param ( ..) |
871+ // `extern "C" fn` functions can have type parameters, which may or may not be FFI-safe,
872+ // so they are currently ignored for the purposes of this lint, see #65134.
873+ ty:: Param ( ..) | ty:: Projection ( ..) => FfiSafe ,
874+
875875 ty:: Infer ( ..) |
876876 ty:: Bound ( ..) |
877877 ty:: Error |
@@ -880,7 +880,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
880880 ty:: GeneratorWitness ( ..) |
881881 ty:: Placeholder ( ..) |
882882 ty:: UnnormalizedProjection ( ..) |
883- ty:: Projection ( ..) |
884883 ty:: Opaque ( ..) |
885884 ty:: FnDef ( ..) => bug ! ( "unexpected type in foreign function: {:?}" , ty) ,
886885 }
@@ -912,8 +911,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
912911 }
913912
914913 fn check_for_opaque_ty ( & mut self , sp : Span , ty : Ty < ' tcx > ) -> bool {
915- use crate :: rustc:: ty:: TypeFoldable ;
916-
917914 struct ProhibitOpaqueTypes < ' tcx > {
918915 ty : Option < Ty < ' tcx > > ,
919916 } ;
@@ -952,10 +949,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
952949 return ;
953950 }
954951
955- // it is only OK to use this function because extern fns cannot have
956- // any generic types right now:
957- let ty = self . cx . tcx . normalize_erasing_regions ( ParamEnv :: reveal_all ( ) , ty) ;
958-
952+ let ty = self . cx . tcx . normalize_erasing_regions ( self . cx . param_env , ty) ;
959953 match self . check_type_for_ffi ( & mut FxHashSet :: default ( ) , ty) {
960954 FfiResult :: FfiSafe => { }
961955 FfiResult :: FfiPhantom ( ty) => {
@@ -989,15 +983,21 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
989983 let ty = self . cx . tcx . type_of ( def_id) ;
990984 self . check_type_for_ffi_and_report_errors ( span, ty) ;
991985 }
986+
987+ fn is_internal_abi ( & self , abi : Abi ) -> bool {
988+ if let Abi :: Rust | Abi :: RustCall | Abi :: RustIntrinsic | Abi :: PlatformIntrinsic = abi {
989+ true
990+ } else {
991+ false
992+ }
993+ }
992994}
993995
994996impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for ImproperCTypes {
995997 fn check_foreign_item ( & mut self , cx : & LateContext < ' _ , ' _ > , it : & hir:: ForeignItem ) {
996998 let mut vis = ImproperCTypesVisitor { cx } ;
997999 let abi = cx. tcx . hir ( ) . get_foreign_abi ( it. hir_id ) ;
998- if let Abi :: Rust | Abi :: RustCall | Abi :: RustIntrinsic | Abi :: PlatformIntrinsic = abi {
999- // Don't worry about types in internal ABIs.
1000- } else {
1000+ if !vis. is_internal_abi ( abi) {
10011001 match it. kind {
10021002 hir:: ForeignItemKind :: Fn ( ref decl, _, _) => {
10031003 vis. check_foreign_fn ( it. hir_id , decl) ;
@@ -1009,6 +1009,29 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
10091009 }
10101010 }
10111011 }
1012+
1013+ fn check_fn (
1014+ & mut self ,
1015+ cx : & LateContext < ' a , ' tcx > ,
1016+ kind : hir:: intravisit:: FnKind < ' tcx > ,
1017+ decl : & ' tcx hir:: FnDecl ,
1018+ _: & ' tcx hir:: Body ,
1019+ _: Span ,
1020+ hir_id : hir:: HirId ,
1021+ ) {
1022+ use hir:: intravisit:: FnKind ;
1023+
1024+ let abi = match kind {
1025+ FnKind :: ItemFn ( _, _, header, ..) => ( header. abi ) ,
1026+ FnKind :: Method ( _, sig, ..) => ( sig. header . abi ) ,
1027+ _ => return ,
1028+ } ;
1029+
1030+ let mut vis = ImproperCTypesVisitor { cx } ;
1031+ if !vis. is_internal_abi ( abi) {
1032+ vis. check_foreign_fn ( hir_id, decl) ;
1033+ }
1034+ }
10121035}
10131036
10141037declare_lint_pass ! ( VariantSizeDifferences => [ VARIANT_SIZE_DIFFERENCES ] ) ;
0 commit comments