@@ -1529,7 +1529,9 @@ fn maybe_expand_private_type_alias<'tcx>(
15291529 let Res :: Def ( DefKind :: TyAlias , def_id) = path. res else { return None } ;
15301530 // Substitute private type aliases
15311531 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+ {
15331535 & cx. tcx . hir ( ) . expect_item ( def_id) . kind
15341536 } else {
15351537 return None ;
@@ -1609,7 +1611,7 @@ fn maybe_expand_private_type_alias<'tcx>(
16091611 }
16101612 }
16111613
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) ) )
16131615}
16141616
16151617pub ( crate ) fn clean_ty < ' tcx > ( ty : & hir:: Ty < ' tcx > , cx : & mut DocContext < ' tcx > ) -> Type {
@@ -1700,7 +1702,7 @@ fn normalize<'tcx>(
17001702pub ( crate ) fn clean_middle_ty < ' tcx > (
17011703 bound_ty : ty:: Binder < ' tcx , Ty < ' tcx > > ,
17021704 cx : & mut DocContext < ' tcx > ,
1703- def_id : Option < DefId > ,
1705+ parent_def_id : Option < DefId > ,
17041706) -> Type {
17051707 let bound_ty = normalize ( cx, bound_ty) . unwrap_or ( bound_ty) ;
17061708 match * bound_ty. skip_binder ( ) . kind ( ) {
@@ -1830,7 +1832,9 @@ pub(crate) fn clean_middle_ty<'tcx>(
18301832 Tuple ( t. iter ( ) . map ( |t| clean_middle_ty ( bound_ty. rebind ( t) , cx, None ) ) . collect ( ) )
18311833 }
18321834
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+ }
18341838
18351839 ty:: Param ( ref p) => {
18361840 if let Some ( bounds) = cx. impl_trait_bounds . remove ( & p. index . into ( ) ) {
@@ -1841,15 +1845,30 @@ pub(crate) fn clean_middle_ty<'tcx>(
18411845 }
18421846
18431847 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+ }
18531872 }
18541873
18551874 ty:: Closure ( ..) => panic ! ( "Closure" ) ,
@@ -2229,13 +2248,17 @@ fn clean_maybe_renamed_item<'tcx>(
22292248 generics : clean_generics ( ty. generics , cx) ,
22302249 } ) ,
22312250 ItemKind :: TyAlias ( hir_ty, generics) => {
2251+ * cx. current_type_aliases . entry ( def_id) . or_insert ( 0 ) += 1 ;
22322252 let rustdoc_ty = clean_ty ( hir_ty, cx) ;
22332253 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) } ) )
22392262 }
22402263 ItemKind :: Enum ( ref def, generics) => EnumItem ( Enum {
22412264 variants : def. variants . iter ( ) . map ( |v| clean_variant ( v, cx) ) . collect ( ) ,
0 commit comments