@@ -20,8 +20,9 @@ pub fn derive_godot_class(item: venial::Item) -> ParseResult<TokenStream> {
2020 . as_struct ( )
2121 . ok_or_else ( || venial:: Error :: new ( "Not a valid struct" ) ) ?;
2222
23+ let named_fields = named_fields ( class) ?;
2324 let struct_cfg = parse_struct_attributes ( class) ?;
24- let fields = parse_fields ( class , struct_cfg. init_strategy ) ?;
25+ let fields = parse_fields ( named_fields , struct_cfg. init_strategy ) ?;
2526
2627 let class_name = & class. name ;
2728 let class_name_str: String = struct_cfg
@@ -292,9 +293,6 @@ fn parse_struct_attributes(class: &venial::Struct) -> ParseResult<ClassAttribute
292293 base_ty = base;
293294 }
294295
295- // #[class(rename = NewName)]
296- rename = parser. handle_ident ( "rename" ) ?;
297-
298296 // #[class(init)], #[class(no_init)]
299297 match handle_opposite_keys ( & mut parser, "init" , "class" ) ? {
300298 Some ( true ) => init_strategy = InitStrategy :: Generated ,
@@ -314,20 +312,25 @@ fn parse_struct_attributes(class: &venial::Struct) -> ParseResult<ClassAttribute
314312 is_editor_plugin = true ;
315313
316314 // Requires #[class(tool, base=EditorPlugin)].
317- if !is_tool {
315+ // The base=EditorPlugin check should come first to create the best compile errors since it's more complex to resolve.
316+ // See https://github.com/godot-rust/gdext/pull/773
317+ if base_ty != ident ( "EditorPlugin" ) {
318318 return bail ! (
319319 attr_key,
320- "#[class(editor_plugin)] requires additional key `tool `"
320+ "#[class(editor_plugin)] requires additional key-value `base=EditorPlugin `"
321321 ) ;
322322 }
323- if base_ty != ident ( "EditorPlugin" ) {
323+ if !is_tool {
324324 return bail ! (
325325 attr_key,
326- "#[class(editor_plugin)] requires additional key-value `base=EditorPlugin `"
326+ "#[class(editor_plugin)] requires additional key `tool `"
327327 ) ;
328328 }
329329 }
330330
331+ // #[class(rename = NewName)]
332+ rename = parser. handle_ident ( "rename" ) ?;
333+
331334 // #[class(hidden)]
332335 // TODO consider naming this "internal"; godot-cpp uses that terminology:
333336 // https://github.com/godotengine/godot-cpp/blob/master/include/godot_cpp/core/class_db.hpp#L327
@@ -349,22 +352,30 @@ fn parse_struct_attributes(class: &venial::Struct) -> ParseResult<ClassAttribute
349352 } )
350353}
351354
352- /// Returns field names and 1 base field, if available
353- fn parse_fields ( class : & venial:: Struct , init_strategy : InitStrategy ) -> ParseResult < Fields > {
354- let mut all_fields = vec ! [ ] ;
355- let mut base_field = Option :: < Field > :: None ;
356- let mut has_deprecated_base = false ;
357-
358- let named_fields: Vec < ( venial:: NamedField , Punct ) > = match & class. fields {
359- venial:: Fields :: Unit => {
360- vec ! [ ]
361- }
355+ /// Fetches data for all named fields for a struct.
356+ ///
357+ /// Errors if `class` is a tuple struct.
358+ fn named_fields ( class : & venial:: Struct ) -> ParseResult < Vec < ( venial:: NamedField , Punct ) > > {
359+ // This is separate from parse_fields to improve compile errors. The errors from here demand larger and more non-local changes from the API
360+ // user than those from parse_struct_attributes, so this must be run first.
361+ match & class. fields {
362+ venial:: Fields :: Unit => Ok ( vec ! [ ] ) ,
362363 venial:: Fields :: Tuple ( _) => bail ! (
363364 & class. fields,
364365 "#[derive(GodotClass)] not supported for tuple structs" ,
365366 ) ?,
366- venial:: Fields :: Named ( fields) => fields. fields . inner . clone ( ) ,
367- } ;
367+ venial:: Fields :: Named ( fields) => Ok ( fields. fields . inner . clone ( ) ) ,
368+ }
369+ }
370+
371+ /// Returns field names and 1 base field, if available.
372+ fn parse_fields (
373+ named_fields : Vec < ( venial:: NamedField , Punct ) > ,
374+ init_strategy : InitStrategy ,
375+ ) -> ParseResult < Fields > {
376+ let mut all_fields = vec ! [ ] ;
377+ let mut base_field = Option :: < Field > :: None ;
378+ let mut has_deprecated_base = false ;
368379
369380 // Attributes on struct fields
370381 for ( named_field, _punct) in named_fields {
0 commit comments