1717
1818#[ macro_use] extern crate rustc;
1919#[ macro_use] extern crate syntax;
20+ extern crate rustc_typeck;
2021extern crate syntax_pos;
2122
2223use rustc:: hir:: { self , PatKind } ;
@@ -658,65 +659,6 @@ impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
658659 }
659660 false
660661 }
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- }
720662}
721663
722664impl < ' a , ' tcx > Visitor < ' tcx > for TypePrivacyVisitor < ' a , ' tcx > {
@@ -733,6 +675,35 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
733675 self . tables = orig_tables;
734676 }
735677
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+
736707 // Check types of expressions
737708 fn visit_expr ( & mut self , expr : & ' tcx hir:: Expr ) {
738709 if self . check_expr_pat_type ( expr. hir_id , expr. span ) {
@@ -807,63 +778,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
807778 item. id ,
808779 & mut self . tables ,
809780 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-
867781 self . current_item = self . tcx . hir . local_def_id ( item. id ) ;
868782 intravisit:: walk_item ( self , item) ;
869783 self . tables = orig_tables;
@@ -924,8 +838,13 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
924838 }
925839 }
926840 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 ) {
929848 return true ;
930849 }
931850 }
0 commit comments