@@ -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 } ;
7
+ use rustc:: ty:: { self , AdtKind , ParamEnv , Ty , TyCtxt , TypeFoldable } ;
8
8
use rustc:: ty:: layout:: { self , IntegerExt , LayoutOf , VariantIdx , SizeSkeleton } ;
9
9
use rustc:: { lint, util} ;
10
10
use rustc_index:: vec:: Idx ;
@@ -835,16 +835,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
835
835
ty:: Array ( ty, _) => self . check_type_for_ffi ( cache, ty) ,
836
836
837
837
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
+ } ;
848
845
}
849
846
850
847
let sig = cx. erase_late_bound_regions ( & sig) ;
@@ -871,7 +868,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
871
868
872
869
ty:: Foreign ( ..) => FfiSafe ,
873
870
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
+
875
875
ty:: Infer ( ..) |
876
876
ty:: Bound ( ..) |
877
877
ty:: Error |
@@ -880,7 +880,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
880
880
ty:: GeneratorWitness ( ..) |
881
881
ty:: Placeholder ( ..) |
882
882
ty:: UnnormalizedProjection ( ..) |
883
- ty:: Projection ( ..) |
884
883
ty:: Opaque ( ..) |
885
884
ty:: FnDef ( ..) => bug ! ( "unexpected type in foreign function: {:?}" , ty) ,
886
885
}
@@ -912,8 +911,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
912
911
}
913
912
914
913
fn check_for_opaque_ty ( & mut self , sp : Span , ty : Ty < ' tcx > ) -> bool {
915
- use crate :: rustc:: ty:: TypeFoldable ;
916
-
917
914
struct ProhibitOpaqueTypes < ' tcx > {
918
915
ty : Option < Ty < ' tcx > > ,
919
916
} ;
@@ -952,10 +949,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
952
949
return ;
953
950
}
954
951
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) ;
959
953
match self . check_type_for_ffi ( & mut FxHashSet :: default ( ) , ty) {
960
954
FfiResult :: FfiSafe => { }
961
955
FfiResult :: FfiPhantom ( ty) => {
@@ -989,15 +983,21 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
989
983
let ty = self . cx . tcx . type_of ( def_id) ;
990
984
self . check_type_for_ffi_and_report_errors ( span, ty) ;
991
985
}
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
+ }
992
994
}
993
995
994
996
impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for ImproperCTypes {
995
997
fn check_foreign_item ( & mut self , cx : & LateContext < ' _ , ' _ > , it : & hir:: ForeignItem ) {
996
998
let mut vis = ImproperCTypesVisitor { cx } ;
997
999
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) {
1001
1001
match it. kind {
1002
1002
hir:: ForeignItemKind :: Fn ( ref decl, _, _) => {
1003
1003
vis. check_foreign_fn ( it. hir_id , decl) ;
@@ -1009,6 +1009,29 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ImproperCTypes {
1009
1009
}
1010
1010
}
1011
1011
}
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
+ }
1012
1035
}
1013
1036
1014
1037
declare_lint_pass ! ( VariantSizeDifferences => [ VARIANT_SIZE_DIFFERENCES ] ) ;
0 commit comments