@@ -29,7 +29,6 @@ use syntax::attr::{self, AttrMetaMethods};
2929use syntax:: codemap:: { self , Span } ;
3030
3131use rustc_front:: hir;
32- use rustc_front:: intravisit:: { self , Visitor } ;
3332use rustc_front:: util:: is_shift_binop;
3433
3534register_long_diagnostics ! {
@@ -403,16 +402,6 @@ fn is_repr_nullable_ptr<'tcx>(tcx: &TyCtxt<'tcx>,
403402 false
404403}
405404
406- fn ast_ty_to_normalized < ' tcx > ( tcx : & TyCtxt < ' tcx > ,
407- id : ast:: NodeId )
408- -> Ty < ' tcx > {
409- let tty = match tcx. ast_ty_to_ty_cache . borrow ( ) . get ( & id) {
410- Some ( & t) => t,
411- None => panic ! ( "ast_ty_to_ty_cache was incomplete after typeck!" )
412- } ;
413- infer:: normalize_associated_type ( tcx, & tty)
414- }
415-
416405impl < ' a , ' tcx > ImproperCTypesVisitor < ' a , ' tcx > {
417406 /// Check if the given type is "ffi-safe" (has a stable, well-defined
418407 /// representation which can be exported to C code).
@@ -604,10 +593,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
604593 }
605594 }
606595
607- fn check_def ( & mut self , sp : Span , id : ast:: NodeId ) {
608- let tty = ast_ty_to_normalized ( self . cx . tcx , id) ;
596+ fn check_type_for_ffi_and_report_errors ( & mut self , sp : Span , ty : Ty < ' tcx > ) {
597+ // it is only OK to use this function because extern fns cannot have
598+ // any generic types right now:
599+ let ty = infer:: normalize_associated_type ( self . cx . tcx , & ty) ;
609600
610- match ImproperCTypesVisitor :: check_type_for_ffi ( self , & mut FnvHashSet ( ) , tty ) {
601+ match self . check_type_for_ffi ( & mut FnvHashSet ( ) , ty ) {
611602 FfiResult :: FfiSafe => { }
612603 FfiResult :: FfiUnsafe ( s) => {
613604 self . cx . span_lint ( IMPROPER_CTYPES , sp, s) ;
@@ -628,27 +619,30 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
628619 }
629620 }
630621 }
631- }
632622
633- impl < ' a , ' tcx , ' v > Visitor < ' v > for ImproperCTypesVisitor < ' a , ' tcx > {
634- fn visit_ty ( & mut self , ty : & hir:: Ty ) {
635- match ty. node {
636- hir:: TyPath ( ..) |
637- hir:: TyBareFn ( ..) => self . check_def ( ty. span , ty. id ) ,
638- hir:: TyVec ( ..) => {
639- self . cx . span_lint ( IMPROPER_CTYPES , ty. span ,
640- "found Rust slice type in foreign module, consider \
641- using a raw pointer instead") ;
642- }
643- hir:: TyFixedLengthVec ( ref ty, _) => self . visit_ty ( ty) ,
644- hir:: TyTup ( ..) => {
645- self . cx . span_lint ( IMPROPER_CTYPES , ty. span ,
646- "found Rust tuple type in foreign module; \
647- consider using a struct instead`")
623+ fn check_foreign_fn ( & mut self , id : ast:: NodeId , decl : & hir:: FnDecl ) {
624+ let def_id = self . cx . tcx . map . local_def_id ( id) ;
625+ let scheme = self . cx . tcx . lookup_item_type ( def_id) ;
626+ let sig = scheme. ty . fn_sig ( ) ;
627+ let sig = self . cx . tcx . erase_late_bound_regions ( & sig) ;
628+
629+ for ( & input_ty, input_hir) in sig. inputs . iter ( ) . zip ( & decl. inputs ) {
630+ self . check_type_for_ffi_and_report_errors ( input_hir. ty . span , & input_ty) ;
631+ }
632+
633+ if let hir:: Return ( ref ret_hir) = decl. output {
634+ let ret_ty = sig. output . unwrap ( ) ;
635+ if !ret_ty. is_nil ( ) {
636+ self . check_type_for_ffi_and_report_errors ( ret_hir. span , ret_ty) ;
648637 }
649- _ => intravisit:: walk_ty ( self , ty)
650638 }
651639 }
640+
641+ fn check_foreign_static ( & mut self , id : ast:: NodeId , span : Span ) {
642+ let def_id = self . cx . tcx . map . local_def_id ( id) ;
643+ let scheme = self . cx . tcx . lookup_item_type ( def_id) ;
644+ self . check_type_for_ffi_and_report_errors ( span, scheme. ty ) ;
645+ }
652646}
653647
654648#[ derive( Copy , Clone ) ]
@@ -662,29 +656,17 @@ impl LintPass for ImproperCTypes {
662656
663657impl LateLintPass for ImproperCTypes {
664658 fn check_item ( & mut self , cx : & LateContext , it : & hir:: Item ) {
665- fn check_ty ( cx : & LateContext , ty : & hir:: Ty ) {
666- let mut vis = ImproperCTypesVisitor { cx : cx } ;
667- vis. visit_ty ( ty) ;
668- }
669-
670- fn check_foreign_fn ( cx : & LateContext , decl : & hir:: FnDecl ) {
671- for input in & decl. inputs {
672- check_ty ( cx, & input. ty ) ;
673- }
674- if let hir:: Return ( ref ret_ty) = decl. output {
675- let tty = ast_ty_to_normalized ( cx. tcx , ret_ty. id ) ;
676- if !tty. is_nil ( ) {
677- check_ty ( cx, & ret_ty) ;
678- }
679- }
680- }
681-
659+ let mut vis = ImproperCTypesVisitor { cx : cx } ;
682660 if let hir:: ItemForeignMod ( ref nmod) = it. node {
683661 if nmod. abi != Abi :: RustIntrinsic && nmod. abi != Abi :: PlatformIntrinsic {
684662 for ni in & nmod. items {
685663 match ni. node {
686- hir:: ForeignItemFn ( ref decl, _) => check_foreign_fn ( cx, & decl) ,
687- hir:: ForeignItemStatic ( ref t, _) => check_ty ( cx, & t)
664+ hir:: ForeignItemFn ( ref decl, _) => {
665+ vis. check_foreign_fn ( ni. id , decl) ;
666+ }
667+ hir:: ForeignItemStatic ( ref ty, _) => {
668+ vis. check_foreign_static ( ni. id , ty. span ) ;
669+ }
688670 }
689671 }
690672 }
0 commit comments