@@ -148,6 +148,7 @@ pub fn derive_godot_class(item: venial::Item) -> ParseResult<TokenStream> {
148
148
// Note: one limitation is that macros don't work for `impl nested::MyClass` blocks.
149
149
let visibility_macro = make_visibility_macro ( class_name, class. vis_marker . as_ref ( ) ) ;
150
150
let base_field_macro = make_base_field_macro ( class_name, fields. base_field . is_some ( ) ) ;
151
+ let deny_manual_init_macro = make_deny_manual_init_macro ( class_name, struct_cfg. init_strategy ) ;
151
152
152
153
Ok ( quote ! {
153
154
impl :: godot:: obj:: GodotClass for #class_name {
@@ -180,6 +181,7 @@ pub fn derive_godot_class(item: venial::Item) -> ParseResult<TokenStream> {
180
181
#init_expecter
181
182
#visibility_macro
182
183
#base_field_macro
184
+ #deny_manual_init_macro
183
185
#( #deprecations ) *
184
186
#( #errors ) *
185
187
@@ -236,6 +238,35 @@ fn make_base_field_macro(class_name: &Ident, has_base_field: bool) -> TokenStrea
236
238
}
237
239
}
238
240
241
+ /// Generates code for a decl-macro that prevents manual `init()` for incompatible init strategies.
242
+ fn make_deny_manual_init_macro ( class_name : & Ident , init_strategy : InitStrategy ) -> TokenStream {
243
+ let macro_name = util:: format_class_deny_manual_init_macro ( class_name) ;
244
+
245
+ let class_attr = match init_strategy {
246
+ InitStrategy :: Absent => "#[class(no_init)]" ,
247
+ InitStrategy :: Generated => "#[class(init)]" ,
248
+ InitStrategy :: UserDefined => {
249
+ // For classes that expect manual init, do nothing.
250
+ return quote ! {
251
+ macro_rules! #macro_name {
252
+ ( ) => { } ;
253
+ }
254
+ } ;
255
+ }
256
+ } ;
257
+
258
+ let error_message =
259
+ format ! ( "Class `{class_name}` is marked with {class_attr} but provides an init() method." ) ;
260
+
261
+ quote ! {
262
+ macro_rules! #macro_name {
263
+ ( ) => {
264
+ compile_error!( #error_message) ;
265
+ } ;
266
+ }
267
+ }
268
+ }
269
+
239
270
/// Checks at compile time that a function with the given name exists on `Self`.
240
271
#[ must_use]
241
272
pub fn make_existence_check ( ident : & Ident ) -> TokenStream {
0 commit comments