Skip to content

Commit fdd5527

Browse files
committed
Add support for assoc items
- Check types for associated impl
1 parent 40186f3 commit fdd5527

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

godot-macros/src/class/godot_dyn.rs

+24-6
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,24 @@ pub fn attribute_godot_dyn(input_decl: venial::Item) -> ParseResult<TokenStream>
3232
);
3333
};
3434

35+
let mut associated_types = vec![];
36+
for impl_member in &decl.body_items {
37+
let venial::ImplMember::AssocType(associated_type) = impl_member else {
38+
continue;
39+
};
40+
let Some(type_expr) = &associated_type.initializer_ty else {
41+
continue;
42+
};
43+
let type_name = &associated_type.name;
44+
associated_types.push(quote! { #type_name = #type_expr })
45+
}
46+
47+
let associated_impl = if associated_types.is_empty() {
48+
None
49+
} else {
50+
Some(quote! { <#(#associated_types, )*>})
51+
};
52+
3553
let class_path = &decl.self_ty;
3654
let class_name_obj = util::class_name_obj(class_path); //&util::extract_typename(class_path));
3755
let prv = quote! { ::godot::private };
@@ -41,25 +59,25 @@ pub fn attribute_godot_dyn(input_decl: venial::Item) -> ParseResult<TokenStream>
4159
let new_code = quote! {
4260
#decl
4361

44-
impl ::godot::obj::AsDyn<dyn #trait_path> for #class_path {
45-
fn dyn_upcast(&self) -> &(dyn #trait_path + 'static) {
62+
impl ::godot::obj::AsDyn<dyn #trait_path #associated_impl> for #class_path {
63+
fn dyn_upcast(&self) -> &(dyn #trait_path #associated_impl + 'static) {
4664
self
4765
}
4866

49-
fn dyn_upcast_mut(&mut self) -> &mut (dyn #trait_path + 'static) {
67+
fn dyn_upcast_mut(&mut self) -> &mut (dyn #trait_path #associated_impl + 'static) {
5068
self
5169
}
5270
}
5371

5472
::godot::sys::plugin_add!(__GODOT_PLUGIN_REGISTRY in #prv; #prv::ClassPlugin {
5573
class_name: #class_name_obj,
5674
item: #prv::PluginItem::DynTraitImpl {
57-
dyn_trait_typeid: std::any::TypeId::of::<dyn #trait_path>(),
75+
dyn_trait_typeid: std::any::TypeId::of::<dyn #trait_path #associated_impl>(),
5876
erased_dynify_fn: {
5977
fn dynify_fn(obj: ::godot::obj::Gd<::godot::classes::Object>) -> #prv::ErasedDynGd {
6078
// SAFETY: runtime class type is statically known here and linked to the `class_name` field of the plugin.
6179
let obj = unsafe { obj.try_cast::<#class_path>().unwrap_unchecked() };
62-
let obj = obj.into_dyn::<dyn #trait_path>();
80+
let obj = obj.into_dyn::<dyn #trait_path #associated_impl>();
6381
let obj = obj.upcast::<::godot::classes::Object>();
6482

6583
#prv::ErasedDynGd {
@@ -76,4 +94,4 @@ pub fn attribute_godot_dyn(input_decl: venial::Item) -> ParseResult<TokenStream>
7694
};
7795

7896
Ok(new_code)
79-
}
97+
}

0 commit comments

Comments
 (0)