@@ -1460,13 +1460,38 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> {
1460
1460
old_error_set : & ' a NodeSet ,
1461
1461
}
1462
1462
1463
+ impl < ' a , ' tcx : ' a > SearchInterfaceForPrivateItemsVisitor < ' a , ' tcx > {
1464
+ // Check if the type alias contain private types when substituted
1465
+ fn is_public_type_alias ( & self , item : & hir:: Item , path : & hir:: Path ) -> bool {
1466
+ // Type alias is considered public if the aliased type is
1467
+ // public, even if the type alias itself is private. So, something
1468
+ // like `type A = u8; pub fn f() -> A {...}` doesn't cause an error.
1469
+ if let hir:: ItemTy ( ref ty, ref generics) = item. node {
1470
+ let mut check = SearchInterfaceForPrivateItemsVisitor {
1471
+ tcx : self . tcx , is_quiet : self . is_quiet ,
1472
+ is_public : true , old_error_set : self . old_error_set ,
1473
+ } ;
1474
+ check. visit_ty ( ty) ;
1475
+ let provided_params = path. segments . last ( ) . unwrap ( ) . parameters . types ( ) . len ( ) ;
1476
+ for ty_param in & generics. ty_params [ provided_params..] {
1477
+ if let Some ( ref default_ty) = ty_param. default {
1478
+ check. visit_ty ( default_ty) ;
1479
+ }
1480
+ }
1481
+ check. is_public
1482
+ } else {
1483
+ false
1484
+ }
1485
+ }
1486
+ }
1487
+
1463
1488
impl < ' a , ' tcx : ' a , ' v > Visitor < ' v > for SearchInterfaceForPrivateItemsVisitor < ' a , ' tcx > {
1464
1489
fn visit_ty ( & mut self , ty : & hir:: Ty ) {
1465
1490
if self . is_quiet && !self . is_public {
1466
1491
// We are in quiet mode and a private type is already found, no need to proceed
1467
1492
return
1468
1493
}
1469
- if let hir:: TyPath ( .. ) = ty. node {
1494
+ if let hir:: TyPath ( _ , ref path ) = ty. node {
1470
1495
let def = self . tcx . def_map . borrow ( ) . get ( & ty. id ) . unwrap ( ) . full_def ( ) ;
1471
1496
match def {
1472
1497
def:: DefPrimTy ( ..) | def:: DefSelfTy ( ..) | def:: DefTyParam ( ..) => {
@@ -1482,12 +1507,7 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a,
1482
1507
// Non-local means public, local needs to be checked
1483
1508
if let Some ( node_id) = self . tcx . map . as_local_node_id ( def_id) {
1484
1509
if let Some ( ast_map:: NodeItem ( ref item) ) = self . tcx . map . find ( node_id) {
1485
- if let ( & hir:: ItemTy ( ..) , true ) = ( & item. node , self . is_quiet ) {
1486
- // Conservatively approximate the whole type alias as public without
1487
- // recursing into its components when determining impl publicity.
1488
- return
1489
- }
1490
- if item. vis != hir:: Public {
1510
+ if item. vis != hir:: Public && !self . is_public_type_alias ( item, path) {
1491
1511
if !self . is_quiet {
1492
1512
if self . old_error_set . contains ( & ty. id ) {
1493
1513
span_err ! ( self . tcx. sess, ty. span, E0446 ,
0 commit comments