@@ -302,11 +302,7 @@ fn make_forwarding_closure(
302302 _ => unreachable ! ( "unexpected receiver type" ) , // checked above.
303303 } ;
304304
305- let rust_sig_name = format_ident ! ( "Sig_{method_name}" ) ;
306-
307- sig_tuple_annotation = quote ! {
308- : :: godot:: private:: virtuals:: #trait_base_class:: #rust_sig_name
309- } ;
305+ sig_tuple_annotation = make_sig_tuple_annotation ( trait_base_class, method_name) ;
310306
311307 let method_invocation = TokenStream :: from_iter (
312308 quote ! { <#class_name as #interface_trait>:: #method_name}
@@ -346,10 +342,17 @@ fn make_forwarding_closure(
346342 ReceiverType :: GdSelf => {
347343 // Method call is always present, since GdSelf implies that the user declares the method.
348344 // (Absent method is only used in the case of a generated default virtual method, e.g. for ready()).
345+
346+ let sig_tuple_annotation = if interface_trait. is_some ( ) {
347+ make_sig_tuple_annotation ( trait_base_class, method_name)
348+ } else {
349+ TokenStream :: new ( )
350+ } ;
351+
349352 quote ! {
350353 |instance_ptr, params| {
351354 // Not using `virtual_sig`, since virtual methods with `#[func(gd_self)]` are being moved out of the trait to inherent impl.
352- let #params_tuple = #param_ident;
355+ let #params_tuple #sig_tuple_annotation = #param_ident;
353356
354357 let storage =
355358 unsafe { :: godot:: private:: as_storage:: <#class_name>( instance_ptr) } ;
@@ -637,6 +640,19 @@ fn make_call_context(class_name_str: &str, method_name_str: &str) -> TokenStream
637640 }
638641}
639642
643+ /// Returns a type annotation for the tuple corresponding to the signature declared on given ITrait method,
644+ /// allowing to validate params for a generated method call at compile time.
645+ ///
646+ /// For example `::godot::private::virtuals::Node::Sig_physics_process` is `(f64, )`,
647+ /// thus `let params: ::godot::private::virtuals::Node::Sig_physics_process = ();`
648+ /// will not compile.
649+ fn make_sig_tuple_annotation ( trait_base_class : & Ident , method_name : & Ident ) -> TokenStream {
650+ let rust_sig_name = format_ident ! ( "Sig_{method_name}" ) ;
651+ quote ! {
652+ : :: godot:: private:: virtuals:: #trait_base_class:: #rust_sig_name
653+ }
654+ }
655+
640656pub fn bail_attr < R > ( attr_name : & Ident , msg : & str , method_name : & Ident ) -> ParseResult < R > {
641657 bail ! ( method_name, "#[{attr_name}]: {msg}" )
642658}
0 commit comments