@@ -45,6 +45,26 @@ use std::mem::replace;
45
45
46
46
pub mod diagnostics;
47
47
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
+
48
68
////////////////////////////////////////////////////////////////////////////////
49
69
/// The embargo visitor, used to determine the exports of the ast
50
70
////////////////////////////////////////////////////////////////////////////////
@@ -891,6 +911,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> {
891
911
required_visibility : ty:: Visibility ,
892
912
/// The visibility of the least visible component that has been visited
893
913
min_visibility : ty:: Visibility ,
914
+ has_pub_restricted : bool ,
894
915
has_old_errors : bool ,
895
916
}
896
917
@@ -951,7 +972,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
951
972
self . min_visibility = vis;
952
973
}
953
974
if !vis. is_at_least ( self . required_visibility , self . tcx ) {
954
- if self . tcx . sess . features . borrow ( ) . pub_restricted || self . has_old_errors {
975
+ if self . has_pub_restricted || self . has_old_errors {
955
976
let mut err = struct_span_err ! ( self . tcx. sess, self . span, E0446 ,
956
977
"private type `{}` in public interface" , ty) ;
957
978
err. span_label ( self . span , & format ! ( "can't leak private type" ) ) ;
@@ -986,7 +1007,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
986
1007
self . min_visibility = vis;
987
1008
}
988
1009
if !vis. is_at_least ( self . required_visibility , self . tcx ) {
989
- if self . tcx . sess . features . borrow ( ) . pub_restricted || self . has_old_errors {
1010
+ if self . has_pub_restricted || self . has_old_errors {
990
1011
struct_span_err ! ( self . tcx. sess, self . span, E0445 ,
991
1012
"private trait `{}` in public interface" , trait_ref)
992
1013
. span_label ( self . span , & format ! (
@@ -1008,6 +1029,7 @@ impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'
1008
1029
1009
1030
struct PrivateItemsInPublicInterfacesVisitor < ' a , ' tcx : ' a > {
1010
1031
tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
1032
+ has_pub_restricted : bool ,
1011
1033
old_error_set : & ' a NodeSet ,
1012
1034
inner_visibility : ty:: Visibility ,
1013
1035
}
@@ -1044,6 +1066,7 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
1044
1066
span : self . tcx . hir . span ( item_id) ,
1045
1067
min_visibility : ty:: Visibility :: Public ,
1046
1068
required_visibility : required_visibility,
1069
+ has_pub_restricted : self . has_pub_restricted ,
1047
1070
has_old_errors : has_old_errors,
1048
1071
}
1049
1072
}
@@ -1227,9 +1250,20 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1227
1250
} ;
1228
1251
intravisit:: walk_crate ( & mut visitor, krate) ;
1229
1252
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
+
1230
1263
// Check for private types and traits in public interfaces
1231
1264
let mut visitor = PrivateItemsInPublicInterfacesVisitor {
1232
1265
tcx : tcx,
1266
+ has_pub_restricted : has_pub_restricted,
1233
1267
old_error_set : & visitor. old_error_set ,
1234
1268
inner_visibility : ty:: Visibility :: Public ,
1235
1269
} ;
0 commit comments