@@ -441,7 +441,7 @@ fn clean_projection<'tcx>(
441441 assoc : projection_to_path_segment ( ty, cx) ,
442442 should_show_cast,
443443 self_type,
444- trait_,
444+ trait_ : Some ( trait_ ) ,
445445 } ) )
446446}
447447
@@ -1330,7 +1330,13 @@ pub(crate) fn clean_middle_assoc_item<'tcx>(
13301330 let mut bounds: Vec < GenericBound > = Vec :: new ( ) ;
13311331 generics. where_predicates . retain_mut ( |pred| match * pred {
13321332 WherePredicate :: BoundPredicate {
1333- ty : QPath ( box QPathData { ref assoc, ref self_type, ref trait_, .. } ) ,
1333+ ty :
1334+ QPath ( box QPathData {
1335+ ref assoc,
1336+ ref self_type,
1337+ trait_ : Some ( ref trait_) ,
1338+ ..
1339+ } ) ,
13341340 bounds : ref mut pred_bounds,
13351341 ..
13361342 } => {
@@ -1492,25 +1498,30 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
14921498 assoc : clean_path_segment ( p. segments . last ( ) . expect ( "segments were empty" ) , cx) ,
14931499 should_show_cast,
14941500 self_type,
1495- trait_,
1501+ trait_ : Some ( trait_ ) ,
14961502 } ) )
14971503 }
14981504 hir:: QPath :: TypeRelative ( qself, segment) => {
14991505 let ty = hir_ty_to_ty ( cx. tcx , hir_ty) ;
1500- let res = match ty. kind ( ) {
1506+ let self_type = clean_ty ( qself, cx) ;
1507+
1508+ let ( trait_, should_show_cast) = match ty. kind ( ) {
15011509 ty:: Alias ( ty:: Projection , proj) => {
1502- Res :: Def ( DefKind :: Trait , proj. trait_ref ( cx. tcx ) . def_id )
1510+ let res = Res :: Def ( DefKind :: Trait , proj. trait_ref ( cx. tcx ) . def_id ) ;
1511+ let trait_ = clean_path ( & hir:: Path { span, res, segments : & [ ] } , cx) ;
1512+ register_res ( cx, trait_. res ) ;
1513+ let self_def_id = res. opt_def_id ( ) ;
1514+ let should_show_cast =
1515+ compute_should_show_cast ( self_def_id, & trait_, & self_type) ;
1516+
1517+ ( Some ( trait_) , should_show_cast)
15031518 }
1519+ ty:: Alias ( ty:: Inherent , _) => ( None , false ) ,
15041520 // Rustdoc handles `ty::Error`s by turning them into `Type::Infer`s.
15051521 ty:: Error ( _) => return Type :: Infer ,
1506- // Otherwise, this is an inherent associated type.
1507- _ => return clean_middle_ty ( ty:: Binder :: dummy ( ty) , cx, None ) ,
1522+ _ => bug ! ( "clean: expected associated type, found `{ty:?}`" ) ,
15081523 } ;
1509- let trait_ = clean_path ( & hir:: Path { span, res, segments : & [ ] } , cx) ;
1510- register_res ( cx, trait_. res ) ;
1511- let self_def_id = res. opt_def_id ( ) ;
1512- let self_type = clean_ty ( qself, cx) ;
1513- let should_show_cast = compute_should_show_cast ( self_def_id, & trait_, & self_type) ;
1524+
15141525 Type :: QPath ( Box :: new ( QPathData {
15151526 assoc : clean_path_segment ( segment, cx) ,
15161527 should_show_cast,
@@ -1836,9 +1847,28 @@ pub(crate) fn clean_middle_ty<'tcx>(
18361847 clean_projection ( bound_ty. rebind ( * data) , cx, parent_def_id)
18371848 }
18381849
1839- // FIXME(fmease): Clean inherent projections properly. This requires making the trait ref in
1840- // `QPathData` optional or alternatively adding a new `clean::Type` variant.
1841- ty:: Alias ( ty:: Inherent , _data) => Type :: Infer ,
1850+ ty:: Alias ( ty:: Inherent , alias_ty) => {
1851+ let alias_ty = bound_ty. rebind ( alias_ty) ;
1852+ let self_type = clean_middle_ty ( alias_ty. map_bound ( |ty| ty. self_ty ( ) ) , cx, None ) ;
1853+
1854+ Type :: QPath ( Box :: new ( QPathData {
1855+ assoc : PathSegment {
1856+ name : cx. tcx . associated_item ( alias_ty. skip_binder ( ) . def_id ) . name ,
1857+ args : GenericArgs :: AngleBracketed {
1858+ args : substs_to_args (
1859+ cx,
1860+ alias_ty. map_bound ( |ty| ty. substs . as_slice ( ) ) ,
1861+ true ,
1862+ )
1863+ . into ( ) ,
1864+ bindings : Default :: default ( ) ,
1865+ } ,
1866+ } ,
1867+ should_show_cast : false ,
1868+ self_type,
1869+ trait_ : None ,
1870+ } ) )
1871+ }
18421872
18431873 ty:: Param ( ref p) => {
18441874 if let Some ( bounds) = cx. impl_trait_bounds . remove ( & p. index . into ( ) ) {
0 commit comments