@@ -388,14 +388,35 @@ impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
388
388
let trait_ = lifted. trait_ref ( cx. tcx ) . clean ( cx) ;
389
389
let self_type = self . self_ty ( ) . clean ( cx) ;
390
390
Type :: QPath {
391
- name : cx . tcx . associated_item ( self . item_def_id ) . name ,
391
+ assoc : Box :: new ( projection_to_path_segment ( * self , cx ) ) ,
392
392
self_def_id : self_type. def_id ( & cx. cache ) ,
393
393
self_type : box self_type,
394
394
trait_,
395
395
}
396
396
}
397
397
}
398
398
399
+ fn projection_to_path_segment ( ty : ty:: ProjectionTy < ' _ > , cx : & mut DocContext < ' _ > ) -> PathSegment {
400
+ let item = cx. tcx . associated_item ( ty. item_def_id ) ;
401
+ let generics = cx. tcx . generics_of ( ty. item_def_id ) ;
402
+ PathSegment {
403
+ name : item. name ,
404
+ args : GenericArgs :: AngleBracketed {
405
+ args : ty. substs [ generics. parent_count ..]
406
+ . iter ( )
407
+ . map ( |ty| match ty. unpack ( ) {
408
+ ty:: subst:: GenericArgKind :: Lifetime ( lt) => {
409
+ GenericArg :: Lifetime ( lt. clean ( cx) . unwrap ( ) )
410
+ }
411
+ ty:: subst:: GenericArgKind :: Type ( ty) => GenericArg :: Type ( ty. clean ( cx) ) ,
412
+ ty:: subst:: GenericArgKind :: Const ( c) => GenericArg :: Const ( Box :: new ( c. clean ( cx) ) ) ,
413
+ } )
414
+ . collect ( ) ,
415
+ bindings : Default :: default ( ) ,
416
+ } ,
417
+ }
418
+ }
419
+
399
420
impl Clean < GenericParamDef > for ty:: GenericParamDef {
400
421
fn clean ( & self , cx : & mut DocContext < ' _ > ) -> GenericParamDef {
401
422
let ( name, kind) = match self . kind {
@@ -601,8 +622,8 @@ fn clean_ty_generics(
601
622
} )
602
623
. collect :: < Vec < GenericParamDef > > ( ) ;
603
624
604
- // param index -> [(DefId of trait, associated type name, type)]
605
- let mut impl_trait_proj = FxHashMap :: < u32 , Vec < ( DefId , Symbol , Ty < ' _ > ) > > :: default ( ) ;
625
+ // param index -> [(DefId of trait, associated type name and generics , type)]
626
+ let mut impl_trait_proj = FxHashMap :: < u32 , Vec < ( DefId , PathSegment , Ty < ' _ > ) > > :: default ( ) ;
606
627
607
628
let where_predicates = preds
608
629
. predicates
@@ -648,8 +669,9 @@ fn clean_ty_generics(
648
669
649
670
let proj = projection
650
671
. map ( |p| ( p. skip_binder ( ) . projection_ty . clean ( cx) , p. skip_binder ( ) . term ) ) ;
651
- if let Some ( ( ( _, trait_did, name) , rhs) ) =
652
- proj. as_ref ( ) . and_then ( |( lhs, rhs) | Some ( ( lhs. projection ( ) ?, rhs) ) )
672
+ if let Some ( ( ( _, trait_did, name) , rhs) ) = proj
673
+ . as_ref ( )
674
+ . and_then ( |( lhs, rhs) : & ( Type , _ ) | Some ( ( lhs. projection ( ) ?, rhs) ) )
653
675
{
654
676
// FIXME(...): Remove this unwrap()
655
677
impl_trait_proj. entry ( param_idx) . or_default ( ) . push ( (
@@ -985,7 +1007,7 @@ impl Clean<Item> for hir::TraitItem<'_> {
985
1007
TyMethodItem ( t)
986
1008
}
987
1009
hir:: TraitItemKind :: Type ( bounds, ref default) => {
988
- let generics = self . generics . clean ( cx) ;
1010
+ let generics = enter_impl_trait ( cx , |cx| self . generics . clean ( cx) ) ;
989
1011
let bounds = bounds. iter ( ) . filter_map ( |x| x. clean ( cx) ) . collect ( ) ;
990
1012
let default = default. map ( |t| t. clean ( cx) ) ;
991
1013
AssocTypeItem ( Box :: new ( generics) , bounds, default)
@@ -1136,6 +1158,27 @@ impl Clean<Item> for ty::AssocItem {
1136
1158
ty:: AssocKind :: Type => {
1137
1159
let my_name = self . name ;
1138
1160
1161
+ fn param_eq_arg ( param : & GenericParamDef , arg : & GenericArg ) -> bool {
1162
+ match ( & param. kind , arg) {
1163
+ ( GenericParamDefKind :: Type { .. } , GenericArg :: Type ( Type :: Generic ( ty) ) )
1164
+ if * ty == param. name =>
1165
+ {
1166
+ true
1167
+ }
1168
+ (
1169
+ GenericParamDefKind :: Lifetime { .. } ,
1170
+ GenericArg :: Lifetime ( Lifetime ( lt) ) ,
1171
+ ) if * lt == param. name => true ,
1172
+ ( GenericParamDefKind :: Const { .. } , GenericArg :: Const ( c) ) => {
1173
+ match & c. kind {
1174
+ ConstantKind :: TyConst { expr } => expr == param. name . as_str ( ) ,
1175
+ _ => false ,
1176
+ }
1177
+ }
1178
+ _ => false ,
1179
+ }
1180
+ }
1181
+
1139
1182
if let ty:: TraitContainer ( _) = self . container {
1140
1183
let bounds = tcx. explicit_item_bounds ( self . def_id ) ;
1141
1184
let predicates = ty:: GenericPredicates { parent : None , predicates : bounds } ;
@@ -1147,10 +1190,10 @@ impl Clean<Item> for ty::AssocItem {
1147
1190
. where_predicates
1148
1191
. drain_filter ( |pred| match * pred {
1149
1192
WherePredicate :: BoundPredicate {
1150
- ty : QPath { name , ref self_type, ref trait_, .. } ,
1193
+ ty : QPath { ref assoc , ref self_type, ref trait_, .. } ,
1151
1194
..
1152
1195
} => {
1153
- if name != my_name {
1196
+ if assoc . name != my_name {
1154
1197
return false ;
1155
1198
}
1156
1199
if trait_. def_id ( ) != self . container . id ( ) {
@@ -1267,7 +1310,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
1267
1310
} ;
1268
1311
register_res ( cx, trait_. res ) ;
1269
1312
Type :: QPath {
1270
- name : p. segments . last ( ) . expect ( "segments were empty" ) . ident . name ,
1313
+ assoc : Box :: new ( p. segments . last ( ) . expect ( "segments were empty" ) . clean ( cx ) ) ,
1271
1314
self_def_id : Some ( DefId :: local ( qself. hir_id . owner . local_def_index ) ) ,
1272
1315
self_type : box qself. clean ( cx) ,
1273
1316
trait_,
@@ -1284,7 +1327,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
1284
1327
let trait_ = hir:: Path { span, res, segments : & [ ] } . clean ( cx) ;
1285
1328
register_res ( cx, trait_. res ) ;
1286
1329
Type :: QPath {
1287
- name : segment. ident . name ,
1330
+ assoc : Box :: new ( segment. clean ( cx ) ) ,
1288
1331
self_def_id : res. opt_def_id ( ) ,
1289
1332
self_type : box qself. clean ( cx) ,
1290
1333
trait_,
@@ -1557,7 +1600,16 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
1557
1600
let mut bindings = vec ! [ ] ;
1558
1601
for pb in obj. projection_bounds ( ) {
1559
1602
bindings. push ( TypeBinding {
1560
- name : cx. tcx . associated_item ( pb. item_def_id ( ) ) . name ,
1603
+ assoc : projection_to_path_segment (
1604
+ pb. skip_binder ( )
1605
+ . lift_to_tcx ( cx. tcx )
1606
+ . unwrap ( )
1607
+ // HACK(compiler-errors): Doesn't actually matter what self
1608
+ // type we put here, because we're only using the GAT's substs.
1609
+ . with_self_ty ( cx. tcx , cx. tcx . types . self_param )
1610
+ . projection_ty ,
1611
+ cx,
1612
+ ) ,
1561
1613
kind : TypeBindingKind :: Equality { term : pb. skip_binder ( ) . term . clean ( cx) } ,
1562
1614
} ) ;
1563
1615
}
@@ -1623,10 +1675,10 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
1623
1675
== trait_ref. skip_binder ( )
1624
1676
{
1625
1677
Some ( TypeBinding {
1626
- name : cx
1627
- . tcx
1628
- . associated_item ( proj . projection_ty . item_def_id )
1629
- . name ,
1678
+ assoc : projection_to_path_segment (
1679
+ proj . projection_ty ,
1680
+ cx ,
1681
+ ) ,
1630
1682
kind : TypeBindingKind :: Equality {
1631
1683
term : proj. term . clean ( cx) ,
1632
1684
} ,
@@ -2169,7 +2221,10 @@ fn clean_maybe_renamed_foreign_item(
2169
2221
2170
2222
impl Clean < TypeBinding > for hir:: TypeBinding < ' _ > {
2171
2223
fn clean ( & self , cx : & mut DocContext < ' _ > ) -> TypeBinding {
2172
- TypeBinding { name : self . ident . name , kind : self . kind . clean ( cx) }
2224
+ TypeBinding {
2225
+ assoc : PathSegment { name : self . ident . name , args : self . gen_args . clean ( cx) } ,
2226
+ kind : self . kind . clean ( cx) ,
2227
+ }
2173
2228
}
2174
2229
}
2175
2230
0 commit comments