@@ -44,7 +44,12 @@ pub fn make_function_definition_with_defaults(
44
44
builder_fields,
45
45
builder_args,
46
46
builder_inits,
47
- } = make_extender ( sig, object_fn_param, default_fn_params) ;
47
+ } = make_extender (
48
+ sig. name ( ) ,
49
+ object_fn_param,
50
+ & required_fn_params,
51
+ & default_fn_params,
52
+ ) ;
48
53
49
54
// ExBuilder::new() constructor signature.
50
55
let FnParamTokens {
@@ -61,19 +66,6 @@ pub fn make_function_definition_with_defaults(
61
66
) ;
62
67
let required_params_builder_constructor = & required_params_class_methods;
63
68
64
- // Parameters for some_function() and some_function_ex().
65
- // TODO collapse with next assignment. Maybe next 2
66
- /*let FnParamTokens {
67
- params: required_params_class_methods,
68
- ..
69
- } = functions_common::make_params_exprs(
70
- required_fn_params.iter().cloned(),
71
- true,
72
- true,
73
- false,
74
- false,
75
- );*/
76
-
77
69
// Forwarded args by some_function() and some_function_ex().
78
70
let FnParamTokens {
79
71
arg_names : required_args_internal,
@@ -92,13 +84,15 @@ pub fn make_function_definition_with_defaults(
92
84
// then we need to annotate the _ex() function with an explicit lifetime. Also adjust &self -> &'a self.
93
85
let receiver_self = & code. receiver . self_prefix ;
94
86
95
- let ( builder_ret_lifetime, receiver_param) ;
96
- if let Some ( func_lifetime) = func_general_lifetime. as_ref ( ) {
97
- builder_ret_lifetime = Some ( func_lifetime) ;
98
- receiver_param = & code. receiver . param_lifetime_a ;
87
+ let ( simple_receiver_param, extended_receiver_param, func_or_builder_lifetime) ;
88
+ if let Some ( func_lt) = func_general_lifetime. as_ref ( ) . or ( builder_lifetime. as_ref ( ) ) {
89
+ simple_receiver_param = & code. receiver . param ;
90
+ extended_receiver_param = & code. receiver . param_lifetime_a ;
91
+ func_or_builder_lifetime = Some ( func_lt) ;
99
92
} else {
100
- builder_ret_lifetime = None ;
101
- receiver_param = & code. receiver . param ;
93
+ simple_receiver_param = & code. receiver . param ;
94
+ extended_receiver_param = & code. receiver . param ;
95
+ func_or_builder_lifetime = None ;
102
96
} ;
103
97
104
98
// Technically, the builder would not need a lifetime -- it could just maintain an `object_ptr` copy.
@@ -146,7 +140,7 @@ pub fn make_function_definition_with_defaults(
146
140
#[ doc = #default_parameter_usage]
147
141
#[ inline]
148
142
#vis fn #simple_fn_name #func_general_lifetime (
149
- #receiver_param
143
+ #simple_receiver_param
150
144
#( #required_params_class_methods, ) *
151
145
) #return_decl {
152
146
#receiver_self #extended_fn_name(
@@ -157,10 +151,10 @@ pub fn make_function_definition_with_defaults(
157
151
// _ex() function:
158
152
// Lifetime is set if any parameter is a reference OR if the method is not static/global (and thus can refer to self).
159
153
#[ inline]
160
- #vis fn #extended_fn_name #func_general_lifetime (
161
- #receiver_param
154
+ #vis fn #extended_fn_name #func_or_builder_lifetime (
155
+ #extended_receiver_param
162
156
#( #required_params_class_methods, ) *
163
- ) -> #builder_ty #builder_ret_lifetime {
157
+ ) -> #builder_ty #builder_lifetime {
164
158
#builder_ty:: new(
165
159
#object_arg
166
160
#( #required_args_internal, ) *
@@ -278,26 +272,34 @@ fn make_extender_receiver(sig: &dyn Function) -> ExtenderReceiver {
278
272
}
279
273
280
274
fn make_extender (
281
- sig : & dyn Function ,
282
- object_fn_param : Option < FnParam > ,
283
- default_fn_params : Vec < & FnParam > ,
275
+ fn_name : & str ,
276
+ receiver_param : Option < FnParam > ,
277
+ required_params : & [ & FnParam ] ,
278
+ default_params : & [ & FnParam ] ,
284
279
) -> Extender {
285
280
// Note: could build a documentation string with default values here, but the Rust tokens are not very readable,
286
281
// and often not helpful, such as Enum::from_ord(13). Maybe one day those could be resolved and curated.
287
282
288
- let lifetime = if sig. qualifier ( ) . is_static_or_global ( ) {
289
- None
290
- } else {
283
+ let all_fn_params = receiver_param
284
+ . iter ( )
285
+ . chain ( required_params. iter ( ) . cloned ( ) )
286
+ . chain ( default_params. iter ( ) . cloned ( ) ) ;
287
+ let len = all_fn_params. size_hint ( ) . 0 ;
288
+
289
+ // If builder is a method with a receiver OR any *required* parameter is by-ref, use lifetime.
290
+ // Default parameters cannot be by-ref, since they need to store a default value. Potential optimization later.
291
+ let lifetime = if receiver_param. is_some ( ) // !sig.qualifier().is_static_or_global()
292
+ || required_params. iter ( ) . any ( |p| p. type_ . is_pass_by_ref ( ) )
293
+ {
291
294
Some ( quote ! { <' a> } )
295
+ } else {
296
+ None
292
297
} ;
293
298
294
- let all_fn_params = object_fn_param. iter ( ) . chain ( sig. params ( ) . iter ( ) ) ;
295
- let len = all_fn_params. size_hint ( ) . 0 ;
296
-
297
299
let mut result = Extender {
298
- builder_ty : format_ident ! ( "Ex{}" , conv:: to_pascal_case( sig . name ( ) ) ) ,
300
+ builder_ty : format_ident ! ( "Ex{}" , conv:: to_pascal_case( fn_name ) ) ,
299
301
builder_lifetime : lifetime,
300
- builder_methods : Vec :: with_capacity ( default_fn_params . len ( ) ) ,
302
+ builder_methods : Vec :: with_capacity ( default_params . len ( ) ) ,
301
303
builder_fields : Vec :: with_capacity ( len) ,
302
304
builder_args : Vec :: with_capacity ( len) ,
303
305
builder_inits : Vec :: with_capacity ( len) ,
@@ -316,7 +318,6 @@ fn make_extender(
316
318
let init = if let Some ( value) = default_value {
317
319
make_field_init ( name, Some ( value) , conversion)
318
320
} else {
319
- //quote! { #name }
320
321
make_field_init ( name, None , conversion)
321
322
} ;
322
323
@@ -336,7 +337,7 @@ fn make_extender(
336
337
result. builder_inits . push ( init) ;
337
338
}
338
339
339
- for param in default_fn_params {
340
+ for param in default_params {
340
341
let FnParam { name, type_, .. } = param;
341
342
let param_type = type_. param_decl ( ) ;
342
343
let ( _, field_needs_conversion) = default_extender_field_decl ( type_, true ) ;
@@ -397,9 +398,9 @@ fn make_field_init(
397
398
match ( conversion, expr) {
398
399
( Conv :: ObjectArg , Some ( expr) ) => quote ! { #name: #expr. consume_object( ) } ,
399
400
( Conv :: ObjectArg , None ) /*. */ => quote ! { #name: #name. consume_object( ) } ,
400
- ( Conv :: Reference , Some ( expr ) ) => quote ! { #name : & #expr } ,
401
- ( Conv :: Reference , None ) /*. */ => quote ! { #name : & #name } ,
402
- ( Conv :: None | Conv :: ReferenceWithDefault , Some ( expr) ) => quote ! { #name: #expr } ,
403
- ( Conv :: None | Conv :: ReferenceWithDefault , None ) /*. */ => quote ! { #name } ,
401
+
402
+ // Currently no differentiation between None|Reference|ReferenceWithDefault; this may change...
403
+ ( Conv :: None | Conv :: Reference | Conv :: ReferenceWithDefault , Some ( expr) ) => quote ! { #name: #expr } ,
404
+ ( Conv :: None | Conv :: Reference | Conv :: ReferenceWithDefault , None ) /*. */ => quote ! { #name } ,
404
405
}
405
406
}
0 commit comments