1- use syn:: { spanned:: Spanned , FnArg , ImplItem , ItemImpl , Pat , PatIdent , Signature , Type } ;
1+ use syn:: { spanned:: Spanned , FnArg , Generics , ImplItem , ItemImpl , Pat , PatIdent , Signature , Type } ;
22
33use proc_macro2:: TokenStream as TokenStream2 ;
44use quote:: { quote, ToTokens } ;
@@ -330,6 +330,7 @@ pub(crate) struct ExportArgs {
330330pub ( crate ) fn derive_methods ( item_impl : ItemImpl ) -> TokenStream2 {
331331 let derived = crate :: automatically_derived ( ) ;
332332 let ( impl_block, export) = impl_gdnative_expose ( item_impl) ;
333+ let ( impl_generics, _, where_clause) = impl_block. generics . split_for_impl ( ) ;
333334
334335 let class_name = export. class_ty ;
335336
@@ -390,7 +391,7 @@ pub(crate) fn derive_methods(item_impl: ItemImpl) -> TokenStream2 {
390391 quote_spanned ! ( ret_span=>)
391392 } ;
392393
393- let method = wrap_method ( & class_name, & export_method)
394+ let method = wrap_method ( & class_name, & impl_block . generics , & export_method)
394395 . unwrap_or_else ( |err| err. to_compile_error ( ) ) ;
395396
396397 quote_spanned ! ( sig_span=>
@@ -410,7 +411,7 @@ pub(crate) fn derive_methods(item_impl: ItemImpl) -> TokenStream2 {
410411 #impl_block
411412
412413 #derived
413- impl gdnative:: export:: NativeClassMethods for #class_name {
414+ impl #impl_generics gdnative:: export:: NativeClassMethods for #class_name #where_clause {
414415 fn nativeclass_register( #builder: & :: gdnative:: export:: ClassBuilder <Self >) {
415416 use gdnative:: export:: * ;
416417
@@ -767,11 +768,17 @@ pub(crate) fn expand_godot_wrap_method(
767768 return Err ( errors) ;
768769 }
769770
770- wrap_method ( & class_name, & export_method. expect ( "ExportMethod is valid" ) ) . map_err ( |e| vec ! [ e] )
771+ wrap_method (
772+ & class_name,
773+ & Generics :: default ( ) ,
774+ & export_method. expect ( "ExportMethod is valid" ) ,
775+ )
776+ . map_err ( |e| vec ! [ e] )
771777}
772778
773779fn wrap_method (
774780 class_name : & Type ,
781+ generics : & Generics ,
775782 export_method : & ExportMethod ,
776783) -> Result < TokenStream2 , syn:: Error > {
777784 let ExportMethod {
@@ -783,6 +790,21 @@ fn wrap_method(
783790 let gdnative_core = crate :: crate_gdnative_core ( ) ;
784791 let automatically_derived = crate :: automatically_derived ( ) ;
785792
793+ let ( impl_generics, ty_generics, where_clause) = generics. split_for_impl ( ) ;
794+ let turbofish_ty_generics = ty_generics. as_turbofish ( ) ;
795+
796+ let generic_marker_decl = if generics. params . is_empty ( ) {
797+ quote ! ( ( ) )
798+ } else {
799+ quote ! ( core:: marker:: PhantomData #ty_generics)
800+ } ;
801+
802+ let generic_marker_ctor = if generics. params . is_empty ( ) {
803+ quote ! ( ( ) )
804+ } else {
805+ quote ! ( core:: marker:: PhantomData )
806+ } ;
807+
786808 let sig_span = sig. ident . span ( ) ;
787809 let ret_span = sig. output . span ( ) ;
788810
@@ -875,8 +897,8 @@ fn wrap_method(
875897
876898 quote_spanned ! { sig_span =>
877899 #automatically_derived
878- impl #gdnative_async:: StaticArgsAsyncMethod <#class_name> for ThisMethod {
879- type Args = Args ;
900+ impl #impl_generics # gdnative_async:: StaticArgsAsyncMethod <#class_name> for ThisMethod #ty_generics #where_clause {
901+ type Args = Args #ty_generics ;
880902
881903 fn spawn_with(
882904 & self ,
@@ -885,7 +907,7 @@ fn wrap_method(
885907 __spawner. spawn( move |__ctx, __this, __args| {
886908 let __future = __this
887909 . #map_method( move |__rust_val, __base| {
888- let Args { #( #destructure_arg_list, ) * } = __args;
910+ let Args { #( #destructure_arg_list, ) * __generic_marker } = __args;
889911
890912 #[ allow( unused_unsafe) ]
891913 unsafe {
@@ -916,17 +938,19 @@ fn wrap_method(
916938 }
917939 }
918940
919- #gdnative_async:: Async :: new( #gdnative_async:: StaticArgs :: new( ThisMethod ) )
941+ #gdnative_async:: Async :: new( #gdnative_async:: StaticArgs :: new( ThisMethod #turbofish_ty_generics {
942+ _marker: #generic_marker_ctor,
943+ } ) )
920944 }
921945 } else {
922946 quote_spanned ! { sig_span =>
923947 #automatically_derived
924- impl #gdnative_core:: export:: StaticArgsMethod <#class_name> for ThisMethod {
925- type Args = Args ;
948+ impl #impl_generics # gdnative_core:: export:: StaticArgsMethod <#class_name> for ThisMethod #ty_generics #where_clause {
949+ type Args = Args #ty_generics ;
926950 fn call(
927951 & self ,
928952 __this: TInstance <' _, #class_name, #gdnative_core:: object:: ownership:: Shared >,
929- Args { #( #destructure_arg_list, ) * } : Args ,
953+ Args { #( #destructure_arg_list, ) * __generic_marker } : Self :: Args ,
930954 ) -> #gdnative_core:: core_types:: Variant {
931955 __this
932956 . #map_method( |__rust_val, __base| {
@@ -950,23 +974,48 @@ fn wrap_method(
950974 }
951975 }
952976
953- #gdnative_core:: export:: StaticArgs :: new( ThisMethod )
977+ #gdnative_core:: export:: StaticArgs :: new( ThisMethod #turbofish_ty_generics {
978+ _marker: #generic_marker_ctor,
979+ } )
954980 }
955981 } ;
956982
983+ // Necessary standard traits have to be implemented manually because the default derive isn't smart enough.
957984 let output = quote_spanned ! { sig_span =>
958985 {
959- #[ derive( Copy , Clone , Default ) ]
960- struct ThisMethod ;
986+ struct ThisMethod #ty_generics #where_clause {
987+ _marker: #generic_marker_decl,
988+ }
989+
990+ impl #impl_generics Copy for ThisMethod #ty_generics #where_clause { }
991+ impl #impl_generics Clone for ThisMethod #ty_generics #where_clause {
992+ fn clone( & self ) -> Self {
993+ * self
994+ }
995+ }
996+
997+ impl #impl_generics Default for ThisMethod #ty_generics #where_clause {
998+ fn default ( ) -> Self {
999+ Self {
1000+ _marker: #generic_marker_ctor,
1001+ }
1002+ }
1003+ }
1004+
1005+ unsafe impl #impl_generics Send for ThisMethod #ty_generics #where_clause { }
1006+ unsafe impl #impl_generics Sync for ThisMethod #ty_generics #where_clause { }
9611007
9621008 use #gdnative_core:: export:: { NativeClass , OwnerArg } ;
9631009 use #gdnative_core:: object:: { Instance , TInstance } ;
9641010 use #gdnative_core:: derive:: FromVarargs ;
9651011
9661012 #[ derive( FromVarargs ) ]
9671013 #automatically_derived
968- struct Args {
1014+ struct Args #ty_generics #where_clause {
9691015 #( #declare_arg_list, ) *
1016+
1017+ #[ skip]
1018+ __generic_marker: #generic_marker_decl,
9701019 }
9711020
9721021 #impl_body
0 commit comments