Skip to content

Commit 8ad4daf

Browse files
authored
Merge pull request #1382 from Yarwin/bugfix/validate-call-params-for-gd-self-methods
Validate call params for `gd_self` virtual methods.
2 parents f025bd7 + 81dfc9a commit 8ad4daf

File tree

1 file changed

+22
-6
lines changed
  • godot-macros/src/class/data_models

1 file changed

+22
-6
lines changed

godot-macros/src/class/data_models/func.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
640656
pub 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

Comments
 (0)