@@ -1479,8 +1479,93 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
1479
1479
Item :: from_def_id_and_parts ( assoc_item. def_id , Some ( assoc_item. name ) , kind, cx)
1480
1480
}
1481
1481
1482
+ /// The goal of this function is to return the first `Path` which is not private (ie not private
1483
+ /// or `doc(hidden)`). If it's not possible, it'll return the "end type".
1484
+ ///
1485
+ /// If the path is not a re-export or is public, it'll return `None`.
1486
+ fn first_not_private (
1487
+ cx : & mut DocContext < ' _ > ,
1488
+ hir_id : hir:: HirId ,
1489
+ path : & hir:: Path < ' _ > ,
1490
+ ) -> Option < Path > {
1491
+ if path. segments . is_empty ( ) {
1492
+ return None ;
1493
+ }
1494
+ let parent_def_id = if path. segments . len ( ) == 1 {
1495
+ // Then it's available in the same scope as the owner.
1496
+ hir_id. owner . def_id
1497
+ } else {
1498
+ // It's not available in the same scope, so we start from the parent of the item.
1499
+ path. segments [ path. segments . len ( ) - 2 ] . res . opt_def_id ( ) ?. as_local ( ) ?
1500
+ } ;
1501
+ let target_def_id = path. res . opt_def_id ( ) ?;
1502
+ let mut ident = path. segments . last ( ) . unwrap ( ) . ident ;
1503
+ // First we try to get the `DefId` of the item.
1504
+ for child in cx
1505
+ . tcx
1506
+ . module_children_local ( cx. tcx . local_parent ( parent_def_id) )
1507
+ . iter ( )
1508
+ . filter ( move |c| c. ident == ident)
1509
+ {
1510
+ if let Res :: Def ( DefKind :: Ctor ( ..) , _) | Res :: SelfCtor ( ..) = child. res {
1511
+ continue ;
1512
+ }
1513
+
1514
+ if let Some ( def_id) = child. res . opt_def_id ( ) && target_def_id == def_id {
1515
+ let mut last_path_res = None ;
1516
+ ' reexps: for reexp in child. reexport_chain . iter ( ) {
1517
+ if let Some ( use_def_id) = reexp. id ( ) &&
1518
+ let Some ( local_use_def_id) = use_def_id. as_local ( )
1519
+ {
1520
+ let hir = cx. tcx . hir ( ) ;
1521
+ // let parent_mod = hir.local_def_id_to_hir_id();
1522
+ for item_id in hir. module_items ( cx. tcx . local_parent ( local_use_def_id) ) {
1523
+ let item = hir. item ( item_id) ;
1524
+ if item. ident == ident {
1525
+ match item. kind {
1526
+ hir:: ItemKind :: Use ( path, _) => {
1527
+ for res in & path. res {
1528
+ if let Res :: Def ( DefKind :: Ctor ( ..) , _) | Res :: SelfCtor ( ..) = res {
1529
+ continue ;
1530
+ }
1531
+ if !cx. tcx . is_doc_hidden ( use_def_id) &&
1532
+ cx. tcx . local_visibility ( local_use_def_id) . is_public ( ) {
1533
+ break ' reexps;
1534
+ }
1535
+ ident = path. segments . last ( ) . unwrap ( ) . ident ;
1536
+ last_path_res = Some ( ( path, res) ) ;
1537
+ continue ' reexps;
1538
+ }
1539
+ }
1540
+ _ => { }
1541
+ }
1542
+ }
1543
+ }
1544
+ }
1545
+ }
1546
+ if !child. reexport_chain . is_empty ( ) {
1547
+ // So in here, we use the data we gathered from iterating the reexports. If
1548
+ // `last_path_res` is set, it can mean two things:
1549
+ //
1550
+ // 1. We found a public reexport.
1551
+ // 2. We didn't find a public reexport so it's the "end type" path.
1552
+ if let Some ( ( path, res) ) = last_path_res {
1553
+ let path = hir:: Path { segments : path. segments , res : * res, span : path. span } ;
1554
+ return Some ( clean_path ( & path, cx) ) ;
1555
+ }
1556
+ // If `last_path_res` is `None`, it can mean two things:
1557
+ //
1558
+ // 1. The re-export is public, no need to change anything, just use the path as is.
1559
+ // 2. Nothing was found, so let's just return the original path.
1560
+ return None ;
1561
+ }
1562
+ }
1563
+ }
1564
+ None
1565
+ }
1566
+
1482
1567
fn clean_qpath < ' tcx > ( hir_ty : & hir:: Ty < ' tcx > , cx : & mut DocContext < ' tcx > ) -> Type {
1483
- let hir:: Ty { hir_id : _ , span, ref kind } = * hir_ty;
1568
+ let hir:: Ty { hir_id, span, ref kind } = * hir_ty;
1484
1569
let hir:: TyKind :: Path ( qpath) = kind else { unreachable ! ( ) } ;
1485
1570
1486
1571
match qpath {
@@ -1497,7 +1582,12 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
1497
1582
if let Some ( expanded) = maybe_expand_private_type_alias ( cx, path) {
1498
1583
expanded
1499
1584
} else {
1500
- let path = clean_path ( path, cx) ;
1585
+ // First we check if it's a private re-export.
1586
+ let path = if let Some ( path) = first_not_private ( cx, hir_id, & path) {
1587
+ path
1588
+ } else {
1589
+ clean_path ( path, cx)
1590
+ } ;
1501
1591
resolve_type ( cx, path)
1502
1592
}
1503
1593
}
@@ -1649,7 +1739,7 @@ fn maybe_expand_private_type_alias<'tcx>(
1649
1739
}
1650
1740
}
1651
1741
1652
- Some ( cx. enter_alias ( substs, def_id. to_def_id ( ) , |cx| clean_ty ( ty, cx) ) )
1742
+ Some ( cx. enter_alias ( substs, def_id. to_def_id ( ) , |cx| clean_ty ( & ty, cx) ) )
1653
1743
}
1654
1744
1655
1745
pub ( crate ) fn clean_ty < ' tcx > ( ty : & hir:: Ty < ' tcx > , cx : & mut DocContext < ' tcx > ) -> Type {
0 commit comments