Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bevy_reflect: Fix ignored/skipped field order #7575

Merged
merged 5 commits into from
Oct 22, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Improve reflection hygiene
Wrap impl-only macros inside unnamed constants.
  • Loading branch information
MrGVSV committed Oct 21, 2023
commit 973a147b1d26cb431d8fc75f8a7e64be1e77b60b
87 changes: 63 additions & 24 deletions crates/bevy_reflect/bevy_reflect_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`].
Expand All @@ -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.
Expand Down Expand Up @@ -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
};
})
}

Expand Down Expand Up @@ -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(
Expand All @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
};
})
}
Loading