@@ -589,12 +589,23 @@ impl<'a, 'tcx> TypePrivacyVisitor<'a, 'tcx> {
589589 }
590590
591591 fn check_expr_pat_type ( & mut self , id : ast:: NodeId , span : Span ) -> bool {
592+ self . span = span;
592593 if let Some ( ty) = self . tables . node_id_to_type_opt ( id) {
593- self . span = span;
594- ty. visit_with ( self )
595- } else {
596- false
594+ if ty. visit_with ( self ) {
595+ return true ;
596+ }
597+ }
598+ if self . tables . node_substs ( id) . visit_with ( self ) {
599+ return true ;
597600 }
601+ if let Some ( adjustments) = self . tables . adjustments . get ( & id) {
602+ for adjustment in adjustments {
603+ if adjustment. target . visit_with ( self ) {
604+ return true ;
605+ }
606+ }
607+ }
608+ false
598609 }
599610
600611 fn check_item ( & mut self , item_id : ast:: NodeId ) -> & mut Self {
@@ -658,11 +669,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
658669 }
659670 hir:: ExprMethodCall ( name, ..) => {
660671 // Method calls have to be checked specially.
661- if let Some ( method) = self . tables . method_map . get ( & ty:: MethodCall :: expr ( expr. id ) ) {
662- self . span = name. span ;
663- if method. ty . visit_with ( self ) || method. substs . visit_with ( self ) {
664- return ;
665- }
672+ let def_id = self . tables . type_dependent_defs [ & expr. id ] . def_id ( ) ;
673+ self . span = name. span ;
674+ if self . tcx . type_of ( def_id) . visit_with ( self ) {
675+ return ;
666676 }
667677 }
668678 _ => { }
@@ -671,6 +681,24 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
671681 intravisit:: walk_expr ( self , expr) ;
672682 }
673683
684+ fn visit_qpath ( & mut self , qpath : & ' tcx hir:: QPath , id : ast:: NodeId , span : Span ) {
685+ // Inherent associated constants don't have self type in substs,
686+ // we have to check it additionally.
687+ if let hir:: QPath :: TypeRelative ( ..) = * qpath {
688+ if let Some ( def) = self . tables . type_dependent_defs . get ( & id) . cloned ( ) {
689+ if let Some ( assoc_item) = self . tcx . opt_associated_item ( def. def_id ( ) ) {
690+ if let ty:: ImplContainer ( impl_def_id) = assoc_item. container {
691+ if self . tcx . type_of ( impl_def_id) . visit_with ( self ) {
692+ return ;
693+ }
694+ }
695+ }
696+ }
697+ }
698+
699+ intravisit:: walk_qpath ( self , qpath, id, span) ;
700+ }
701+
674702 // Check types of patterns
675703 fn visit_pat ( & mut self , pattern : & ' tcx hir:: Pat ) {
676704 if self . check_expr_pat_type ( pattern. id , pattern. span ) {
@@ -767,25 +795,11 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
767795 self . tcx . sess . span_err ( self . span , & msg) ;
768796 return true ;
769797 }
770- if let ty:: TyFnDef ( ..) = ty. sty {
771- // Inherent static methods don't have self type in substs,
772- // we have to check it additionally.
773- let mut impl_def_id = None ;
774- if let Some ( node_id) = self . tcx . hir . as_local_node_id ( def_id) {
775- if let hir:: map:: NodeImplItem ( ..) = self . tcx . hir . get ( node_id) {
776- impl_def_id = Some ( self . tcx . hir . get_parent_did ( node_id) ) ;
777- }
778- } else if let Some ( Def :: Method ( ..) ) = self . tcx . describe_def ( def_id) {
779- let candidate_impl_def_id = self . tcx . parent_def_id ( def_id)
780- . expect ( "no parent for method def_id" ) ;
781- // `is_none` means it's an impl, not a trait
782- if self . tcx . describe_def ( candidate_impl_def_id) . is_none ( ) {
783- impl_def_id = Some ( candidate_impl_def_id)
784- }
785- }
786- if let Some ( impl_def_id) = impl_def_id {
787- let self_ty = self . tcx . type_of ( impl_def_id) ;
788- if self_ty. visit_with ( self ) {
798+ // Inherent static methods don't have self type in substs,
799+ // we have to check it additionally.
800+ if let Some ( assoc_item) = self . tcx . opt_associated_item ( def_id) {
801+ if let ty:: ImplContainer ( impl_def_id) = assoc_item. container {
802+ if self . tcx . type_of ( impl_def_id) . visit_with ( self ) {
789803 return true ;
790804 }
791805 }
@@ -827,7 +841,7 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
827841 self . tcx . sess . span_err ( self . span , & msg) ;
828842 return true ;
829843 }
830- // Skip `Self` to avoid infinite recursion
844+ // `Self` here is the same `TyAnon`, so skip it to avoid infinite recursion
831845 for subst in trait_ref. substs . iter ( ) . skip ( 1 ) {
832846 if subst. visit_with ( self ) {
833847 return true ;
0 commit comments