@@ -118,24 +118,30 @@ pub fn make_function_definition(
118
118
( TokenStream :: new ( ) , TokenStream :: new ( ) )
119
119
} ;
120
120
121
- let [ params, param_types, arg_names] = make_params_exprs ( sig. params ( ) ) ;
121
+ let [ params, param_types, arg_names] = make_params_exprs (
122
+ sig. params ( ) . iter ( ) ,
123
+ sig. is_virtual ( ) ,
124
+ !has_default_params, // For *_full function, we don't need impl AsObjectArg<T> parameters
125
+ !has_default_params, // or arg.as_object_arg() calls.
126
+ ) ;
122
127
123
128
let rust_function_name_str = sig. name ( ) ;
124
- let primary_fn_name = if has_default_params {
125
- format_ident ! ( "{}_full" , safe_ident( rust_function_name_str) )
126
- } else {
127
- safe_ident ( rust_function_name_str)
128
- } ;
129
129
130
- let ( default_fn_code, default_structs_code) = if has_default_params {
131
- default_parameters:: make_function_definition_with_defaults (
132
- sig,
133
- code,
134
- & primary_fn_name,
135
- cfg_attributes,
136
- )
130
+ let ( primary_fn_name, default_fn_code, default_structs_code) ;
131
+ if has_default_params {
132
+ primary_fn_name = format_ident ! ( "{}_full" , safe_ident( rust_function_name_str) ) ;
133
+
134
+ ( default_fn_code, default_structs_code) =
135
+ default_parameters:: make_function_definition_with_defaults (
136
+ sig,
137
+ code,
138
+ & primary_fn_name,
139
+ cfg_attributes,
140
+ ) ;
137
141
} else {
138
- ( TokenStream :: new ( ) , TokenStream :: new ( ) )
142
+ primary_fn_name = safe_ident ( rust_function_name_str) ;
143
+ default_fn_code = TokenStream :: new ( ) ;
144
+ default_structs_code = TokenStream :: new ( ) ;
139
145
} ;
140
146
141
147
let return_ty = & sig. return_value ( ) . type_tokens ( ) ;
@@ -189,6 +195,14 @@ pub fn make_function_definition(
189
195
// Note: all varargs functions are non-static, which is why there are some shortcuts in try_*() argument forwarding.
190
196
// This can be made more complex if ever necessary.
191
197
198
+ // A function() may call try_function(), its arguments should not have .as_object_arg().
199
+ let [ _, _, arg_names_without_asarg] = make_params_exprs (
200
+ sig. params ( ) . iter ( ) ,
201
+ false ,
202
+ !has_default_params, // For *_full function, we don't need impl AsObjectArg<T> parameters
203
+ false , // or arg.as_object_arg() calls.
204
+ ) ;
205
+
192
206
quote ! {
193
207
/// # Panics
194
208
/// This is a _varcall_ method, meaning parameters and return values are passed as `Variant`.
@@ -199,7 +213,7 @@ pub fn make_function_definition(
199
213
#( #params, ) *
200
214
varargs: & [ Variant ]
201
215
) #return_decl {
202
- Self :: #try_fn_name( self , #( #arg_names , ) * varargs)
216
+ Self :: #try_fn_name( self , #( #arg_names_without_asarg , ) * varargs)
203
217
. unwrap_or_else( |e| panic!( "{e}" ) )
204
218
}
205
219
@@ -278,19 +292,6 @@ pub fn make_receiver(qualifier: FnQualifier, ffi_arg_in: TokenStream) -> FnRecei
278
292
self_prefix,
279
293
}
280
294
}
281
-
282
- pub fn make_params_and_args ( method_args : & [ & FnParam ] ) -> ( Vec < TokenStream > , Vec < TokenStream > ) {
283
- method_args
284
- . iter ( )
285
- . map ( |param| {
286
- let param_name = & param. name ;
287
- let param_ty = & param. type_ ;
288
-
289
- ( quote ! { #param_name: #param_ty } , quote ! { #param_name } )
290
- } )
291
- . unzip ( )
292
- }
293
-
294
295
pub fn make_vis ( is_private : bool ) -> TokenStream {
295
296
if is_private {
296
297
quote ! { pub ( crate ) }
@@ -302,18 +303,50 @@ pub fn make_vis(is_private: bool) -> TokenStream {
302
303
// ----------------------------------------------------------------------------------------------------------------------------------------------
303
304
// Implementation
304
305
305
- fn make_params_exprs ( method_args : & [ FnParam ] ) -> [ Vec < TokenStream > ; 3 ] {
306
+ pub ( crate ) fn make_params_exprs < ' a > (
307
+ method_args : impl Iterator < Item = & ' a FnParam > ,
308
+ is_virtual : bool ,
309
+ param_is_impl_asarg : bool ,
310
+ arg_is_asarg : bool ,
311
+ ) -> [ Vec < TokenStream > ; 3 ] {
306
312
let mut params = vec ! [ ] ;
307
- let mut param_types = vec ! [ ] ;
313
+ let mut param_types = vec ! [ ] ; // or non-generic params
308
314
let mut arg_names = vec ! [ ] ;
309
315
310
- for param in method_args. iter ( ) {
316
+ for param in method_args {
311
317
let param_name = & param. name ;
312
318
let param_ty = & param. type_ ;
313
319
314
- params. push ( quote ! { #param_name: #param_ty } ) ;
315
- param_types. push ( quote ! { #param_ty } ) ;
316
- arg_names. push ( quote ! { #param_name } ) ;
320
+ // Objects (Gd<T>) use implicit conversions via AsObjectArg. Only use in non-virtual functions.
321
+ match & param. type_ {
322
+ RustTy :: EngineClass {
323
+ arg_view,
324
+ impl_as_arg,
325
+ ..
326
+ } if !is_virtual => {
327
+ // Parameter declarations in signature: impl AsObjectArg<T>
328
+ if param_is_impl_asarg {
329
+ params. push ( quote ! { #param_name: #impl_as_arg } ) ;
330
+ } else {
331
+ params. push ( quote ! { #param_name: #arg_view } ) ;
332
+ }
333
+
334
+ // Argument names in function body: arg.as_object_arg() vs. arg
335
+ if arg_is_asarg {
336
+ arg_names. push ( quote ! { #param_name. as_object_arg( ) } ) ;
337
+ } else {
338
+ arg_names. push ( quote ! { #param_name } ) ;
339
+ }
340
+
341
+ param_types. push ( quote ! { #arg_view } ) ;
342
+ }
343
+
344
+ _ => {
345
+ params. push ( quote ! { #param_name: #param_ty } ) ;
346
+ arg_names. push ( quote ! { #param_name } ) ;
347
+ param_types. push ( quote ! { #param_ty } ) ;
348
+ }
349
+ }
317
350
}
318
351
319
352
[ params, param_types, arg_names]
0 commit comments