@@ -988,11 +988,63 @@ fn make_virtual_method(class_method: &ClassMethod, ctx: &mut Context) -> TokenSt
988
988
// Virtual methods are never static.
989
989
assert ! ( !class_method. is_static) ;
990
990
991
- let receiver = make_receiver_self_param ( false , class_method. is_const ) ;
992
- let [ params, _, _, _] = make_params ( & class_method. arguments , class_method. is_vararg , ctx) ;
991
+ let [ params, variant_types, _, arg_names] =
992
+ make_params ( & class_method. arguments , class_method. is_vararg , ctx) ;
993
+
994
+ let is_varcall = class_method. is_vararg ;
995
+ let variant_ffi = is_varcall. then ( VariantFfi :: type_ptr) ;
996
+ let ( receiver, receiver_arg) = make_receiver (
997
+ class_method. is_static ,
998
+ class_method. is_const ,
999
+ quote ! { self . object_ptr } ,
1000
+ ) ;
1001
+ let varcall_invocation = quote ! {
1002
+ __call_fn( __method_bind, #receiver_arg, __args_ptr, __args. len( ) as i64 , return_ptr, std:: ptr:: addr_of_mut!( __err) ) ;
1003
+ } ;
1004
+ let ptrcall_invocation = quote ! {
1005
+ __call_fn( __method_bind, #receiver_arg, __args_ptr, return_ptr) ;
1006
+ } ;
1007
+
1008
+ let ( prepare_arg_types, error_fn_context) ;
1009
+ if variant_ffi. is_some ( ) {
1010
+ // varcall (using varargs)
1011
+ prepare_arg_types = quote ! {
1012
+ let mut __arg_types = Vec :: with_capacity( __explicit_args. len( ) + varargs. len( ) ) ;
1013
+ // __arg_types.extend(__explicit_args.iter().map(Variant::get_type));
1014
+ __arg_types. extend( varargs. iter( ) . map( Variant :: get_type) ) ;
1015
+ let __vararg_str = varargs. iter( ) . map( |v| format!( "{v}" ) ) . collect:: <Vec <_>>( ) . join( ", " ) ;
1016
+ } ;
1017
+
1018
+ let joined = arg_names
1019
+ . iter ( )
1020
+ . map ( |n| format ! ( "{{{n}:?}}" ) )
1021
+ . collect :: < Vec < _ > > ( )
1022
+ . join ( ", " ) ;
1023
+
1024
+ let fmt = format ! ( "{method_name}({joined}; {{__vararg_str}})" ) ;
1025
+ error_fn_context = quote ! { & format!( #fmt) } ;
1026
+ } else {
1027
+ // ptrcall
1028
+ prepare_arg_types = quote ! {
1029
+ let __arg_types = [
1030
+ #( #variant_types ) , *
1031
+ ] ;
1032
+ } ;
1033
+ error_fn_context = method_name. to_token_stream ( ) ;
1034
+ } ;
1035
+
1036
+ let ( return_value, _) = make_return (
1037
+ class_method. return_value . as_ref ( ) ,
1038
+ variant_ffi. as_ref ( ) ,
1039
+ & varcall_invocation,
1040
+ & ptrcall_invocation,
1041
+ prepare_arg_types,
1042
+ error_fn_context,
1043
+ ctx,
1044
+ ) ;
993
1045
994
1046
quote ! {
995
- fn #method_name ( #receiver #( #params , ) * ) {
1047
+ fn #method_name ( #receiver #( #params , ) * ) #return_value {
996
1048
unimplemented!( )
997
1049
}
998
1050
}
0 commit comments