@@ -45,6 +45,26 @@ use std::mem::replace;
4545
4646pub  mod  diagnostics; 
4747
48+ //////////////////////////////////////////////////////////////////////////////// 
49+ /// Visitor used to determine if pub(restricted) is used anywhere in the crate. 
50+ /// 
51+ /// This is done so that `private_in_public` warnings can be turned into hard errors 
52+ /// in crates that have been updated to use pub(restricted). 
53+ //////////////////////////////////////////////////////////////////////////////// 
54+ struct  PubRestrictedVisitor < ' a ,  ' tcx :  ' a >  { 
55+     tcx :   TyCtxt < ' a ,  ' tcx ,  ' tcx > , 
56+     has_pub_restricted :  bool , 
57+ } 
58+ 
59+ impl < ' a ,  ' tcx >  Visitor < ' tcx >  for  PubRestrictedVisitor < ' a ,  ' tcx >  { 
60+     fn  nested_visit_map < ' this > ( & ' this  mut  self )  -> NestedVisitorMap < ' this ,  ' tcx >  { 
61+         NestedVisitorMap :: All ( & self . tcx . hir ) 
62+     } 
63+     fn  visit_vis ( & mut  self ,  vis :  & ' tcx  hir:: Visibility )  { 
64+         self . has_pub_restricted  = self . has_pub_restricted  || vis. is_pub_restricted ( ) ; 
65+     } 
66+ } 
67+ 
4868//////////////////////////////////////////////////////////////////////////////// 
4969/// The embargo visitor, used to determine the exports of the ast 
5070//////////////////////////////////////////////////////////////////////////////// 
@@ -891,6 +911,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> {
891911     required_visibility :  ty:: Visibility , 
892912    /// The visibility of the least visible component that has been visited 
893913     min_visibility :  ty:: Visibility , 
914+     has_pub_restricted :  bool , 
894915    has_old_errors :  bool , 
895916} 
896917
@@ -951,7 +972,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
951972                    self . min_visibility  = vis; 
952973                } 
953974                if  !vis. is_at_least ( self . required_visibility ,  self . tcx )  { 
954-                     if  self . has_old_errors  { 
975+                     if  self . has_pub_restricted  ||  self . has_old_errors  { 
955976                        let  mut  err = struct_span_err ! ( self . tcx. sess,  self . span,  E0446 , 
956977                            "private type `{}` in public interface" ,  ty) ; 
957978                        err. span_label ( self . span ,  & format ! ( "can't leak private type" ) ) ; 
@@ -986,7 +1007,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
9861007                self . min_visibility  = vis; 
9871008            } 
9881009            if  !vis. is_at_least ( self . required_visibility ,  self . tcx )  { 
989-                 if  self . has_old_errors  { 
1010+                 if  self . has_pub_restricted  ||  self . has_old_errors  { 
9901011                    struct_span_err ! ( self . tcx. sess,  self . span,  E0445 , 
9911012                                     "private trait `{}` in public interface" ,  trait_ref) 
9921013                        . span_label ( self . span ,  & format ! ( 
@@ -1008,6 +1029,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
10081029
10091030struct  PrivateItemsInPublicInterfacesVisitor < ' a ,  ' tcx :  ' a >  { 
10101031    tcx :  TyCtxt < ' a ,  ' tcx ,  ' tcx > , 
1032+     has_pub_restricted :  bool , 
10111033    old_error_set :  & ' a  NodeSet , 
10121034    inner_visibility :  ty:: Visibility , 
10131035} 
@@ -1044,6 +1066,7 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
10441066            span :  self . tcx . hir . span ( item_id) , 
10451067            min_visibility :  ty:: Visibility :: Public , 
10461068            required_visibility :  required_visibility, 
1069+             has_pub_restricted :  self . has_pub_restricted , 
10471070            has_old_errors :  has_old_errors, 
10481071        } 
10491072    } 
@@ -1227,9 +1250,20 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
12271250        } ; 
12281251        intravisit:: walk_crate ( & mut  visitor,  krate) ; 
12291252
1253+ 
1254+         let  has_pub_restricted = { 
1255+             let  mut  pub_restricted_visitor = PubRestrictedVisitor  { 
1256+                 tcx :  tcx, 
1257+                 has_pub_restricted :  false 
1258+             } ; 
1259+             intravisit:: walk_crate ( & mut  pub_restricted_visitor,  krate) ; 
1260+             pub_restricted_visitor. has_pub_restricted 
1261+         } ; 
1262+ 
12301263        // Check for private types and traits in public interfaces 
12311264        let  mut  visitor = PrivateItemsInPublicInterfacesVisitor  { 
12321265            tcx :  tcx, 
1266+             has_pub_restricted :  has_pub_restricted, 
12331267            old_error_set :  & visitor. old_error_set , 
12341268            inner_visibility :  ty:: Visibility :: Public , 
12351269        } ; 
0 commit comments