@@ -1496,8 +1496,93 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
1496
1496
Item :: from_def_id_and_parts ( assoc_item. def_id , Some ( assoc_item. name ) , kind, cx)
1497
1497
}
1498
1498
1499
+ /// The goal of this function is to return the first `Path` which is not private (ie not private
1500
+ /// or `doc(hidden)`). If it's not possible, it'll return the "end type".
1501
+ ///
1502
+ /// If the path is not a re-export or is public, it'll return `None`.
1503
+ fn first_not_private (
1504
+ cx : & mut DocContext < ' _ > ,
1505
+ hir_id : hir:: HirId ,
1506
+ path : & hir:: Path < ' _ > ,
1507
+ ) -> Option < Path > {
1508
+ if path. segments . is_empty ( ) {
1509
+ return None ;
1510
+ }
1511
+ let parent_def_id = if path. segments . len ( ) == 1 {
1512
+ // Then it's available in the same scope as the owner.
1513
+ hir_id. owner . def_id
1514
+ } else {
1515
+ // It's not available in the same scope, so we start from the parent of the item.
1516
+ path. segments [ path. segments . len ( ) - 2 ] . res . opt_def_id ( ) ?. as_local ( ) ?
1517
+ } ;
1518
+ let target_def_id = path. res . opt_def_id ( ) ?;
1519
+ let mut ident = path. segments . last ( ) . unwrap ( ) . ident ;
1520
+ // First we try to get the `DefId` of the item.
1521
+ for child in cx
1522
+ . tcx
1523
+ . module_children_local ( cx. tcx . local_parent ( parent_def_id) )
1524
+ . iter ( )
1525
+ . filter ( move |c| c. ident == ident)
1526
+ {
1527
+ if let Res :: Def ( DefKind :: Ctor ( ..) , _) | Res :: SelfCtor ( ..) = child. res {
1528
+ continue ;
1529
+ }
1530
+
1531
+ if let Some ( def_id) = child. res . opt_def_id ( ) && target_def_id == def_id {
1532
+ let mut last_path_res = None ;
1533
+ ' reexps: for reexp in child. reexport_chain . iter ( ) {
1534
+ if let Some ( use_def_id) = reexp. id ( ) &&
1535
+ let Some ( local_use_def_id) = use_def_id. as_local ( )
1536
+ {
1537
+ let hir = cx. tcx . hir ( ) ;
1538
+ // let parent_mod = hir.local_def_id_to_hir_id();
1539
+ for item_id in hir. module_items ( cx. tcx . local_parent ( local_use_def_id) ) {
1540
+ let item = hir. item ( item_id) ;
1541
+ if item. ident == ident {
1542
+ match item. kind {
1543
+ hir:: ItemKind :: Use ( path, _) => {
1544
+ for res in & path. res {
1545
+ if let Res :: Def ( DefKind :: Ctor ( ..) , _) | Res :: SelfCtor ( ..) = res {
1546
+ continue ;
1547
+ }
1548
+ if !cx. tcx . is_doc_hidden ( use_def_id) &&
1549
+ cx. tcx . local_visibility ( local_use_def_id) . is_public ( ) {
1550
+ break ' reexps;
1551
+ }
1552
+ ident = path. segments . last ( ) . unwrap ( ) . ident ;
1553
+ last_path_res = Some ( ( path, res) ) ;
1554
+ continue ' reexps;
1555
+ }
1556
+ }
1557
+ _ => { }
1558
+ }
1559
+ }
1560
+ }
1561
+ }
1562
+ }
1563
+ if !child. reexport_chain . is_empty ( ) {
1564
+ // So in here, we use the data we gathered from iterating the reexports. If
1565
+ // `last_path_res` is set, it can mean two things:
1566
+ //
1567
+ // 1. We found a public reexport.
1568
+ // 2. We didn't find a public reexport so it's the "end type" path.
1569
+ if let Some ( ( path, res) ) = last_path_res {
1570
+ let path = hir:: Path { segments : path. segments , res : * res, span : path. span } ;
1571
+ return Some ( clean_path ( & path, cx) ) ;
1572
+ }
1573
+ // If `last_path_res` is `None`, it can mean two things:
1574
+ //
1575
+ // 1. The re-export is public, no need to change anything, just use the path as is.
1576
+ // 2. Nothing was found, so let's just return the original path.
1577
+ return None ;
1578
+ }
1579
+ }
1580
+ }
1581
+ None
1582
+ }
1583
+
1499
1584
fn clean_qpath < ' tcx > ( hir_ty : & hir:: Ty < ' tcx > , cx : & mut DocContext < ' tcx > ) -> Type {
1500
- let hir:: Ty { hir_id : _ , span, ref kind } = * hir_ty;
1585
+ let hir:: Ty { hir_id, span, ref kind } = * hir_ty;
1501
1586
let hir:: TyKind :: Path ( qpath) = kind else { unreachable ! ( ) } ;
1502
1587
1503
1588
match qpath {
@@ -1514,7 +1599,12 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
1514
1599
if let Some ( expanded) = maybe_expand_private_type_alias ( cx, path) {
1515
1600
expanded
1516
1601
} else {
1517
- let path = clean_path ( path, cx) ;
1602
+ // First we check if it's a private re-export.
1603
+ let path = if let Some ( path) = first_not_private ( cx, hir_id, & path) {
1604
+ path
1605
+ } else {
1606
+ clean_path ( path, cx)
1607
+ } ;
1518
1608
resolve_type ( cx, path)
1519
1609
}
1520
1610
}
@@ -1665,7 +1755,7 @@ fn maybe_expand_private_type_alias<'tcx>(
1665
1755
}
1666
1756
}
1667
1757
1668
- Some ( cx. enter_alias ( args, def_id. to_def_id ( ) , |cx| clean_ty ( ty, cx) ) )
1758
+ Some ( cx. enter_alias ( args, def_id. to_def_id ( ) , |cx| clean_ty ( & ty, cx) ) )
1669
1759
}
1670
1760
1671
1761
pub ( crate ) fn clean_ty < ' tcx > ( ty : & hir:: Ty < ' tcx > , cx : & mut DocContext < ' tcx > ) -> Type {
0 commit comments