@@ -81,7 +81,8 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
81
81
mut has_self : bool ,
82
82
owner : DefId ,
83
83
) -> Vec < GenericArg > {
84
- if args. skip_binder ( ) . is_empty ( ) {
84
+ let ( args, bound_vars) = ( args. skip_binder ( ) , args. bound_vars ( ) ) ;
85
+ if args. is_empty ( ) {
85
86
// Fast path which avoids executing the query `generics_of`.
86
87
return Vec :: new ( ) ;
87
88
}
@@ -90,24 +91,21 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
90
91
let mut elision_has_failed_once_before = false ;
91
92
92
93
let offset = if has_self { 1 } else { 0 } ;
93
- let mut clean_args = Vec :: with_capacity ( args. skip_binder ( ) . len ( ) . saturating_sub ( offset) ) ;
94
+ let mut clean_args = Vec :: with_capacity ( args. len ( ) . saturating_sub ( offset) ) ;
94
95
95
96
// If the container is a trait object type, the arguments won't contain the self type but the
96
97
// generics of the corresponding trait will. In such a case, prepend a dummy self type in order
97
98
// to align the arguments and parameters for the iteration below and to enable us to correctly
98
99
// instantiate the generic parameter default later.
99
100
let args = if !has_self && generics. parent . is_none ( ) && generics. has_self {
100
101
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
- } )
102
+ [ cx. tcx . types . trait_object_dummy_self . into ( ) ]
103
+ . into_iter ( )
104
+ . chain ( args. iter ( ) . copied ( ) )
105
+ . collect :: < Vec < _ > > ( )
106
+ . into ( )
109
107
} else {
110
- args
108
+ std :: borrow :: Cow :: from ( args)
111
109
} ;
112
110
113
111
let clean_arg = |( index, arg) : ( usize , & ty:: GenericArg < ' tcx > ) | match arg. unpack ( ) {
@@ -116,23 +114,28 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
116
114
}
117
115
GenericArgKind :: Type ( _) if has_self && index == 0 => None ,
118
116
GenericArgKind :: Type ( ty) => {
117
+ let ty = ty:: Binder :: bind_with_vars ( ty, bound_vars) ;
118
+
119
119
if !elision_has_failed_once_before
120
120
&& let Some ( default) = generics. param_at ( index, cx. tcx ) . default_value ( cx. tcx )
121
121
{
122
- let default = args. map_bound ( |args| default. instantiate ( cx. tcx , args) . expect_ty ( ) ) ;
123
-
124
- if can_elide_generic_arg ( args. rebind ( ty) , default) {
122
+ let default = default. instantiate ( cx. tcx , args. as_ref ( ) ) . expect_ty ( ) ;
123
+ if can_elide_generic_arg ( ty, ty. rebind ( default) ) {
125
124
return None ;
126
125
}
127
126
128
127
elision_has_failed_once_before = true ;
129
128
}
130
129
131
130
Some ( GenericArg :: Type ( clean_middle_ty (
132
- args . rebind ( ty ) ,
131
+ ty ,
133
132
cx,
134
133
None ,
135
- Some ( crate :: clean:: ContainerTy :: Regular { ty : owner, args, arg : index } ) ,
134
+ Some ( crate :: clean:: ContainerTy :: Regular {
135
+ ty : owner,
136
+ args : ty. rebind ( args. as_ref ( ) ) ,
137
+ arg : index,
138
+ } ) ,
136
139
) ) )
137
140
}
138
141
GenericArgKind :: Const ( ct) => {
@@ -142,24 +145,24 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
142
145
return None ;
143
146
}
144
147
148
+ let ct = ty:: Binder :: bind_with_vars ( ct, bound_vars) ;
149
+
145
150
if !elision_has_failed_once_before
146
151
&& let Some ( default) = generics. param_at ( index, cx. tcx ) . default_value ( cx. tcx )
147
152
{
148
- let default =
149
- args. map_bound ( |args| default. instantiate ( cx. tcx , args) . expect_const ( ) ) ;
150
-
151
- if can_elide_generic_arg ( args. rebind ( ct) , default) {
153
+ let default = default. instantiate ( cx. tcx , args. as_ref ( ) ) . expect_const ( ) ;
154
+ if can_elide_generic_arg ( ct, ct. rebind ( default) ) {
152
155
return None ;
153
156
}
154
157
155
158
elision_has_failed_once_before = true ;
156
159
}
157
160
158
- Some ( GenericArg :: Const ( Box :: new ( clean_middle_const ( args . rebind ( ct ) , cx) ) ) )
161
+ Some ( GenericArg :: Const ( Box :: new ( clean_middle_const ( ct , cx) ) ) )
159
162
}
160
163
} ;
161
164
162
- clean_args. extend ( args. skip_binder ( ) . iter ( ) . enumerate ( ) . rev ( ) . filter_map ( clean_arg) ) ;
165
+ clean_args. extend ( args. iter ( ) . enumerate ( ) . rev ( ) . filter_map ( clean_arg) ) ;
163
166
clean_args. reverse ( ) ;
164
167
clean_args
165
168
}
0 commit comments