diff --git a/crates/bevy_ecs/macros/src/component.rs b/crates/bevy_ecs/macros/src/component.rs index 00268cb680050..16e75f9b6bb18 100644 --- a/crates/bevy_ecs/macros/src/component.rs +++ b/crates/bevy_ecs/macros/src/component.rs @@ -92,12 +92,15 @@ pub fn derive_component(input: TokenStream) -> TokenStream { Err(err) => err.into_compile_error().into(), }; - let map_entities = map_entities( + let map_entities = match map_entities( &ast.data, Ident::new("this", Span::call_site()), relationship.is_some(), relationship_target.is_some(), - ).map(|map_entities_impl| quote! { + ) { + Ok(map) => map, + Err(err) => return err.into_compile_error().into() + }.map(|map_entities_impl| quote! { fn map_entities(this: &mut Self, mapper: &mut M) { use #bevy_ecs_path::entity::MapEntities; #map_entities_impl @@ -308,7 +311,7 @@ pub(crate) fn map_entities( self_ident: Ident, is_relationship: bool, is_relationship_target: bool, -) -> Option { +) -> Result> { match data { Data::Struct(DataStruct { fields, .. }) => { let mut map = Vec::with_capacity(fields.len()); @@ -334,16 +337,23 @@ pub(crate) fn map_entities( map.push(quote!(#self_ident.#field_member.map_entities(mapper);)); }); if map.is_empty() { - return None; + return Ok(None); }; - Some(quote!( + Ok(Some(quote!( #(#map)* - )) + ))) } Data::Enum(DataEnum { variants, .. }) => { let mut map = Vec::with_capacity(variants.len()); for variant in variants.iter() { + if let Some(attr) = variant.attrs.iter().find(|a| a.path().is_ident(ENTITIES)) { + return Err(syn::Error::new( + attr.span(), + "`#[entities]` should be on the associated type, not on the variant.", + )); + } + let field_members = variant .fields .iter() @@ -371,17 +381,17 @@ pub(crate) fn map_entities( } if map.is_empty() { - return None; + return Ok(None); }; - Some(quote!( + Ok(Some(quote!( match #self_ident { #(#map,)* _ => {} } - )) + ))) } - Data::Union(_) => None, + Data::Union(_) => Ok(None), } } diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index 114aff642b58c..f07b4a3c3fbf4 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -191,13 +191,15 @@ 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( + let map_entities_impl = match map_entities( &ast.data, Ident::new("self", Span::call_site()), false, false, - ); + ) { + Ok(map) => map, + Err(err) => return err.into_compile_error().into(), + }; let struct_name = &ast.ident; let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl();