17
17
18
18
#[ macro_use] extern crate rustc;
19
19
#[ macro_use] extern crate syntax;
20
+ extern crate rustc_typeck;
20
21
extern crate syntax_pos;
21
22
22
23
use rustc:: hir:: { self , PatKind } ;
@@ -658,65 +659,6 @@ impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
658
659
}
659
660
false
660
661
}
661
-
662
- fn check_item ( & mut self , item_id : ast:: NodeId ) -> & mut Self {
663
- self . current_item = self . tcx . hir . local_def_id ( item_id) ;
664
- self . span = self . tcx . hir . span ( item_id) ;
665
- self
666
- }
667
-
668
- // Convenience methods for checking item interfaces
669
- fn ty ( & mut self ) -> & mut Self {
670
- self . tcx . type_of ( self . current_item ) . visit_with ( self ) ;
671
- self
672
- }
673
-
674
- fn generics ( & mut self ) -> & mut Self {
675
- for def in & self . tcx . generics_of ( self . current_item ) . types {
676
- if def. has_default {
677
- self . tcx . type_of ( def. def_id ) . visit_with ( self ) ;
678
- }
679
- }
680
- self
681
- }
682
-
683
- fn predicates ( & mut self ) -> & mut Self {
684
- let predicates = self . tcx . predicates_of ( self . current_item ) ;
685
- for predicate in & predicates. predicates {
686
- predicate. visit_with ( self ) ;
687
- match predicate {
688
- & ty:: Predicate :: Trait ( poly_predicate) => {
689
- self . check_trait_ref ( poly_predicate. skip_binder ( ) . trait_ref ) ;
690
- } ,
691
- & ty:: Predicate :: Projection ( poly_predicate) => {
692
- let tcx = self . tcx ;
693
- self . check_trait_ref (
694
- poly_predicate. skip_binder ( ) . projection_ty . trait_ref ( tcx)
695
- ) ;
696
- } ,
697
- _ => ( ) ,
698
- } ;
699
- }
700
- self
701
- }
702
-
703
- fn impl_trait_ref ( & mut self ) -> & mut Self {
704
- if let Some ( impl_trait_ref) = self . tcx . impl_trait_ref ( self . current_item ) {
705
- self . check_trait_ref ( impl_trait_ref) ;
706
- }
707
- self . tcx . predicates_of ( self . current_item ) . visit_with ( self ) ;
708
- self
709
- }
710
-
711
- fn check_trait_ref ( & mut self , trait_ref : ty:: TraitRef < ' tcx > ) -> bool {
712
- if !self . item_is_accessible ( trait_ref. def_id ) {
713
- let msg = format ! ( "trait `{}` is private" , trait_ref) ;
714
- self . tcx . sess . span_err ( self . span , & msg) ;
715
- return true ;
716
- }
717
-
718
- trait_ref. super_visit_with ( self )
719
- }
720
662
}
721
663
722
664
impl < ' a , ' tcx > Visitor < ' tcx > for TypePrivacyVisitor < ' a , ' tcx > {
@@ -733,6 +675,35 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
733
675
self . tables = orig_tables;
734
676
}
735
677
678
+ fn visit_ty ( & mut self , hir_ty : & ' tcx hir:: Ty ) {
679
+ self . span = hir_ty. span ;
680
+ if let Some ( ty) = self . tables . node_id_to_type_opt ( hir_ty. hir_id ) {
681
+ // Types in bodies.
682
+ if ty. visit_with ( self ) {
683
+ return ;
684
+ }
685
+ } else {
686
+ // Types in signatures.
687
+ // FIXME: This is very ineffective. Ideally each HIR type should be converted
688
+ // into a semantic type only once and the result should be cached somehow.
689
+ if rustc_typeck:: hir_ty_to_ty ( self . tcx , hir_ty) . visit_with ( self ) {
690
+ return ;
691
+ }
692
+ }
693
+
694
+ intravisit:: walk_ty ( self , hir_ty) ;
695
+ }
696
+
697
+ fn visit_trait_ref ( & mut self , trait_ref : & ' tcx hir:: TraitRef ) {
698
+ if !self . item_is_accessible ( trait_ref. path . def . def_id ( ) ) {
699
+ let msg = format ! ( "trait `{:?}` is private" , trait_ref. path) ;
700
+ self . tcx . sess . span_err ( self . span , & msg) ;
701
+ return ;
702
+ }
703
+
704
+ intravisit:: walk_trait_ref ( self , trait_ref) ;
705
+ }
706
+
736
707
// Check types of expressions
737
708
fn visit_expr ( & mut self , expr : & ' tcx hir:: Expr ) {
738
709
if self . check_expr_pat_type ( expr. hir_id , expr. span ) {
@@ -807,63 +778,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
807
778
item. id ,
808
779
& mut self . tables ,
809
780
self . empty_tables ) ;
810
-
811
- match item. node {
812
- hir:: ItemExternCrate ( ..) | hir:: ItemMod ( ..) |
813
- hir:: ItemUse ( ..) | hir:: ItemGlobalAsm ( ..) => { }
814
- hir:: ItemConst ( ..) | hir:: ItemStatic ( ..) |
815
- hir:: ItemTy ( ..) | hir:: ItemFn ( ..) => {
816
- self . check_item ( item. id ) . generics ( ) . predicates ( ) . ty ( ) ;
817
- }
818
- hir:: ItemTrait ( .., ref trait_item_refs) => {
819
- self . check_item ( item. id ) . generics ( ) . predicates ( ) ;
820
- for trait_item_ref in trait_item_refs {
821
- let check = self . check_item ( trait_item_ref. id . node_id ) ;
822
- check. generics ( ) . predicates ( ) ;
823
- if trait_item_ref. kind != hir:: AssociatedItemKind :: Type ||
824
- trait_item_ref. defaultness . has_value ( ) {
825
- check. ty ( ) ;
826
- }
827
- }
828
- }
829
- hir:: ItemEnum ( ref def, _) => {
830
- self . check_item ( item. id ) . generics ( ) . predicates ( ) ;
831
- for variant in & def. variants {
832
- for field in variant. node . data . fields ( ) {
833
- self . check_item ( field. id ) . ty ( ) ;
834
- }
835
- }
836
- }
837
- hir:: ItemForeignMod ( ref foreign_mod) => {
838
- for foreign_item in & foreign_mod. items {
839
- self . check_item ( foreign_item. id ) . generics ( ) . predicates ( ) . ty ( ) ;
840
- }
841
- }
842
- hir:: ItemStruct ( ref struct_def, _) |
843
- hir:: ItemUnion ( ref struct_def, _) => {
844
- self . check_item ( item. id ) . generics ( ) . predicates ( ) ;
845
- for field in struct_def. fields ( ) {
846
- self . check_item ( field. id ) . ty ( ) ;
847
- }
848
- }
849
- hir:: ItemDefaultImpl ( ..) => {
850
- self . check_item ( item. id ) . impl_trait_ref ( ) ;
851
- }
852
- hir:: ItemImpl ( .., ref trait_ref, _, ref impl_item_refs) => {
853
- {
854
- let check = self . check_item ( item. id ) ;
855
- check. ty ( ) . generics ( ) . predicates ( ) ;
856
- if trait_ref. is_some ( ) {
857
- check. impl_trait_ref ( ) ;
858
- }
859
- }
860
- for impl_item_ref in impl_item_refs {
861
- let impl_item = self . tcx . hir . impl_item ( impl_item_ref. id ) ;
862
- self . check_item ( impl_item. id ) . generics ( ) . predicates ( ) . ty ( ) ;
863
- }
864
- }
865
- }
866
-
867
781
self . current_item = self . tcx . hir . local_def_id ( item. id ) ;
868
782
intravisit:: walk_item ( self , item) ;
869
783
self . tables = orig_tables;
@@ -924,8 +838,13 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
924
838
}
925
839
}
926
840
ty:: TyProjection ( ref proj) => {
927
- let tcx = self . tcx ;
928
- if self . check_trait_ref ( proj. trait_ref ( tcx) ) {
841
+ let trait_ref = proj. trait_ref ( self . tcx ) ;
842
+ if !self . item_is_accessible ( trait_ref. def_id ) {
843
+ let msg = format ! ( "trait `{}` is private" , trait_ref) ;
844
+ self . tcx . sess . span_err ( self . span , & msg) ;
845
+ return true ;
846
+ }
847
+ if trait_ref. super_visit_with ( self ) {
929
848
return true ;
930
849
}
931
850
}
0 commit comments