diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index ea4908ef3f..ffca06f754 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -34,7 +34,7 @@ pub fn derive_bundle(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); let ecs_path = bevy_ecs_path(); - let named_fields = match get_struct_fields(&ast.data) { + let named_fields = match get_struct_fields(&ast.data, "derive(Bundle)") { Ok(fields) => fields, Err(e) => return e.into_compile_error().into(), }; @@ -191,12 +191,14 @@ pub fn derive_bundle(input: TokenStream) -> TokenStream { pub fn derive_map_entities(input: TokenStream) -> TokenStream { let ast = parse_macro_input!(input as DeriveInput); let ecs_path = bevy_ecs_path(); + let map_entities_impl = map_entities( &ast.data, Ident::new("self", Span::call_site()), false, false, ); + let struct_name = &ast.ident; let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl(); TokenStream::from(quote! { diff --git a/crates/bevy_macro_utils/src/shape.rs b/crates/bevy_macro_utils/src/shape.rs index 2d0124d62a..502738cb9b 100644 --- a/crates/bevy_macro_utils/src/shape.rs +++ b/crates/bevy_macro_utils/src/shape.rs @@ -1,24 +1,29 @@ -use proc_macro::Span; -use syn::{punctuated::Punctuated, token::Comma, Data, DataStruct, Error, Field, Fields}; +use syn::{ + punctuated::Punctuated, spanned::Spanned, token::Comma, Data, DataEnum, DataUnion, Error, + Field, Fields, +}; /// Get the fields of a data structure if that structure is a struct with named fields; /// otherwise, return a compile error that points to the site of the macro invocation. -pub fn get_struct_fields(data: &Data) -> syn::Result<&Punctuated> { +/// +/// `meta` should be the name of the macro calling this function. +pub fn get_struct_fields<'a>( + data: &'a Data, + meta: &str, +) -> syn::Result<&'a Punctuated> { match data { - Data::Struct(DataStruct { - fields: Fields::Named(fields), - .. - }) => Ok(&fields.named), - Data::Struct(DataStruct { - fields: Fields::Unnamed(fields), - .. - }) => Ok(&fields.unnamed), - _ => Err(Error::new( - // This deliberately points to the call site rather than the structure - // body; marking the entire body as the source of the error makes it - // impossible to figure out which `derive` has a problem. - Span::call_site().into(), - "Only structs are supported", + Data::Struct(data_struct) => match &data_struct.fields { + Fields::Named(fields_named) => Ok(&fields_named.named), + Fields::Unnamed(fields_unnamed) => Ok(&fields_unnamed.unnamed), + Fields::Unit => Ok(const { &Punctuated::new() }), + }, + Data::Enum(DataEnum { enum_token, .. }) => Err(Error::new( + enum_token.span(), + format!("#[{meta}] only supports structs, not enums"), + )), + Data::Union(DataUnion { union_token, .. }) => Err(Error::new( + union_token.span(), + format!("#[{meta}] only supports structs, not unions"), )), } }