diff --git a/crates/bevy_ecs/examples/derive_label.rs b/crates/bevy_ecs/examples/derive_label.rs index 573b42dc8153d7..5ace3567db3739 100644 --- a/crates/bevy_ecs/examples/derive_label.rs +++ b/crates/bevy_ecs/examples/derive_label.rs @@ -18,6 +18,14 @@ fn main() { GenericLabel::::One.as_label(), GenericLabel::::One.as_label(), ); + + assert_eq!(format!("{:?}", UnitLabel.as_label()), "UnitLabel"); + assert_eq!(format!("{:?}", WeirdLabel(1).as_label()), "WeirdLabel"); + assert_eq!(format!("{:?}", WeirdLabel(2).as_label()), "WeirdLabel"); + assert_eq!( + format!("{:?}", GenericLabel::::One.as_label()), + "GenericLabel::One::" + ); } #[derive(SystemLabel)] diff --git a/crates/bevy_ecs/src/schedule/state.rs b/crates/bevy_ecs/src/schedule/state.rs index 61d3a458b2a132..0cd2dde1d567ad 100644 --- a/crates/bevy_ecs/src/schedule/state.rs +++ b/crates/bevy_ecs/src/schedule/state.rs @@ -1,4 +1,5 @@ use crate::{ + self as bevy_ecs, schedule::{ RunCriteriaDescriptor, RunCriteriaDescriptorCoercion, RunCriteriaLabel, ShouldRun, SystemSet, @@ -52,20 +53,9 @@ enum ScheduledOperation { Push(T), } +#[derive(RunCriteriaLabel)] +#[run_criteria_label(ignore_fields)] struct DriverLabel(PhantomData T>); -impl RunCriteriaLabel for DriverLabel { - #[inline] - fn type_id(&self) -> std::any::TypeId { - std::any::TypeId::of::() - } - #[inline] - fn data(&self) -> u64 { - 0 - } - fn fmt(data: u64, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{}", std::any::type_name::()) - } -} fn driver_label() -> DriverLabel { DriverLabel(PhantomData) diff --git a/crates/bevy_macro_utils/src/lib.rs b/crates/bevy_macro_utils/src/lib.rs index 82c6cb38c6ce5d..4ecbf6af7def36 100644 --- a/crates/bevy_macro_utils/src/lib.rs +++ b/crates/bevy_macro_utils/src/lib.rs @@ -141,7 +141,7 @@ pub fn derive_label( .predicates .push(syn::parse2(quote! { Self: 'static }).unwrap()); - let (data, fmt) = match input.data { + let (data, mut fmt) = match input.data { syn::Data::Struct(d) => { // see if the user tried to ignore fields incorrectly if let Some(attr) = d @@ -226,6 +226,27 @@ pub fn derive_label( } }; + // Formatting for generics + let mut ty_args = input.generics.params.iter().filter_map(|p| match p { + syn::GenericParam::Type(ty) => Some({ + let ty = &ty.ident; + quote! { ::std::any::type_name::<#ty>() } + }), + _ => None, + }); + if let Some(first_arg) = ty_args.next() { + // Note: We're doing this manually instead of using magic `syn` methods, + // because those methods insert ugly whitespace everywhere. + // Those are for codegen, not user-facing formatting. + fmt = quote! { + ( #fmt )?; + write!(f, "::<")?; + write!(f, "{}", #first_arg)?; + #( write!(f, ", {}", #ty_args)?; )* + write!(f, ">") + } + } + (quote! { impl #impl_generics #trait_path for #ident #ty_generics #where_clause { #[inline]