Skip to content

Commit

Permalink
Fixed bounds for normal FromReflect derive
Browse files Browse the repository at this point in the history
  • Loading branch information
MrGVSV committed Jun 18, 2023
1 parent 56d11a2 commit 95cb9e3
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,10 @@ pub(crate) struct ReflectTraits {
}

impl ReflectTraits {
pub fn from_metas(metas: Punctuated<Meta, Comma>) -> Result<Self, syn::Error> {
pub fn from_metas(
metas: Punctuated<Meta, Comma>,
is_from_reflect_derive: bool,
) -> Result<Self, syn::Error> {
let mut traits = ReflectTraits::default();
for meta in &metas {
match meta {
Expand Down Expand Up @@ -245,7 +248,14 @@ impl ReflectTraits {
syn::Expr::Lit(syn::ExprLit {
lit: syn::Lit::Bool(lit),
..
}) => Some(lit.clone()),
}) => {
// Overrride `lit` if this is a `FromReflect` derive.
// This typically means a user is opting out of the default implementation
// from the `Reflect` derive and using the `FromReflect` derive directly instead.
is_from_reflect_derive
.then(|| LitBool::new(true, Span::call_site()))
.or_else(|| Some(lit.clone()))
}
_ => {
return Err(syn::Error::new(
pair.value.span(),
Expand Down Expand Up @@ -366,7 +376,7 @@ impl ReflectTraits {

impl Parse for ReflectTraits {
fn parse(input: ParseStream) -> syn::Result<Self> {
ReflectTraits::from_metas(Punctuated::<Meta, Comma>::parse_terminated(input)?)
ReflectTraits::from_metas(Punctuated::<Meta, Comma>::parse_terminated(input)?, false)
}
}

Expand Down
7 changes: 6 additions & 1 deletion crates/bevy_reflect/bevy_reflect_derive/src/derive_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,10 @@ enum ReflectMode {
}

impl<'a> ReflectDerive<'a> {
pub fn from_input(input: &'a DeriveInput) -> Result<Self, syn::Error> {
pub fn from_input(
input: &'a DeriveInput,
is_from_reflect_derive: bool,
) -> Result<Self, syn::Error> {
let mut traits = ReflectTraits::default();
// Should indicate whether `#[reflect_value]` was used.
let mut reflect_mode = None;
Expand All @@ -159,6 +162,7 @@ impl<'a> ReflectDerive<'a> {
reflect_mode = Some(ReflectMode::Normal);
let new_traits = ReflectTraits::from_metas(
meta_list.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)?,
is_from_reflect_derive,
)?;
traits.merge(new_traits)?;
}
Expand All @@ -173,6 +177,7 @@ impl<'a> ReflectDerive<'a> {
reflect_mode = Some(ReflectMode::Value);
let new_traits = ReflectTraits::from_metas(
meta_list.parse_args_with(Punctuated::<Meta, Comma>::parse_terminated)?,
is_from_reflect_derive,
)?;
traits.merge(new_traits)?;
}
Expand Down
8 changes: 4 additions & 4 deletions crates/bevy_reflect/bevy_reflect_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ pub(crate) static TYPE_NAME_ATTRIBUTE_NAME: &str = "type_name";
pub fn derive_reflect(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);

let derive_data = match ReflectDerive::from_input(&ast) {
let derive_data = match ReflectDerive::from_input(&ast, false) {
Ok(data) => data,
Err(err) => return err.into_compile_error().into(),
};
Expand Down Expand Up @@ -232,7 +232,7 @@ pub fn derive_reflect(input: TokenStream) -> TokenStream {
pub fn derive_from_reflect(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);

let derive_data = match ReflectDerive::from_input(&ast) {
let derive_data = match ReflectDerive::from_input(&ast, true) {
Ok(data) => data,
Err(err) => return err.into_compile_error().into(),
};
Expand Down Expand Up @@ -266,7 +266,7 @@ pub fn derive_from_reflect(input: TokenStream) -> TokenStream {
#[proc_macro_derive(TypePath, attributes(type_path, type_name))]
pub fn derive_type_path(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let derive_data = match ReflectDerive::from_input(&ast) {
let derive_data = match ReflectDerive::from_input(&ast, false) {
Ok(data) => data,
Err(err) => return err.into_compile_error().into(),
};
Expand Down Expand Up @@ -434,7 +434,7 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
#[proc_macro]
pub fn impl_reflect_struct(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
let derive_data = match ReflectDerive::from_input(&ast) {
let derive_data = match ReflectDerive::from_input(&ast, false) {
Ok(data) => data,
Err(err) => return err.into_compile_error().into(),
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy_reflect::Reflect;
use bevy_reflect::{FromReflect, Reflect};

// Reason: Cannot have conflicting `from_reflect` attributes
#[derive(Reflect)]
Expand All @@ -16,4 +16,10 @@ struct Bar {
value: String,
}

// Reason: Conflicting `FromReflect` implementations
#[derive(Reflect, FromReflect)]
struct Baz {
value: String,
}

fn main() {}
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,13 @@ error: `from_reflect` already set to true
|
14 | #[reflect(from_reflect = false)]
| ^^^^^

error[E0119]: conflicting implementations of trait `FromReflect` for type `Baz`
--> tests/reflect_derive/from_reflect.fail.rs:20:19
|
20 | #[derive(Reflect, FromReflect)]
| ------- ^^^^^^^^^^^ conflicting implementation for `Baz`
| |
| first implementation here
|
= note: this error originates in the derive macro `FromReflect` (in Nightly builds, run with -Z macro-backtrace for more info)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy_reflect::Reflect;
use bevy_reflect::{FromReflect, Reflect};

#[derive(Reflect)]
#[reflect(from_reflect = false)]
Expand All @@ -14,4 +14,10 @@ struct Bar {
value: String,
}

#[derive(Reflect, FromReflect)]
#[reflect(from_reflect = false)]
struct Baz {
value: String,
}

fn main() {}
2 changes: 1 addition & 1 deletion examples/reflection/reflection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fn main() {
/// To do this, you can either define a `#[reflect(default = "...")]` attribute on the ignored field, or
/// opt-out of `FromReflect`'s auto-derive using the `#[reflect(from_reflect = false)]` attribute.
#[derive(Reflect)]
#[from_reflect(auto_derive = false)]
#[reflect(from_reflect = false)]
pub struct Foo {
a: usize,
nested: Bar,
Expand Down

0 comments on commit 95cb9e3

Please sign in to comment.