Skip to content

Commit 4a95bbf

Browse files
committed
Allow modification of impl block by #[godot_api] proc-macro
1 parent b088305 commit 4a95bbf

File tree

1 file changed

+11
-4
lines changed

1 file changed

+11
-4
lines changed

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use proc_macro2::{Ident, TokenStream};
1313
use quote::{quote, ToTokens};
1414

1515
/// Codegen for `#[godot_api] impl ISomething for MyType`.
16-
pub fn transform_trait_impl(original_impl: venial::Impl) -> ParseResult<TokenStream> {
16+
pub fn transform_trait_impl(mut original_impl: venial::Impl) -> ParseResult<TokenStream> {
1717
let (class_name, trait_path, trait_base_class) =
1818
util::validate_trait_impl_virtual(&original_impl, "godot_api")?;
1919

@@ -26,7 +26,7 @@ pub fn transform_trait_impl(original_impl: venial::Impl) -> ParseResult<TokenStr
2626

2727
let mut decls = IDecls::default();
2828

29-
for item in original_impl.body_items.iter() {
29+
for item in original_impl.body_items.iter_mut() {
3030
let method = if let venial::ImplMember::AssocFunction(f) = item {
3131
f
3232
} else {
@@ -70,6 +70,9 @@ pub fn transform_trait_impl(original_impl: venial::Impl) -> ParseResult<TokenStr
7070
handle_property_get_revert(&class_name, &trait_path, cfg_attrs, &mut decls);
7171
}
7272
regular_virtual_fn => {
73+
// Break borrow chain to allow handle_regular_virtual_fn() to mutably borrow `method` and modify `original_impl` through it.
74+
let cfg_attrs = cfg_attrs.iter().cloned().collect();
75+
7376
// All the non-special engine ones: ready(), process(), etc.
7477
// Can modify original_impl, concretely the fn body for f64->f32 conversions.
7578
handle_regular_virtual_fn(
@@ -142,8 +145,8 @@ pub fn transform_trait_impl(original_impl: venial::Impl) -> ParseResult<TokenStr
142145
.iter()
143146
.map(|v| v.make_match_arm(&class_name));
144147

145-
let result = quote! {
146-
#original_impl
148+
let mut result = quote! {
149+
// #original_impl inserted below.
147150
#decls
148151

149152
impl ::godot::private::You_forgot_the_attribute__godot_api for #class_name {}
@@ -167,6 +170,10 @@ pub fn transform_trait_impl(original_impl: venial::Impl) -> ParseResult<TokenStr
167170
));
168171
};
169172

173+
// Not in upper quote!, because #decls still holds holds a mutable borrow to `original_impl`, so we can't also borrow `original_impl`
174+
// as immutable.
175+
original_impl.to_tokens(&mut result);
176+
170177
Ok(result)
171178
}
172179

0 commit comments

Comments
 (0)