@@ -29,7 +29,6 @@ use syntax::attr::{self, AttrMetaMethods};
29
29
use syntax:: codemap:: { self , Span } ;
30
30
31
31
use rustc_front:: hir;
32
- use rustc_front:: intravisit:: { self , Visitor } ;
33
32
use rustc_front:: util:: is_shift_binop;
34
33
35
34
register_long_diagnostics ! {
@@ -403,16 +402,6 @@ fn is_repr_nullable_ptr<'tcx>(tcx: &TyCtxt<'tcx>,
403
402
false
404
403
}
405
404
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
-
416
405
impl < ' a , ' tcx > ImproperCTypesVisitor < ' a , ' tcx > {
417
406
/// Check if the given type is "ffi-safe" (has a stable, well-defined
418
407
/// representation which can be exported to C code).
@@ -604,10 +593,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
604
593
}
605
594
}
606
595
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) ;
609
600
610
- match ImproperCTypesVisitor :: check_type_for_ffi ( self , & mut FnvHashSet ( ) , tty ) {
601
+ match self . check_type_for_ffi ( & mut FnvHashSet ( ) , ty ) {
611
602
FfiResult :: FfiSafe => { }
612
603
FfiResult :: FfiUnsafe ( s) => {
613
604
self . cx . span_lint ( IMPROPER_CTYPES , sp, s) ;
@@ -628,27 +619,30 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
628
619
}
629
620
}
630
621
}
631
- }
632
622
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) ;
648
637
}
649
- _ => intravisit:: walk_ty ( self , ty)
650
638
}
651
639
}
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
+ }
652
646
}
653
647
654
648
#[ derive( Copy , Clone ) ]
@@ -662,29 +656,17 @@ impl LintPass for ImproperCTypes {
662
656
663
657
impl LateLintPass for ImproperCTypes {
664
658
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 } ;
682
660
if let hir:: ItemForeignMod ( ref nmod) = it. node {
683
661
if nmod. abi != Abi :: RustIntrinsic && nmod. abi != Abi :: PlatformIntrinsic {
684
662
for ni in & nmod. items {
685
663
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
+ }
688
670
}
689
671
}
690
672
}
0 commit comments