@@ -1186,6 +1186,7 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
1186
1186
if !is_local ( did) {
1187
1187
return false
1188
1188
}
1189
+
1189
1190
// .. and it corresponds to a private type in the AST (this returns
1190
1191
// None for type parameters)
1191
1192
match self . tcx . map . find ( did. node ) {
@@ -1206,12 +1207,15 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
1206
1207
if !self . tcx . sess . features . borrow ( ) . visible_private_types &&
1207
1208
self . path_is_private_type ( trait_ref. trait_ref . ref_id ) {
1208
1209
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") ;
1212
1212
}
1213
1213
}
1214
1214
}
1215
+
1216
+ fn item_is_public ( & self , id : & ast:: NodeId , vis : ast:: Visibility ) -> bool {
1217
+ self . exported_items . contains ( id) || vis == ast:: Public
1218
+ }
1215
1219
}
1216
1220
1217
1221
impl < ' 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> {
1259
1263
// error messages without (too many) false positives
1260
1264
// (i.e. we could just return here to not check them at
1261
1265
// all, or some worse estimation of whether an impl is
1262
- // publicly visible.
1266
+ // publicly visible) .
1263
1267
ast:: ItemImpl ( _, _, ref g, ref trait_ref, ref self_, ref impl_items) => {
1264
1268
// `impl [... for] Private` is never visible.
1265
1269
let self_contains_private;
@@ -1321,7 +1325,22 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
1321
1325
match * trait_ref {
1322
1326
None => {
1323
1327
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
+ }
1325
1344
}
1326
1345
}
1327
1346
Some ( ref tr) => {
@@ -1360,7 +1379,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
1360
1379
match impl_item. node {
1361
1380
ast:: MethodImplItem ( ref sig, _) => {
1362
1381
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 ) {
1364
1383
found_pub_static = true ;
1365
1384
visit:: walk_impl_item ( self , impl_item) ;
1366
1385
}
@@ -1381,15 +1400,18 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
1381
1400
ast:: ItemTy ( ..) => return ,
1382
1401
1383
1402
// 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
+ }
1385
1406
1386
1407
_ => { }
1387
1408
}
1388
1409
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
1390
1411
// any `visit_ty`'s will be called on things that are in
1391
1412
// public signatures, i.e. things that we're interested in for
1392
1413
// this visitor.
1414
+ debug ! ( "VisiblePrivateTypesVisitor entering item {:?}" , item) ;
1393
1415
visit:: walk_item ( self , item) ;
1394
1416
}
1395
1417
@@ -1420,20 +1442,12 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
1420
1442
}
1421
1443
}
1422
1444
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
-
1431
1445
fn visit_ty ( & mut self , t : & ast:: Ty ) {
1446
+ debug ! ( "VisiblePrivateTypesVisitor checking ty {:?}" , t) ;
1432
1447
if let ast:: TyPath ( _, ref p) = t. node {
1433
1448
if !self . tcx . sess . features . borrow ( ) . visible_private_types &&
1434
1449
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" ) ;
1437
1451
}
1438
1452
}
1439
1453
visit:: walk_ty ( self , t)
0 commit comments