@@ -1529,7 +1529,9 @@ fn maybe_expand_private_type_alias<'tcx>(
1529
1529
let Res :: Def ( DefKind :: TyAlias , def_id) = path. res else { return None } ;
1530
1530
// Substitute private type aliases
1531
1531
let def_id = def_id. as_local ( ) ?;
1532
- let alias = if !cx. cache . effective_visibilities . is_exported ( cx. tcx , def_id. to_def_id ( ) ) {
1532
+ let alias = if !cx. cache . effective_visibilities . is_exported ( cx. tcx , def_id. to_def_id ( ) )
1533
+ && !cx. current_type_aliases . contains_key ( & def_id. to_def_id ( ) )
1534
+ {
1533
1535
& cx. tcx . hir ( ) . expect_item ( def_id) . kind
1534
1536
} else {
1535
1537
return None ;
@@ -1609,7 +1611,7 @@ fn maybe_expand_private_type_alias<'tcx>(
1609
1611
}
1610
1612
}
1611
1613
1612
- Some ( cx. enter_alias ( substs, |cx| clean_ty ( ty, cx) ) )
1614
+ Some ( cx. enter_alias ( substs, def_id . to_def_id ( ) , |cx| clean_ty ( ty, cx) ) )
1613
1615
}
1614
1616
1615
1617
pub ( crate ) fn clean_ty < ' tcx > ( ty : & hir:: Ty < ' tcx > , cx : & mut DocContext < ' tcx > ) -> Type {
@@ -1700,7 +1702,7 @@ fn normalize<'tcx>(
1700
1702
pub ( crate ) fn clean_middle_ty < ' tcx > (
1701
1703
bound_ty : ty:: Binder < ' tcx , Ty < ' tcx > > ,
1702
1704
cx : & mut DocContext < ' tcx > ,
1703
- def_id : Option < DefId > ,
1705
+ parent_def_id : Option < DefId > ,
1704
1706
) -> Type {
1705
1707
let bound_ty = normalize ( cx, bound_ty) . unwrap_or ( bound_ty) ;
1706
1708
match * bound_ty. skip_binder ( ) . kind ( ) {
@@ -1830,7 +1832,9 @@ pub(crate) fn clean_middle_ty<'tcx>(
1830
1832
Tuple ( t. iter ( ) . map ( |t| clean_middle_ty ( bound_ty. rebind ( t) , cx, None ) ) . collect ( ) )
1831
1833
}
1832
1834
1833
- ty:: Alias ( ty:: Projection , ref data) => clean_projection ( bound_ty. rebind ( * data) , cx, def_id) ,
1835
+ ty:: Alias ( ty:: Projection , ref data) => {
1836
+ clean_projection ( bound_ty. rebind ( * data) , cx, parent_def_id)
1837
+ }
1834
1838
1835
1839
ty:: Param ( ref p) => {
1836
1840
if let Some ( bounds) = cx. impl_trait_bounds . remove ( & p. index . into ( ) ) {
@@ -1841,15 +1845,30 @@ pub(crate) fn clean_middle_ty<'tcx>(
1841
1845
}
1842
1846
1843
1847
ty:: Alias ( ty:: Opaque , ty:: AliasTy { def_id, substs, .. } ) => {
1844
- // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
1845
- // by looking up the bounds associated with the def_id.
1846
- let bounds = cx
1847
- . tcx
1848
- . explicit_item_bounds ( def_id)
1849
- . subst_iter_copied ( cx. tcx , substs)
1850
- . map ( |( bound, _) | bound)
1851
- . collect :: < Vec < _ > > ( ) ;
1852
- clean_middle_opaque_bounds ( cx, bounds)
1848
+ // If it's already in the same alias, don't get an infinite loop.
1849
+ if cx. current_type_aliases . contains_key ( & def_id) {
1850
+ let path =
1851
+ external_path ( cx, def_id, false , ThinVec :: new ( ) , bound_ty. rebind ( substs) ) ;
1852
+ Type :: Path { path }
1853
+ } else {
1854
+ * cx. current_type_aliases . entry ( def_id) . or_insert ( 0 ) += 1 ;
1855
+ // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
1856
+ // by looking up the bounds associated with the def_id.
1857
+ let bounds = cx
1858
+ . tcx
1859
+ . explicit_item_bounds ( def_id)
1860
+ . subst_iter_copied ( cx. tcx , substs)
1861
+ . map ( |( bound, _) | bound)
1862
+ . collect :: < Vec < _ > > ( ) ;
1863
+ let ty = clean_middle_opaque_bounds ( cx, bounds) ;
1864
+ if let Some ( count) = cx. current_type_aliases . get_mut ( & def_id) {
1865
+ * count -= 1 ;
1866
+ if * count == 0 {
1867
+ cx. current_type_aliases . remove ( & def_id) ;
1868
+ }
1869
+ }
1870
+ ty
1871
+ }
1853
1872
}
1854
1873
1855
1874
ty:: Closure ( ..) => panic ! ( "Closure" ) ,
@@ -2229,13 +2248,17 @@ fn clean_maybe_renamed_item<'tcx>(
2229
2248
generics : clean_generics ( ty. generics , cx) ,
2230
2249
} ) ,
2231
2250
ItemKind :: TyAlias ( hir_ty, generics) => {
2251
+ * cx. current_type_aliases . entry ( def_id) . or_insert ( 0 ) += 1 ;
2232
2252
let rustdoc_ty = clean_ty ( hir_ty, cx) ;
2233
2253
let ty = clean_middle_ty ( ty:: Binder :: dummy ( hir_ty_to_ty ( cx. tcx , hir_ty) ) , cx, None ) ;
2234
- TypedefItem ( Box :: new ( Typedef {
2235
- type_ : rustdoc_ty,
2236
- generics : clean_generics ( generics, cx) ,
2237
- item_type : Some ( ty) ,
2238
- } ) )
2254
+ let generics = clean_generics ( generics, cx) ;
2255
+ if let Some ( count) = cx. current_type_aliases . get_mut ( & def_id) {
2256
+ * count -= 1 ;
2257
+ if * count == 0 {
2258
+ cx. current_type_aliases . remove ( & def_id) ;
2259
+ }
2260
+ }
2261
+ TypedefItem ( Box :: new ( Typedef { type_ : rustdoc_ty, generics, item_type : Some ( ty) } ) )
2239
2262
}
2240
2263
ItemKind :: Enum ( ref def, generics) => EnumItem ( Enum {
2241
2264
variants : def. variants . iter ( ) . map ( |v| clean_variant ( v, cx) ) . collect ( ) ,
0 commit comments