11//! Transforms syntax into `Path` objects, ideally with accounting for hygiene
22
3+ use std:: iter;
4+
35use crate :: type_ref:: ConstScalarOrPath ;
46
57use either:: Either ;
@@ -86,15 +88,26 @@ pub(super) fn lower_path(mut path: ast::Path, ctx: &LowerCtx<'_>) -> Option<Path
8688 generic_args. resize ( segments. len ( ) , None ) ;
8789 }
8890
91+ let self_type = GenericArg :: Type ( self_type) ;
92+
8993 // Insert the type reference (T in the above example) as Self parameter for the trait
9094 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+ } ) ) ;
98111 }
99112 }
100113 }
@@ -187,7 +200,7 @@ pub(super) fn lower_generic_args(
187200 . map ( |it| Interned :: new ( TypeBound :: from_ast ( lower_ctx, it) ) )
188201 . collect ( )
189202 } else {
190- Vec :: new ( )
203+ Box :: default ( )
191204 } ;
192205 bindings. push ( AssociatedTypeBinding { name, args, type_ref, bounds } ) ;
193206 }
@@ -208,7 +221,12 @@ pub(super) fn lower_generic_args(
208221 if args. is_empty ( ) && bindings. is_empty ( ) {
209222 return None ;
210223 }
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+ } )
212230}
213231
214232/// 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(
218236 params : Option < ast:: ParamList > ,
219237 ret_type : Option < ast:: RetType > ,
220238) -> Option < GenericArgs > {
221- let mut args = Vec :: new ( ) ;
222- let mut bindings = Vec :: new ( ) ;
223239 let params = params?;
224240 let mut param_types = Vec :: new ( ) ;
225241 for param in params. params ( ) {
226242 let type_ref = TypeRef :: from_ast_opt ( ctx, param. ty ( ) ) ;
227243 param_types. push ( type_ref) ;
228244 }
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 {
232247 let type_ref = TypeRef :: from_ast_opt ( ctx, ret_type. ty ( ) ) ;
233- bindings . push ( AssociatedTypeBinding {
248+ Box :: new ( [ AssociatedTypeBinding {
234249 name : name ! [ Output ] ,
235250 args : None ,
236251 type_ref : Some ( type_ref) ,
237- bounds : Vec :: new ( ) ,
238- } ) ;
252+ bounds : Box :: default ( ) ,
253+ } ] )
239254 } else {
240255 // -> ()
241256 let type_ref = TypeRef :: Tuple ( Vec :: new ( ) ) ;
242- bindings . push ( AssociatedTypeBinding {
257+ Box :: new ( [ AssociatedTypeBinding {
243258 name : name ! [ Output ] ,
244259 args : None ,
245260 type_ref : Some ( type_ref) ,
246- bounds : Vec :: new ( ) ,
247- } ) ;
248- }
261+ bounds : Box :: default ( ) ,
262+ } ] )
263+ } ;
249264 Some ( GenericArgs { args, has_self_type : false , bindings, desugared_from_fn : true } )
250265}
0 commit comments