diff --git a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs index 03ef4f2668aaa..e87d3ccf5c8d3 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs +++ b/crates/bevy_reflect/bevy_reflect_derive/src/lib.rs @@ -244,15 +244,20 @@ pub fn derive_from_reflect(input: TokenStream) -> TokenStream { Err(err) => return err.into_compile_error().into(), }; - match derive_data { + let from_reflect_impl = match derive_data { ReflectDerive::Struct(struct_data) | ReflectDerive::UnitStruct(struct_data) => { from_reflect::impl_struct(&struct_data) } ReflectDerive::TupleStruct(struct_data) => from_reflect::impl_tuple_struct(&struct_data), ReflectDerive::Enum(meta) => from_reflect::impl_enum(&meta), ReflectDerive::Value(meta) => from_reflect::impl_value(&meta), - } - .into() + }; + + TokenStream::from(quote! { + const _: () = { + #from_reflect_impl + }; + }) } /// Derives the `TypePath` trait, providing a stable alternative to [`std::any::type_name`]. @@ -278,21 +283,31 @@ pub fn derive_type_path(input: TokenStream) -> TokenStream { Err(err) => return err.into_compile_error().into(), }; - impls::impl_type_path( + let type_path_impl = impls::impl_type_path( derive_data.meta(), // Use `WhereClauseOptions::new_value` here so we don't enforce reflection bounds &WhereClauseOptions::new_value(derive_data.meta()), - ) - .into() + ); + + TokenStream::from(quote! { + const _: () = { + #type_path_impl + }; + }) } // From https://github.com/randomPoison/type-uuid #[proc_macro_derive(TypeUuid, attributes(uuid))] pub fn derive_type_uuid(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as DeriveInput); - type_uuid::type_uuid_derive(input) - .unwrap_or_else(syn::Error::into_compile_error) - .into() + let uuid_impl = + type_uuid::type_uuid_derive(input).unwrap_or_else(syn::Error::into_compile_error); + + TokenStream::from(quote! { + const _: () = { + #uuid_impl + }; + }) } /// A macro that automatically generates type data for traits, which their implementors can then register. @@ -404,8 +419,10 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream { let from_reflect_impl = from_reflect::impl_value(&meta); TokenStream::from(quote! { - #reflect_impls - #from_reflect_impl + const _: () = { + #reflect_impls + #from_reflect_impl + }; }) } @@ -449,7 +466,7 @@ pub fn impl_reflect_struct(input: TokenStream) -> TokenStream { Err(err) => return err.into_compile_error().into(), }; - match derive_data { + let output = match derive_data { ReflectDerive::Struct(struct_data) => { if !struct_data.meta().type_path().has_custom_path() { return syn::Error::new( @@ -463,27 +480,30 @@ pub fn impl_reflect_struct(input: TokenStream) -> TokenStream { let impl_struct = impls::impl_struct(&struct_data); let impl_from_struct = from_reflect::impl_struct(&struct_data); - TokenStream::from(quote! { + quote! { #impl_struct #impl_from_struct - }) + } } ReflectDerive::TupleStruct(..) => syn::Error::new( ast.span(), "impl_reflect_struct does not support tuple structs", ) - .into_compile_error() - .into(), + .into_compile_error(), ReflectDerive::UnitStruct(..) => syn::Error::new( ast.span(), "impl_reflect_struct does not support unit structs", ) - .into_compile_error() - .into(), + .into_compile_error(), _ => syn::Error::new(ast.span(), "impl_reflect_struct only supports structs") - .into_compile_error() - .into(), - } + .into_compile_error(), + }; + + TokenStream::from(quote! { + const _: () = { + #output + }; + }) } /// A macro used to generate a `FromReflect` trait implementation for the given type. @@ -524,7 +544,14 @@ pub fn impl_from_reflect_value(input: TokenStream) -> TokenStream { } }; - from_reflect::impl_value(&ReflectMeta::new(type_path, def.traits.unwrap_or_default())).into() + let from_reflect_impl = + from_reflect::impl_value(&ReflectMeta::new(type_path, def.traits.unwrap_or_default())); + + TokenStream::from(quote! { + const _: () = { + #from_reflect_impl + }; + }) } /// A replacement for [deriving `TypePath`] for use on foreign types. @@ -586,12 +613,24 @@ pub fn impl_type_path(input: TokenStream) -> TokenStream { let meta = ReflectMeta::new(type_path, ReflectTraits::default()); - impls::impl_type_path(&meta, &WhereClauseOptions::new_value(&meta)).into() + let type_path_impl = impls::impl_type_path(&meta, &WhereClauseOptions::new_value(&meta)); + + TokenStream::from(quote! { + const _: () = { + #type_path_impl + }; + }) } /// Derives `TypeUuid` for the given type. This is used internally to implement `TypeUuid` on foreign types, such as those in the std. This macro should be used in the format of `<[Generic Params]> [Type (Path)], [Uuid (String Literal)]`. #[proc_macro] pub fn impl_type_uuid(input: TokenStream) -> TokenStream { let def = parse_macro_input!(input as type_uuid::TypeUuidDef); - type_uuid::gen_impl_type_uuid(def).into() + let uuid_impl = type_uuid::gen_impl_type_uuid(def); + + TokenStream::from(quote! { + const _: () = { + #uuid_impl + }; + }) }