@@ -78,28 +78,46 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
7878pub ( crate ) fn clean_middle_generic_args < ' tcx > (
7979 cx : & mut DocContext < ' tcx > ,
8080 args : ty:: Binder < ' tcx , & ' tcx [ ty:: GenericArg < ' tcx > ] > ,
81- has_self : bool ,
81+ mut has_self : bool ,
8282 owner : DefId ,
8383) -> Vec < GenericArg > {
8484 if args. skip_binder ( ) . is_empty ( ) {
8585 // Fast path which avoids executing the query `generics_of`.
8686 return Vec :: new ( ) ;
8787 }
8888
89- let params = & cx. tcx . generics_of ( owner) . params ;
89+ let generics = cx. tcx . generics_of ( owner) ;
9090 let mut elision_has_failed_once_before = false ;
9191
9292 let offset = if has_self { 1 } else { 0 } ;
9393 let mut clean_args = Vec :: with_capacity ( args. skip_binder ( ) . len ( ) . saturating_sub ( offset) ) ;
9494
95+ // If the container is a trait object type, the arguments won't contain the self type but the
96+ // generics of the corresponding trait will. In such a case, prepend a dummy self type in order
97+ // to align the arguments and parameters for the iteration below and to enable us to correctly
98+ // instantiate the generic parameter default later.
99+ let args = if !has_self && generics. parent . is_none ( ) && generics. has_self {
100+ has_self = true ;
101+ // FIXME(fmease): Don't arena-allocate the args (blocked on further refactorings)!
102+ args. map_bound ( |args| {
103+ & * cx. tcx . arena . alloc_from_iter (
104+ [ cx. tcx . types . trait_object_dummy_self . into ( ) ]
105+ . into_iter ( )
106+ . chain ( args. iter ( ) . copied ( ) ) ,
107+ )
108+ } )
109+ } else {
110+ args
111+ } ;
112+
95113 let clean_arg = |( index, arg) : ( usize , & ty:: GenericArg < ' tcx > ) | match arg. unpack ( ) {
96114 GenericArgKind :: Lifetime ( lt) => {
97115 Some ( GenericArg :: Lifetime ( clean_middle_region ( lt) . unwrap_or ( Lifetime :: elided ( ) ) ) )
98116 }
99117 GenericArgKind :: Type ( _) if has_self && index == 0 => None ,
100118 GenericArgKind :: Type ( ty) => {
101119 if !elision_has_failed_once_before
102- && let Some ( default) = params [ index] . default_value ( cx. tcx )
120+ && let Some ( default) = generics . param_at ( index, cx . tcx ) . default_value ( cx. tcx )
103121 {
104122 let default = args. map_bound ( |args| default. instantiate ( cx. tcx , args) . expect_ty ( ) ) ;
105123
@@ -114,17 +132,18 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
114132 args. rebind ( ty) ,
115133 cx,
116134 None ,
117- Some ( crate :: clean:: ContainerTy :: Regular { ty : owner, args, has_self , arg : index } ) ,
135+ Some ( crate :: clean:: ContainerTy :: Regular { ty : owner, args, arg : index } ) ,
118136 ) ) )
119137 }
120138 GenericArgKind :: Const ( ct) => {
121- if let ty:: GenericParamDefKind :: Const { is_host_effect : true , .. } = params[ index] . kind
139+ if let ty:: GenericParamDefKind :: Const { is_host_effect : true , .. } =
140+ generics. param_at ( index, cx. tcx ) . kind
122141 {
123142 return None ;
124143 }
125144
126145 if !elision_has_failed_once_before
127- && let Some ( default) = params [ index] . default_value ( cx. tcx )
146+ && let Some ( default) = generics . param_at ( index, cx . tcx ) . default_value ( cx. tcx )
128147 {
129148 let default =
130149 args. map_bound ( |args| default. instantiate ( cx. tcx , args) . expect_const ( ) ) ;
0 commit comments