@@ -78,28 +78,46 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
78
78
pub ( crate ) fn clean_middle_generic_args < ' tcx > (
79
79
cx : & mut DocContext < ' tcx > ,
80
80
args : ty:: Binder < ' tcx , & ' tcx [ ty:: GenericArg < ' tcx > ] > ,
81
- has_self : bool ,
81
+ mut has_self : bool ,
82
82
owner : DefId ,
83
83
) -> Vec < GenericArg > {
84
84
if args. skip_binder ( ) . is_empty ( ) {
85
85
// Fast path which avoids executing the query `generics_of`.
86
86
return Vec :: new ( ) ;
87
87
}
88
88
89
- let params = & cx. tcx . generics_of ( owner) . params ;
89
+ let generics = cx. tcx . generics_of ( owner) ;
90
90
let mut elision_has_failed_once_before = false ;
91
91
92
92
let offset = if has_self { 1 } else { 0 } ;
93
93
let mut clean_args = Vec :: with_capacity ( args. skip_binder ( ) . len ( ) . saturating_sub ( offset) ) ;
94
94
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
+
95
113
let clean_arg = |( index, arg) : ( usize , & ty:: GenericArg < ' tcx > ) | match arg. unpack ( ) {
96
114
GenericArgKind :: Lifetime ( lt) => {
97
115
Some ( GenericArg :: Lifetime ( clean_middle_region ( lt) . unwrap_or ( Lifetime :: elided ( ) ) ) )
98
116
}
99
117
GenericArgKind :: Type ( _) if has_self && index == 0 => None ,
100
118
GenericArgKind :: Type ( ty) => {
101
119
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 )
103
121
{
104
122
let default = args. map_bound ( |args| default. instantiate ( cx. tcx , args) . expect_ty ( ) ) ;
105
123
@@ -114,17 +132,18 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
114
132
args. rebind ( ty) ,
115
133
cx,
116
134
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 } ) ,
118
136
) ) )
119
137
}
120
138
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
122
141
{
123
142
return None ;
124
143
}
125
144
126
145
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 )
128
147
{
129
148
let default =
130
149
args. map_bound ( |args| default. instantiate ( cx. tcx , args) . expect_const ( ) ) ;
0 commit comments