1
1
//! Transforms syntax into `Path` objects, ideally with accounting for hygiene
2
2
3
+ use std:: iter;
4
+
3
5
use crate :: type_ref:: ConstScalarOrPath ;
4
6
5
7
use either:: Either ;
@@ -86,15 +88,26 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx<'_>) -> Option<Path
86
88
generic_args. resize ( segments. len ( ) , None ) ;
87
89
}
88
90
91
+ let self_type = GenericArg :: Type ( self_type) ;
92
+
89
93
// Insert the type reference (T in the above example) as Self parameter for the trait
90
94
let last_segment = generic_args. get_mut ( segments. len ( ) - num_segments) ?;
91
- let mut args_inner = match last_segment {
92
- Some ( it) => it. as_ref ( ) . clone ( ) ,
93
- None => GenericArgs :: empty ( ) ,
94
- } ;
95
- args_inner. has_self_type = true ;
96
- args_inner. args . insert ( 0 , GenericArg :: Type ( self_type) ) ;
97
- * last_segment = Some ( Interned :: new ( args_inner) ) ;
95
+ * last_segment = Some ( Interned :: new ( match last_segment. take ( ) {
96
+ Some ( it) => GenericArgs {
97
+ args : iter:: once ( self_type)
98
+ . chain ( it. args . iter ( ) . cloned ( ) )
99
+ . collect ( ) ,
100
+
101
+ has_self_type : true ,
102
+ bindings : it. bindings . clone ( ) ,
103
+ desugared_from_fn : it. desugared_from_fn ,
104
+ } ,
105
+ None => GenericArgs {
106
+ args : Box :: new ( [ self_type] ) ,
107
+ has_self_type : true ,
108
+ ..GenericArgs :: empty ( )
109
+ } ,
110
+ } ) ) ;
98
111
}
99
112
}
100
113
}
@@ -187,7 +200,7 @@ pub(super) fn lower_generic_args(
187
200
. map ( |it| Interned :: new ( TypeBound :: from_ast ( lower_ctx, it) ) )
188
201
. collect ( )
189
202
} else {
190
- Vec :: new ( )
203
+ Box :: default ( )
191
204
} ;
192
205
bindings. push ( AssociatedTypeBinding { name, args, type_ref, bounds } ) ;
193
206
}
@@ -208,7 +221,12 @@ pub(super) fn lower_generic_args(
208
221
if args. is_empty ( ) && bindings. is_empty ( ) {
209
222
return None ;
210
223
}
211
- Some ( GenericArgs { args, has_self_type : false , bindings, desugared_from_fn : false } )
224
+ Some ( GenericArgs {
225
+ args : args. into_boxed_slice ( ) ,
226
+ has_self_type : false ,
227
+ bindings : bindings. into_boxed_slice ( ) ,
228
+ desugared_from_fn : false ,
229
+ } )
212
230
}
213
231
214
232
/// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y)
@@ -218,33 +236,30 @@ fn lower_generic_args_from_fn_path(
218
236
params : Option < ast:: ParamList > ,
219
237
ret_type : Option < ast:: RetType > ,
220
238
) -> Option < GenericArgs > {
221
- let mut args = Vec :: new ( ) ;
222
- let mut bindings = Vec :: new ( ) ;
223
239
let params = params?;
224
240
let mut param_types = Vec :: new ( ) ;
225
241
for param in params. params ( ) {
226
242
let type_ref = TypeRef :: from_ast_opt ( ctx, param. ty ( ) ) ;
227
243
param_types. push ( type_ref) ;
228
244
}
229
- let arg = GenericArg :: Type ( TypeRef :: Tuple ( param_types) ) ;
230
- args. push ( arg) ;
231
- if let Some ( ret_type) = ret_type {
245
+ let args = Box :: new ( [ GenericArg :: Type ( TypeRef :: Tuple ( param_types) ) ] ) ;
246
+ let bindings = if let Some ( ret_type) = ret_type {
232
247
let type_ref = TypeRef :: from_ast_opt ( ctx, ret_type. ty ( ) ) ;
233
- bindings . push ( AssociatedTypeBinding {
248
+ Box :: new ( [ AssociatedTypeBinding {
234
249
name : name ! [ Output ] ,
235
250
args : None ,
236
251
type_ref : Some ( type_ref) ,
237
- bounds : Vec :: new ( ) ,
238
- } ) ;
252
+ bounds : Box :: default ( ) ,
253
+ } ] )
239
254
} else {
240
255
// -> ()
241
256
let type_ref = TypeRef :: Tuple ( Vec :: new ( ) ) ;
242
- bindings . push ( AssociatedTypeBinding {
257
+ Box :: new ( [ AssociatedTypeBinding {
243
258
name : name ! [ Output ] ,
244
259
args : None ,
245
260
type_ref : Some ( type_ref) ,
246
- bounds : Vec :: new ( ) ,
247
- } ) ;
248
- }
261
+ bounds : Box :: default ( ) ,
262
+ } ] )
263
+ } ;
249
264
Some ( GenericArgs { args, has_self_type : false , bindings, desugared_from_fn : true } )
250
265
}
0 commit comments