@@ -1186,6 +1186,7 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
11861186 if !is_local ( did) {
11871187 return false
11881188 }
1189+
11891190 // .. and it corresponds to a private type in the AST (this returns
11901191 // None for type parameters)
11911192 match self . tcx . map . find ( did. node ) {
@@ -1206,12 +1207,15 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
12061207 if !self . tcx . sess . features . borrow ( ) . visible_private_types &&
12071208 self . path_is_private_type ( trait_ref. trait_ref . ref_id ) {
12081209 let span = trait_ref. trait_ref . path . span ;
1209- self . tcx . sess . span_err ( span,
1210- "private trait in exported type \
1211- parameter bound") ;
1210+ self . tcx . sess . span_err ( span, "private trait in exported type \
1211+ parameter bound") ;
12121212 }
12131213 }
12141214 }
1215+
1216+ fn item_is_public ( & self , id : & ast:: NodeId , vis : ast:: Visibility ) -> bool {
1217+ self . exported_items . contains ( id) || vis == ast:: Public
1218+ }
12151219}
12161220
12171221impl < ' a , ' b , ' tcx , ' v > Visitor < ' v > for CheckTypeForPrivatenessVisitor < ' a , ' b , ' tcx > {
@@ -1259,7 +1263,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
12591263 // error messages without (too many) false positives
12601264 // (i.e. we could just return here to not check them at
12611265 // all, or some worse estimation of whether an impl is
1262- // publicly visible.
1266+ // publicly visible) .
12631267 ast:: ItemImpl ( _, _, ref g, ref trait_ref, ref self_, ref impl_items) => {
12641268 // `impl [... for] Private` is never visible.
12651269 let self_contains_private;
@@ -1321,7 +1325,22 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
13211325 match * trait_ref {
13221326 None => {
13231327 for impl_item in impl_items {
1324- visit:: walk_impl_item ( self , impl_item) ;
1328+ // This is where we choose whether to walk down
1329+ // further into the impl to check its items. We
1330+ // should only walk into public items so that we
1331+ // don't erroneously report errors for private
1332+ // types in private items.
1333+ match impl_item. node {
1334+ ast:: MethodImplItem ( ..)
1335+ if self . item_is_public ( & impl_item. id , impl_item. vis ) =>
1336+ {
1337+ visit:: walk_impl_item ( self , impl_item)
1338+ }
1339+ ast:: TypeImplItem ( ..) => {
1340+ visit:: walk_impl_item ( self , impl_item)
1341+ }
1342+ _ => { }
1343+ }
13251344 }
13261345 }
13271346 Some ( ref tr) => {
@@ -1360,7 +1379,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
13601379 match impl_item. node {
13611380 ast:: MethodImplItem ( ref sig, _) => {
13621381 if sig. explicit_self . node == ast:: SelfStatic &&
1363- self . exported_items . contains ( & impl_item. id ) {
1382+ self . item_is_public ( & impl_item. id , impl_item . vis ) {
13641383 found_pub_static = true ;
13651384 visit:: walk_impl_item ( self , impl_item) ;
13661385 }
@@ -1381,15 +1400,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
13811400 ast:: ItemTy ( ..) => return ,
13821401
13831402 // not at all public, so we don't care
1384- _ if !self . exported_items . contains ( & item. id ) => return ,
1403+ _ if !self . item_is_public ( & item. id , item. vis ) => {
1404+ return ;
1405+ }
13851406
13861407 _ => { }
13871408 }
13881409
1389- // we 've carefully constructed it so that if we're here, then
1410+ // We 've carefully constructed it so that if we're here, then
13901411 // any `visit_ty`'s will be called on things that are in
13911412 // public signatures, i.e. things that we're interested in for
13921413 // this visitor.
1414+ debug ! ( "VisiblePrivateTypesVisitor entering item {:?}" , item) ;
13931415 visit:: walk_item ( self , item) ;
13941416 }
13951417
@@ -1420,20 +1442,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
14201442 }
14211443 }
14221444
1423- fn visit_fn ( & mut self , fk : visit:: FnKind < ' v > , fd : & ' v ast:: FnDecl ,
1424- b : & ' v ast:: Block , s : Span , id : ast:: NodeId ) {
1425- // needs special handling for methods.
1426- if self . exported_items . contains ( & id) {
1427- visit:: walk_fn ( self , fk, fd, b, s) ;
1428- }
1429- }
1430-
14311445 fn visit_ty ( & mut self , t : & ast:: Ty ) {
1446+ debug ! ( "VisiblePrivateTypesVisitor checking ty {:?}" , t) ;
14321447 if let ast:: TyPath ( _, ref p) = t. node {
14331448 if !self . tcx . sess . features . borrow ( ) . visible_private_types &&
14341449 self . path_is_private_type ( t. id ) {
1435- self . tcx . sess . span_err ( p. span ,
1436- "private type in exported type signature" ) ;
1450+ self . tcx . sess . span_err ( p. span , "private type in exported type signature" ) ;
14371451 }
14381452 }
14391453 visit:: walk_ty ( self , t)
0 commit comments