@@ -118,24 +118,30 @@ pub fn make_function_definition(
118118 ( TokenStream :: new ( ) , TokenStream :: new ( ) )
119119 } ;
120120
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 ( ) . into_iter ( ) ,
123+ sig. is_virtual ( ) ,
124+ !has_default_params, // For *_full function, we don't need impl AsArg<T> parameters
125+ !has_default_params, // or arg.as_arg() calls.
126+ ) ;
122127
123128 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- } ;
129129
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+ ) ;
137141 } 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 ( ) ;
139145 } ;
140146
141147 let return_ty = & sig. return_value ( ) . type_tokens ( ) ;
@@ -189,6 +195,14 @@ pub fn make_function_definition(
189195 // Note: all varargs functions are non-static, which is why there are some shortcuts in try_*() argument forwarding.
190196 // This can be made more complex if ever necessary.
191197
198+ // A function() may call try_function(), its arguments should not have .as_arg().
199+ let [ _, _, arg_names_without_asarg] = make_params_exprs (
200+ sig. params ( ) . into_iter ( ) ,
201+ false ,
202+ !has_default_params, // For *_full function, we don't need impl AsArg<T> parameters
203+ false , // or arg.as_arg() calls.
204+ ) ;
205+
192206 quote ! {
193207 /// # Panics
194208 /// This is a _varcall_ method, meaning parameters and return values are passed as `Variant`.
@@ -199,7 +213,7 @@ pub fn make_function_definition(
199213 #( #params, ) *
200214 varargs: & [ Variant ]
201215 ) #return_decl {
202- Self :: #try_fn_name( self , #( #arg_names , ) * varargs)
216+ Self :: #try_fn_name( self , #( #arg_names_without_asarg , ) * varargs)
203217 . unwrap_or_else( |e| panic!( "{e}" ) )
204218 }
205219
@@ -278,19 +292,6 @@ pub fn make_receiver(qualifier: FnQualifier, ffi_arg_in: TokenStream) -> FnRecei
278292 self_prefix,
279293 }
280294}
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-
294295pub fn make_vis ( is_private : bool ) -> TokenStream {
295296 if is_private {
296297 quote ! { pub ( crate ) }
@@ -302,18 +303,50 @@ pub fn make_vis(is_private: bool) -> TokenStream {
302303// ----------------------------------------------------------------------------------------------------------------------------------------------
303304// Implementation
304305
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 ] {
306312 let mut params = vec ! [ ] ;
307- let mut param_types = vec ! [ ] ;
313+ let mut param_types = vec ! [ ] ; // or non-generic params
308314 let mut arg_names = vec ! [ ] ;
309315
310- for param in method_args. iter ( ) {
316+ for param in method_args {
311317 let param_name = & param. name ;
312318 let param_ty = & param. type_ ;
313319
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 AsArg. 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 AsArg<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_arg() vs. arg
335+ if arg_is_asarg {
336+ arg_names. push ( quote ! { #param_name. as_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+ }
317350 }
318351
319352 [ params, param_types, arg_names]
0 commit comments