From 028bd147075eb5f960e7bd52a5bb92c741b9d98d Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 10:58:13 -0700 Subject: [PATCH 01/16] Removed `PartialReflect` bound on `MaybeTyped` --- crates/bevy_reflect/src/type_info.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_reflect/src/type_info.rs b/crates/bevy_reflect/src/type_info.rs index 99c768c092a40..19baefaf4c479 100644 --- a/crates/bevy_reflect/src/type_info.rs +++ b/crates/bevy_reflect/src/type_info.rs @@ -7,7 +7,7 @@ use crate::{ structs::{DynamicStruct, StructInfo}, tuple::{DynamicTuple, TupleInfo}, tuple_struct::{DynamicTupleStruct, TupleStructInfo}, - Generics, PartialReflect, Reflect, ReflectKind, TypePath, TypePathTable, + Generics, Reflect, ReflectKind, TypePath, TypePathTable, }; use core::{ any::{Any, TypeId}, @@ -117,7 +117,7 @@ pub trait Typed: Reflect + TypePath { message = "`{Self}` does not implement `Typed` so cannot provide static type information", note = "consider annotating `{Self}` with `#[derive(Reflect)]`" )] -pub trait MaybeTyped: PartialReflect { +pub trait MaybeTyped { /// Returns the compile-time [info] for the underlying type, if it exists. /// /// [info]: TypeInfo From a1d69d42ac9222773f4cfe05cb53f3610323a106 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 10:58:31 -0700 Subject: [PATCH 02/16] Removed `PartialReflect` bounds in field info constructors --- crates/bevy_reflect/src/fields.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/bevy_reflect/src/fields.rs b/crates/bevy_reflect/src/fields.rs index e66e5cf264346..dc36ebba49253 100644 --- a/crates/bevy_reflect/src/fields.rs +++ b/crates/bevy_reflect/src/fields.rs @@ -1,7 +1,7 @@ use crate::{ attributes::{impl_custom_attribute_methods, CustomAttributes}, type_info::impl_type_methods, - MaybeTyped, PartialReflect, Type, TypeInfo, TypePath, + MaybeTyped, Type, TypeInfo, TypePath, }; use alloc::borrow::Cow; use bevy_platform::sync::Arc; @@ -20,7 +20,7 @@ pub struct NamedField { impl NamedField { /// Create a new [`NamedField`]. - pub fn new(name: &'static str) -> Self { + pub fn new(name: &'static str) -> Self { Self { name, type_info: T::maybe_type_info, @@ -83,7 +83,7 @@ pub struct UnnamedField { impl UnnamedField { /// Create a new [`UnnamedField`]. - pub fn new(index: usize) -> Self { + pub fn new(index: usize) -> Self { Self { index, type_info: T::maybe_type_info, From c99c54f6a5203231bb65a4c2a857fdaefa4ba6a5 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 10:59:45 -0700 Subject: [PATCH 03/16] Added `CastPartialReflect` and `CastReflect` --- crates/bevy_reflect/derive/src/derive_data.rs | 54 ++++- .../bevy_reflect/derive/src/struct_utility.rs | 4 +- .../derive/src/where_clause_options.rs | 4 +- crates/bevy_reflect/src/cast.rs | 186 ++++++++++++++++++ crates/bevy_reflect/src/lib.rs | 1 + 5 files changed, 239 insertions(+), 10 deletions(-) create mode 100644 crates/bevy_reflect/src/cast.rs diff --git a/crates/bevy_reflect/derive/src/derive_data.rs b/crates/bevy_reflect/derive/src/derive_data.rs index cc4581ffda473..afbd1ec8f9625 100644 --- a/crates/bevy_reflect/derive/src/derive_data.rs +++ b/crates/bevy_reflect/derive/src/derive_data.rs @@ -711,7 +711,8 @@ impl<'a> ReflectStruct<'a> { for field in self.fields().iter() { let field_ty = field.reflected_type(); let member = field.to_member(); - let accessor = self.access_for_field(field, false); + let accessor = self.access_for_field(field, false, true); + let non_cast_accessor = self.access_for_field(field, false, false); match &field.attrs.clone { CloneBehavior::Default => { @@ -729,7 +730,17 @@ impl<'a> ReflectStruct<'a> { } } else { quote! { - <#field_ty as #bevy_reflect_path::PartialReflect>::reflect_clone_and_take(#accessor)? + #FQResult::map_err( + ::take( + #bevy_reflect_path::PartialReflect::reflect_clone(#accessor)? + ), + |_| #bevy_reflect_path::ReflectCloneError::FailedDowncast { + expected: #bevy_reflect_path::__macro_exports::alloc_utils::Cow::Borrowed(<#field_ty as #bevy_reflect_path::TypePath>::type_path()), + received: #bevy_reflect_path::__macro_exports::alloc_utils::Cow::Owned( + #bevy_reflect_path::__macro_exports::alloc_utils::ToString::to_string(#bevy_reflect_path::DynamicTypePath::reflect_type_path(#accessor)) + ), + } + )? } }; @@ -739,12 +750,28 @@ impl<'a> ReflectStruct<'a> { } CloneBehavior::Trait => { tokens.extend(quote! { - #member: #FQClone::clone(#accessor), + #member: #FQClone::clone(#non_cast_accessor), }); } CloneBehavior::Func(clone_fn) => { + let value = if field.attrs.ignore.is_ignored() { + quote!(#clone_fn(#non_cast_accessor)) + } else { + quote! { + #clone_fn(#FQOption::ok_or_else( + ::try_downcast_ref(#accessor), + || #bevy_reflect_path::ReflectCloneError::FailedDowncast { + expected: #bevy_reflect_path::__macro_exports::alloc_utils::Cow::Borrowed(<#field_ty as #bevy_reflect_path::TypePath>::type_path()), + received: #bevy_reflect_path::__macro_exports::alloc_utils::Cow::Owned( + #bevy_reflect_path::__macro_exports::alloc_utils::ToString::to_string(#bevy_reflect_path::DynamicTypePath::reflect_type_path(#accessor)) + ), + } + )?) + } + }; + tokens.extend(quote! { - #member: #clone_fn(#accessor), + #member: #value, }); } } @@ -779,21 +806,30 @@ impl<'a> ReflectStruct<'a> { /// Generates an accessor for the given field. /// - /// The mutability of the access can be controlled by the `is_mut` parameter. + /// The mutability of the access can be controlled by the `is_mutable` parameter. /// /// Generally, this just returns something like `&self.field`. /// However, if the struct is a remote wrapper, this then becomes `&self.0.field` in order to access the field on the inner type. /// /// If the field itself is a remote type, the above accessor is further wrapped in a call to `ReflectRemote::as_wrapper[_mut]`. + /// + /// If `is_castable` is true, the accessor is wrapped in a call to `CastPartialReflect::as_partial_reflect[_mut]` to handle reflection casting + /// when the field is not a remote type. pub fn access_for_field( &self, field: &StructField<'a>, is_mutable: bool, + is_castable: bool, ) -> proc_macro2::TokenStream { let bevy_reflect_path = self.meta().bevy_reflect_path(); let member = field.to_member(); let prefix_tokens = if is_mutable { quote!(&mut) } else { quote!(&) }; + let cast_method = if is_mutable { + quote!(as_partial_reflect_mut) + } else { + quote!(as_partial_reflect) + }; let accessor = if self.meta.is_remote_wrapper() { quote!(self.0.#member) @@ -813,7 +849,13 @@ impl<'a> ReflectStruct<'a> { <#wrapper_ty as #bevy_reflect_path::ReflectRemote>::#method(#prefix_tokens #accessor) } } - None => quote!(#prefix_tokens #accessor), + None => { + if is_castable { + quote!(#bevy_reflect_path::cast::CastPartialReflect::#cast_method(#prefix_tokens #accessor)) + } else { + quote!(#prefix_tokens #accessor) + } + } } } } diff --git a/crates/bevy_reflect/derive/src/struct_utility.rs b/crates/bevy_reflect/derive/src/struct_utility.rs index 9bfd72de60596..811f3cc964cba 100644 --- a/crates/bevy_reflect/derive/src/struct_utility.rs +++ b/crates/bevy_reflect/derive/src/struct_utility.rs @@ -23,8 +23,8 @@ impl FieldAccessors { .active_fields() .map(|field| { ( - reflect_struct.access_for_field(field, false), - reflect_struct.access_for_field(field, true), + reflect_struct.access_for_field(field, false, true), + reflect_struct.access_for_field(field, true, true), ) }) .unzip(); diff --git a/crates/bevy_reflect/derive/src/where_clause_options.rs b/crates/bevy_reflect/derive/src/where_clause_options.rs index ea56679eb9f90..11550fdb3e6e5 100644 --- a/crates/bevy_reflect/derive/src/where_clause_options.rs +++ b/crates/bevy_reflect/derive/src/where_clause_options.rs @@ -231,14 +231,14 @@ impl<'a, 'b> WhereClauseOptions<'a, 'b> { } } - /// The `PartialReflect` or `FromReflect` bound to use based on `#[reflect(from_reflect = false)]`. + /// The `CastPartialReflect` or `FromReflect` bound to use based on `#[reflect(from_reflect = false)]`. fn reflect_bound(&self) -> TokenStream { let bevy_reflect_path = self.meta.bevy_reflect_path(); if self.meta.from_reflect().should_auto_derive() { quote!(#bevy_reflect_path::FromReflect) } else { - quote!(#bevy_reflect_path::PartialReflect) + quote!(#bevy_reflect_path::cast::CastPartialReflect) } } diff --git a/crates/bevy_reflect/src/cast.rs b/crates/bevy_reflect/src/cast.rs new file mode 100644 index 0000000000000..d487712af0eb2 --- /dev/null +++ b/crates/bevy_reflect/src/cast.rs @@ -0,0 +1,186 @@ +use crate as bevy_reflect; +use crate::__macro_exports::RegisterForReflection; +use crate::{MaybeTyped, PartialReflect, Reflect}; +use alloc::boxed::Box; +use bevy_reflect_derive::impl_type_path; + +pub trait CastPartialReflect { + fn as_partial_reflect(&self) -> &dyn PartialReflect; + fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect; + fn into_partial_reflect(self: Box) -> Box; +} + +impl CastPartialReflect for T { + fn as_partial_reflect(&self) -> &dyn PartialReflect { + self + } + + fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { + self + } + + fn into_partial_reflect(self: Box) -> Box { + self + } +} + +impl CastPartialReflect for dyn PartialReflect { + fn as_partial_reflect(&self) -> &dyn PartialReflect { + self + } + + fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { + self + } + + fn into_partial_reflect(self: Box) -> Box { + self + } +} + +impl CastPartialReflect for dyn Reflect { + fn as_partial_reflect(&self) -> &dyn PartialReflect { + self.as_partial_reflect() + } + + fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { + self.as_partial_reflect_mut() + } + + fn into_partial_reflect(self: Box) -> Box { + self.into_partial_reflect() + } +} + +impl CastPartialReflect for Box { + fn as_partial_reflect(&self) -> &dyn PartialReflect { + self.as_ref() + } + + fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { + self.as_mut() + } + + fn into_partial_reflect(self: Box) -> Box { + *self + } +} + +impl CastPartialReflect for Box { + fn as_partial_reflect(&self) -> &dyn PartialReflect { + self.as_ref().as_partial_reflect() + } + + fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { + self.as_mut().as_partial_reflect_mut() + } + + fn into_partial_reflect(self: Box) -> Box { + self.into_reflect().into_partial_reflect() + } +} + +pub trait CastReflect: CastPartialReflect { + fn as_reflect(&self) -> &dyn Reflect; + fn as_reflect_mut(&mut self) -> &mut dyn Reflect; + fn into_reflect(self: Box) -> Box; +} + +impl CastReflect for T { + fn as_reflect(&self) -> &dyn Reflect { + self + } + + fn as_reflect_mut(&mut self) -> &mut dyn Reflect { + self + } + + fn into_reflect(self: Box) -> Box { + self + } +} + +impl CastReflect for dyn Reflect { + fn as_reflect(&self) -> &dyn Reflect { + self + } + + fn as_reflect_mut(&mut self) -> &mut dyn Reflect { + self + } + + fn into_reflect(self: Box) -> Box { + self + } +} + +impl CastReflect for Box { + fn as_reflect(&self) -> &dyn Reflect { + self.as_ref() + } + + fn as_reflect_mut(&mut self) -> &mut dyn Reflect { + self.as_mut() + } + + fn into_reflect(self: Box) -> Box { + *self + } +} + +impl_type_path!(::alloc::boxed::Box); + +impl MaybeTyped for Box {} +impl MaybeTyped for Box {} + +impl RegisterForReflection for Box {} +impl RegisterForReflection for Box {} + +#[cfg(test)] +mod tests { + use super::*; + use crate as bevy_reflect; + use crate::{structs::Struct, tuple_struct::TupleStruct}; + use static_assertions::assert_not_impl_all; + + #[test] + fn should_not_reflect_box() { + assert_not_impl_all!(Box: Reflect, PartialReflect); + assert_not_impl_all!(Box: Reflect, PartialReflect); + assert_not_impl_all!(Box: Reflect, PartialReflect); + } + + #[test] + fn should_reflect_boxed_struct_field() { + #[derive(Reflect)] + #[reflect(from_reflect = false)] + struct MyStruct { + value: Box, + } + + let my_struct: Box = Box::new(MyStruct { + value: Box::new(123_i32), + }); + + let field = my_struct.field("value").unwrap(); + assert_eq!(field.try_downcast_ref::(), Some(&123)); + + let field_info = field.get_represented_type_info().unwrap(); + assert!(field_info.ty().is::()); + } + + #[test] + fn should_reflect_boxed_tuple_struct_field() { + #[derive(Reflect)] + #[reflect(from_reflect = false)] + struct MyStruct(Box); + + let my_struct: Box = Box::new(MyStruct(Box::new(123_i32))); + + let field = my_struct.field(0).unwrap(); + assert_eq!(field.try_downcast_ref::(), Some(&123)); + + let field_info = field.get_represented_type_info().unwrap(); + assert!(field_info.ty().is::()); + } +} diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index 32d6c6a661232..ce4f1de189005 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -595,6 +595,7 @@ extern crate alloc; extern crate self as bevy_reflect; pub mod array; +pub mod cast; mod error; mod fields; mod from_reflect; From cae66f44cc60ed0aa9435d4a895a58f0331daec3 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 11:05:22 -0700 Subject: [PATCH 04/16] Removed `Reflect` bound on `FromReflect` Replaced with `Any + CastPartialReflect` to prepare for enum and general `FromReflect` support for `Box` --- crates/bevy_asset/src/reflect.rs | 2 +- crates/bevy_ecs/src/reflect/bundle.rs | 2 +- crates/bevy_ecs/src/reflect/component.rs | 2 +- crates/bevy_ecs/src/reflect/resource.rs | 4 +- .../bevy_reflect/derive/src/enum_utility.rs | 42 ++++++++++++++++--- crates/bevy_reflect/derive/src/impls/enums.rs | 13 ++++-- crates/bevy_reflect/src/cast.rs | 1 - crates/bevy_reflect/src/from_reflect.rs | 6 ++- crates/bevy_reflect/src/impls/alloc/borrow.rs | 16 +++---- .../src/impls/alloc/collections/btree/map.rs | 28 ++++++------- .../src/impls/alloc/collections/vec_deque.rs | 4 +- crates/bevy_reflect/src/impls/alloc/vec.rs | 4 +- .../bevy_platform/collections/hash_map.rs | 5 ++- .../bevy_platform/collections/hash_set.rs | 7 +++- .../bevy_reflect/src/impls/core/primitives.rs | 2 +- crates/bevy_reflect/src/impls/hashbrown.rs | 8 ++-- crates/bevy_reflect/src/impls/indexmap.rs | 36 ++++++++-------- crates/bevy_reflect/src/impls/macros/list.rs | 12 +++--- crates/bevy_reflect/src/impls/macros/map.rs | 24 +++++------ crates/bevy_reflect/src/impls/macros/set.rs | 12 +++--- crates/bevy_reflect/src/impls/smallvec.rs | 14 +++---- .../src/impls/std/collections/hash_map.rs | 6 +-- .../src/impls/std/collections/hash_set.rs | 7 +++- crates/bevy_reflect/src/list.rs | 3 +- crates/bevy_reflect/src/tuple.rs | 6 +-- crates/bevy_state/src/app.rs | 14 +++---- 26 files changed, 164 insertions(+), 116 deletions(-) diff --git a/crates/bevy_asset/src/reflect.rs b/crates/bevy_asset/src/reflect.rs index 2fc18d69bdfa1..86566593346b7 100644 --- a/crates/bevy_asset/src/reflect.rs +++ b/crates/bevy_asset/src/reflect.rs @@ -148,7 +148,7 @@ impl ReflectAsset { } } -impl FromType for ReflectAsset { +impl FromType for ReflectAsset { fn from_type() -> Self { ReflectAsset { handle_type_id: TypeId::of::>(), diff --git a/crates/bevy_ecs/src/reflect/bundle.rs b/crates/bevy_ecs/src/reflect/bundle.rs index 72dc16b2fd181..acf3e1c5511ab 100644 --- a/crates/bevy_ecs/src/reflect/bundle.rs +++ b/crates/bevy_ecs/src/reflect/bundle.rs @@ -57,7 +57,7 @@ impl ReflectBundleFns { /// /// This is useful if you want to start with the default implementation before overriding some /// of the functions to create a custom implementation. - pub fn new() -> Self { + pub fn new() -> Self { >::from_type().0 } } diff --git a/crates/bevy_ecs/src/reflect/component.rs b/crates/bevy_ecs/src/reflect/component.rs index c38deeb31683c..2eefa0cee1a35 100644 --- a/crates/bevy_ecs/src/reflect/component.rs +++ b/crates/bevy_ecs/src/reflect/component.rs @@ -140,7 +140,7 @@ impl ReflectComponentFns { /// /// This is useful if you want to start with the default implementation before overriding some /// of the functions to create a custom implementation. - pub fn new() -> Self { + pub fn new() -> Self { >::from_type().0 } } diff --git a/crates/bevy_ecs/src/reflect/resource.rs b/crates/bevy_ecs/src/reflect/resource.rs index 16362b046f87f..4d6e1e960434b 100644 --- a/crates/bevy_ecs/src/reflect/resource.rs +++ b/crates/bevy_ecs/src/reflect/resource.rs @@ -78,7 +78,7 @@ impl ReflectResourceFns { /// /// This is useful if you want to start with the default implementation before overriding some /// of the functions to create a custom implementation. - pub fn new() -> Self { + pub fn new() -> Self { >::from_type().0 } } @@ -206,7 +206,7 @@ impl ReflectResource { } } -impl FromType for ReflectResource { +impl FromType for ReflectResource { fn from_type() -> Self { ReflectResource(ReflectResourceFns { insert: |world, reflected_resource, registry| { diff --git a/crates/bevy_reflect/derive/src/enum_utility.rs b/crates/bevy_reflect/derive/src/enum_utility.rs index 3410c6eae51b8..74ffa1366f26b 100644 --- a/crates/bevy_reflect/derive/src/enum_utility.rs +++ b/crates/bevy_reflect/derive/src/enum_utility.rs @@ -318,7 +318,7 @@ impl<'a> VariantBuilder for ReflectCloneVariantBuilder<'a> { let bevy_reflect_path = self.reflect_enum.meta().bevy_reflect_path(); let field_ty = field.field.reflected_type(); let alias = field.alias; - let alias = match &field.field.attrs.remote { + let non_cast_alias = match &field.field.attrs.remote { Some(wrapper_ty) => { quote! { <#wrapper_ty as #bevy_reflect_path::ReflectRemote>::as_wrapper(#alias) @@ -326,21 +326,53 @@ impl<'a> VariantBuilder for ReflectCloneVariantBuilder<'a> { } None => alias.to_token_stream(), }; + let alias = match &field.field.attrs.remote { + Some(wrapper_ty) => { + quote! { + <#wrapper_ty as #bevy_reflect_path::ReflectRemote>::as_wrapper(#alias) + } + } + None => quote! { + #bevy_reflect_path::cast::CastPartialReflect::as_partial_reflect(#alias) + }, + }; match &field.field.attrs.clone { CloneBehavior::Default => { quote! { - <#field_ty as #bevy_reflect_path::PartialReflect>::reflect_clone_and_take(#alias)? + #FQResult::map_err( + ::take( + #bevy_reflect_path::PartialReflect::reflect_clone(#alias)? + ), + |_| #bevy_reflect_path::ReflectCloneError::FailedDowncast { + expected: #bevy_reflect_path::__macro_exports::alloc_utils::Cow::Borrowed(<#field_ty as #bevy_reflect_path::TypePath>::type_path()), + received: #bevy_reflect_path::__macro_exports::alloc_utils::Cow::Owned( + #bevy_reflect_path::__macro_exports::alloc_utils::ToString::to_string(#bevy_reflect_path::DynamicTypePath::reflect_type_path(#alias)) + ), + } + )? } } CloneBehavior::Trait => { quote! { - #FQClone::clone(#alias) + #FQClone::clone(#non_cast_alias) } } CloneBehavior::Func(clone_fn) => { - quote! { - #clone_fn(#alias) + if field.field.attrs.ignore.is_ignored() { + quote!(#clone_fn(#non_cast_alias)) + } else { + quote! { + #clone_fn(#FQOption::ok_or_else( + ::try_downcast_ref(#alias), + || #bevy_reflect_path::ReflectCloneError::FailedDowncast { + expected: #bevy_reflect_path::__macro_exports::alloc_utils::Cow::Borrowed(<#field_ty as #bevy_reflect_path::TypePath>::type_path()), + received: #bevy_reflect_path::__macro_exports::alloc_utils::Cow::Owned( + #bevy_reflect_path::__macro_exports::alloc_utils::ToString::to_string(#bevy_reflect_path::DynamicTypePath::reflect_type_path(#alias)) + ), + } + )?) + } } } } diff --git a/crates/bevy_reflect/derive/src/impls/enums.rs b/crates/bevy_reflect/derive/src/impls/enums.rs index fd6c834ac7268..cf57cf1dcf142 100644 --- a/crates/bevy_reflect/derive/src/impls/enums.rs +++ b/crates/bevy_reflect/derive/src/impls/enums.rs @@ -341,18 +341,25 @@ fn generate_impls(reflect_enum: &ReflectEnum, ref_index: &Ident, ref_name: &Iden is_mutable: bool, bevy_reflect_path: &Path, ) -> proc_macro2::TokenStream { - let method = if is_mutable { + let remote_method = if is_mutable { quote!(as_wrapper_mut) } else { quote!(as_wrapper) }; + let cast_method = if is_mutable { + quote!(#bevy_reflect_path::cast::CastPartialReflect::as_partial_reflect_mut) + } else { + quote!(#bevy_reflect_path::cast::CastPartialReflect::as_partial_reflect) + }; field .attrs .remote .as_ref() - .map(|ty| quote!(<#ty as #bevy_reflect_path::ReflectRemote>::#method(#ident))) - .unwrap_or_else(|| quote!(#ident)) + .map( + |ty| quote!(<#ty as #bevy_reflect_path::ReflectRemote>::#remote_method(#ident)), + ) + .unwrap_or_else(|| quote!(#cast_method(#ident))) } match &variant.fields { diff --git a/crates/bevy_reflect/src/cast.rs b/crates/bevy_reflect/src/cast.rs index d487712af0eb2..ab14ea31a6104 100644 --- a/crates/bevy_reflect/src/cast.rs +++ b/crates/bevy_reflect/src/cast.rs @@ -1,4 +1,3 @@ -use crate as bevy_reflect; use crate::__macro_exports::RegisterForReflection; use crate::{MaybeTyped, PartialReflect, Reflect}; use alloc::boxed::Box; diff --git a/crates/bevy_reflect/src/from_reflect.rs b/crates/bevy_reflect/src/from_reflect.rs index d1c55a26305a6..de07c3987a875 100644 --- a/crates/bevy_reflect/src/from_reflect.rs +++ b/crates/bevy_reflect/src/from_reflect.rs @@ -1,5 +1,7 @@ +use crate::cast::CastPartialReflect; use crate::{FromType, PartialReflect, Reflect}; use alloc::boxed::Box; +use core::any::Any; /// A trait that enables types to be dynamically constructed from reflected data. /// @@ -26,7 +28,7 @@ use alloc::boxed::Box; message = "`{Self}` does not implement `FromReflect` so cannot be created through reflection", note = "consider annotating `{Self}` with `#[derive(Reflect)]`" )] -pub trait FromReflect: Reflect + Sized { +pub trait FromReflect: Any + CastPartialReflect + Sized { /// Constructs a concrete instance of `Self` from a reflected value. fn from_reflect(reflect: &dyn PartialReflect) -> Option; @@ -117,7 +119,7 @@ impl ReflectFromReflect { } } -impl FromType for ReflectFromReflect { +impl FromType for ReflectFromReflect { fn from_type() -> Self { Self { from_reflect: |reflect_value| { diff --git a/crates/bevy_reflect/src/impls/alloc/borrow.rs b/crates/bevy_reflect/src/impls/alloc/borrow.rs index 625e65f0a450f..7e61298226bef 100644 --- a/crates/bevy_reflect/src/impls/alloc/borrow.rs +++ b/crates/bevy_reflect/src/impls/alloc/borrow.rs @@ -141,7 +141,7 @@ impl FromReflect for Cow<'static, str> { #[cfg(feature = "functions")] crate::func::macros::impl_function_traits!(Cow<'static, str>); -impl List +impl List for Cow<'static, [T]> { fn get(&self, index: usize) -> Option<&dyn PartialReflect> { @@ -200,7 +200,7 @@ impl List } } -impl PartialReflect +impl PartialReflect for Cow<'static, [T]> { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { @@ -276,10 +276,10 @@ impl Parti impl_full_reflect!( for Cow<'static, [T]> where - T: FromReflect + Clone + MaybeTyped + TypePath + GetTypeRegistration, + T: FromReflect + Reflect + Clone + MaybeTyped + TypePath + GetTypeRegistration, ); -impl Typed +impl Typed for Cow<'static, [T]> { fn type_info() -> &'static TypeInfo { @@ -288,8 +288,8 @@ impl Typed } } -impl GetTypeRegistration - for Cow<'static, [T]> +impl + GetTypeRegistration for Cow<'static, [T]> { fn get_type_registration() -> TypeRegistration { TypeRegistration::of::>() @@ -300,7 +300,7 @@ impl GetTy } } -impl FromReflect +impl FromReflect for Cow<'static, [T]> { fn from_reflect(reflect: &dyn PartialReflect) -> Option { @@ -317,4 +317,4 @@ impl FromR } #[cfg(feature = "functions")] -crate::func::macros::impl_function_traits!(Cow<'static, [T]>; ); +crate::func::macros::impl_function_traits!(Cow<'static, [T]>; ); diff --git a/crates/bevy_reflect/src/impls/alloc/collections/btree/map.rs b/crates/bevy_reflect/src/impls/alloc/collections/btree/map.rs index 1d62e7479fd1b..95aeb37ffe7cc 100644 --- a/crates/bevy_reflect/src/impls/alloc/collections/btree/map.rs +++ b/crates/bevy_reflect/src/impls/alloc/collections/btree/map.rs @@ -15,8 +15,8 @@ use bevy_reflect_derive::impl_type_path; impl Map for ::alloc::collections::BTreeMap where - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, { fn get(&self, key: &dyn PartialReflect) -> Option<&dyn PartialReflect> { key.try_downcast_ref::() @@ -94,8 +94,8 @@ where impl PartialReflect for ::alloc::collections::BTreeMap where - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { Some(::type_info()) @@ -171,14 +171,14 @@ where impl_full_reflect!( for ::alloc::collections::BTreeMap where - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, ); impl Typed for ::alloc::collections::BTreeMap where - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, { fn type_info() -> &'static TypeInfo { static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new(); @@ -195,8 +195,8 @@ where impl GetTypeRegistration for ::alloc::collections::BTreeMap where - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, { fn get_type_registration() -> TypeRegistration { let mut registration = TypeRegistration::of::(); @@ -208,8 +208,8 @@ where impl FromReflect for ::alloc::collections::BTreeMap where - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, { fn from_reflect(reflect: &dyn PartialReflect) -> Option { let ref_map = reflect.reflect_ref().as_map().ok()?; @@ -230,7 +230,7 @@ impl_type_path!(::alloc::collections::BTreeMap); #[cfg(feature = "functions")] crate::func::macros::impl_function_traits!(::alloc::collections::BTreeMap; < - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Ord, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration > ); diff --git a/crates/bevy_reflect/src/impls/alloc/collections/vec_deque.rs b/crates/bevy_reflect/src/impls/alloc/collections/vec_deque.rs index 5144bc3c2bdfb..1268ded33b8d5 100644 --- a/crates/bevy_reflect/src/impls/alloc/collections/vec_deque.rs +++ b/crates/bevy_reflect/src/impls/alloc/collections/vec_deque.rs @@ -3,7 +3,7 @@ use bevy_reflect_derive::impl_type_path; use crate::impls::macros::impl_reflect_for_veclike; #[cfg(feature = "functions")] use crate::{ - from_reflect::FromReflect, type_info::MaybeTyped, type_path::TypePath, + from_reflect::FromReflect, reflect::Reflect, type_info::MaybeTyped, type_path::TypePath, type_registry::GetTypeRegistration, }; @@ -17,4 +17,4 @@ impl_reflect_for_veclike!( ); impl_type_path!(::alloc::collections::VecDeque); #[cfg(feature = "functions")] -crate::func::macros::impl_function_traits!(::alloc::collections::VecDeque; ); +crate::func::macros::impl_function_traits!(::alloc::collections::VecDeque; ); diff --git a/crates/bevy_reflect/src/impls/alloc/vec.rs b/crates/bevy_reflect/src/impls/alloc/vec.rs index 4e4c819d6a49d..437d588a680ec 100644 --- a/crates/bevy_reflect/src/impls/alloc/vec.rs +++ b/crates/bevy_reflect/src/impls/alloc/vec.rs @@ -3,7 +3,7 @@ use bevy_reflect_derive::impl_type_path; use crate::impls::macros::impl_reflect_for_veclike; #[cfg(feature = "functions")] use crate::{ - from_reflect::FromReflect, type_info::MaybeTyped, type_path::TypePath, + from_reflect::FromReflect, reflect::Reflect, type_info::MaybeTyped, type_path::TypePath, type_registry::GetTypeRegistration, }; @@ -17,7 +17,7 @@ impl_reflect_for_veclike!( ); impl_type_path!(::alloc::vec::Vec); #[cfg(feature = "functions")] -crate::func::macros::impl_function_traits!(::alloc::vec::Vec; ); +crate::func::macros::impl_function_traits!(::alloc::vec::Vec; ); #[cfg(test)] mod tests { diff --git a/crates/bevy_reflect/src/impls/bevy_platform/collections/hash_map.rs b/crates/bevy_reflect/src/impls/bevy_platform/collections/hash_map.rs index 48f0ddcd890a9..fc7ab994babad 100644 --- a/crates/bevy_reflect/src/impls/bevy_platform/collections/hash_map.rs +++ b/crates/bevy_reflect/src/impls/bevy_platform/collections/hash_map.rs @@ -1,6 +1,7 @@ use bevy_reflect_derive::impl_type_path; use crate::impls::macros::impl_reflect_for_hashmap; +use crate::Reflect; #[cfg(feature = "functions")] use crate::{ from_reflect::FromReflect, type_info::MaybeTyped, type_path::TypePath, @@ -14,8 +15,8 @@ impl_type_path!(::bevy_platform::collections::HashMap); #[cfg(feature = "functions")] crate::func::macros::impl_function_traits!(::bevy_platform::collections::HashMap; < - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, S: TypePath + BuildHasher + Default + Send + Sync > ); diff --git a/crates/bevy_reflect/src/impls/bevy_platform/collections/hash_set.rs b/crates/bevy_reflect/src/impls/bevy_platform/collections/hash_set.rs index a9c3f7a9593e4..ae51f43784175 100644 --- a/crates/bevy_reflect/src/impls/bevy_platform/collections/hash_set.rs +++ b/crates/bevy_reflect/src/impls/bevy_platform/collections/hash_set.rs @@ -2,7 +2,10 @@ use bevy_reflect_derive::impl_type_path; use crate::impls::macros::impl_reflect_for_hashset; #[cfg(feature = "functions")] -use crate::{from_reflect::FromReflect, type_path::TypePath, type_registry::GetTypeRegistration}; +use crate::{ + from_reflect::FromReflect, reflect::Reflect, type_path::TypePath, + type_registry::GetTypeRegistration, +}; #[cfg(feature = "functions")] use core::hash::{BuildHasher, Hash}; @@ -11,7 +14,7 @@ impl_type_path!(::bevy_platform::collections::HashSet); #[cfg(feature = "functions")] crate::func::macros::impl_function_traits!(::bevy_platform::collections::HashSet; < - V: Hash + Eq + FromReflect + TypePath + GetTypeRegistration, + V: Hash + Eq + FromReflect + Reflect + TypePath + GetTypeRegistration, S: TypePath + BuildHasher + Default + Send + Sync > ); diff --git a/crates/bevy_reflect/src/impls/core/primitives.rs b/crates/bevy_reflect/src/impls/core/primitives.rs index b63bf40926004..69466b7c025c2 100644 --- a/crates/bevy_reflect/src/impls/core/primitives.rs +++ b/crates/bevy_reflect/src/impls/core/primitives.rs @@ -601,7 +601,7 @@ impl R } } -impl FromReflect +impl FromReflect for [T; N] { fn from_reflect(reflect: &dyn PartialReflect) -> Option { diff --git a/crates/bevy_reflect/src/impls/hashbrown.rs b/crates/bevy_reflect/src/impls/hashbrown.rs index 4ea914dc3f68b..a9ff6c4dfc82c 100644 --- a/crates/bevy_reflect/src/impls/hashbrown.rs +++ b/crates/bevy_reflect/src/impls/hashbrown.rs @@ -1,7 +1,7 @@ use crate::impls::macros::{impl_reflect_for_hashmap, impl_reflect_for_hashset}; #[cfg(feature = "functions")] use crate::{ - from_reflect::FromReflect, type_info::MaybeTyped, type_path::TypePath, + from_reflect::FromReflect, reflect::Reflect, type_info::MaybeTyped, type_path::TypePath, type_registry::GetTypeRegistration, }; use bevy_reflect_derive::impl_type_path; @@ -13,8 +13,8 @@ impl_type_path!(::hashbrown::hash_map::HashMap); #[cfg(feature = "functions")] crate::func::macros::impl_function_traits!(::hashbrown::hash_map::HashMap; < - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, S: TypePath + BuildHasher + Default + Send + Sync > ); @@ -24,7 +24,7 @@ impl_type_path!(::hashbrown::hash_set::HashSet); #[cfg(feature = "functions")] crate::func::macros::impl_function_traits!(::hashbrown::hash_set::HashSet; < - V: Hash + Eq + FromReflect + TypePath + GetTypeRegistration, + V: Hash + Eq + FromReflect + Reflect + TypePath + GetTypeRegistration, S: TypePath + BuildHasher + Default + Send + Sync > ); diff --git a/crates/bevy_reflect/src/impls/indexmap.rs b/crates/bevy_reflect/src/impls/indexmap.rs index d7e4ea21d5638..60a86941b6f83 100644 --- a/crates/bevy_reflect/src/impls/indexmap.rs +++ b/crates/bevy_reflect/src/impls/indexmap.rs @@ -16,8 +16,8 @@ use indexmap::{IndexMap, IndexSet}; impl Map for IndexMap where - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, S: TypePath + BuildHasher + Default + Send + Sync, { fn get(&self, key: &dyn PartialReflect) -> Option<&dyn PartialReflect> { @@ -108,8 +108,8 @@ where impl PartialReflect for IndexMap where - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, S: TypePath + BuildHasher + Default + Send + Sync, { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { @@ -184,8 +184,8 @@ where impl Reflect for IndexMap where - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, S: TypePath + BuildHasher + Default + Send + Sync, { fn into_any(self: Box) -> Box { @@ -220,8 +220,8 @@ where impl Typed for IndexMap where - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, S: TypePath + BuildHasher + Default + Send + Sync, { fn type_info() -> &'static TypeInfo { @@ -239,8 +239,8 @@ where impl FromReflect for IndexMap where - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, S: TypePath + BuildHasher + Default + Send + Sync, { fn from_reflect(reflect: &dyn PartialReflect) -> Option { @@ -260,8 +260,8 @@ where impl GetTypeRegistration for IndexMap where - K: Hash + Eq + FromReflect + MaybeTyped + TypePath + GetTypeRegistration, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + K: Hash + Eq + FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, S: TypePath + BuildHasher + Send + Sync + Default, { fn get_type_registration() -> TypeRegistration { @@ -281,7 +281,7 @@ impl_type_path!(::indexmap::IndexMap); impl Set for IndexSet where - T: FromReflect + TypePath + GetTypeRegistration + Eq + Hash, + T: FromReflect + Reflect + TypePath + GetTypeRegistration + Eq + Hash, S: TypePath + BuildHasher + Default + Send + Sync, { fn get(&self, value: &dyn PartialReflect) -> Option<&dyn PartialReflect> { @@ -345,7 +345,7 @@ where impl PartialReflect for IndexSet where - T: FromReflect + TypePath + GetTypeRegistration + Eq + Hash, + T: FromReflect + Reflect + TypePath + GetTypeRegistration + Eq + Hash, S: TypePath + BuildHasher + Default + Send + Sync, { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { @@ -417,7 +417,7 @@ where impl Reflect for IndexSet where - T: FromReflect + TypePath + GetTypeRegistration + Eq + Hash, + T: FromReflect + Reflect + TypePath + GetTypeRegistration + Eq + Hash, S: TypePath + BuildHasher + Default + Send + Sync, { fn into_any(self: Box) -> Box { @@ -452,7 +452,7 @@ where impl Typed for IndexSet where - T: FromReflect + TypePath + GetTypeRegistration + Eq + Hash, + T: FromReflect + Reflect + TypePath + GetTypeRegistration + Eq + Hash, S: TypePath + BuildHasher + Default + Send + Sync, { fn type_info() -> &'static TypeInfo { @@ -468,7 +468,7 @@ where impl FromReflect for IndexSet where - T: FromReflect + TypePath + GetTypeRegistration + Eq + Hash, + T: FromReflect + Reflect + TypePath + GetTypeRegistration + Eq + Hash, S: TypePath + BuildHasher + Default + Send + Sync, { fn from_reflect(reflect: &dyn PartialReflect) -> Option { @@ -486,7 +486,7 @@ where impl GetTypeRegistration for IndexSet where - T: FromReflect + TypePath + GetTypeRegistration + Eq + Hash, + T: FromReflect + Reflect + TypePath + GetTypeRegistration + Eq + Hash, S: TypePath + BuildHasher + Default + Send + Sync, { fn get_type_registration() -> TypeRegistration { diff --git a/crates/bevy_reflect/src/impls/macros/list.rs b/crates/bevy_reflect/src/impls/macros/list.rs index 41c9c752454f9..131cb7283a193 100644 --- a/crates/bevy_reflect/src/impls/macros/list.rs +++ b/crates/bevy_reflect/src/impls/macros/list.rs @@ -1,7 +1,7 @@ macro_rules! impl_reflect_for_veclike { ($ty:ty, $insert:expr, $remove:expr, $push:expr, $pop:expr, $sub:ty) => { const _: () = { - impl $crate::list::List for $ty { + impl $crate::list::List for $ty { #[inline] fn get(&self, index: usize) -> Option<&dyn $crate::reflect::PartialReflect> { <$sub>::get(self, index).map(|value| value as &dyn $crate::reflect::PartialReflect) @@ -60,7 +60,7 @@ macro_rules! impl_reflect_for_veclike { } } - impl $crate::reflect::PartialReflect for $ty { + impl $crate::reflect::PartialReflect for $ty { #[inline] fn get_represented_type_info(&self) -> Option<&'static $crate::type_info::TypeInfo> { Some(::type_info()) @@ -139,9 +139,9 @@ macro_rules! impl_reflect_for_veclike { } } - $crate::impl_full_reflect!( for $ty where T: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration); + $crate::impl_full_reflect!( for $ty where T: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration); - impl $crate::type_info::Typed for $ty { + impl $crate::type_info::Typed for $ty { fn type_info() -> &'static $crate::type_info::TypeInfo { static CELL: $crate::utility::GenericTypeInfoCell = $crate::utility::GenericTypeInfoCell::new(); CELL.get_or_insert::(|| { @@ -154,7 +154,7 @@ macro_rules! impl_reflect_for_veclike { } } - impl $crate::type_registry::GetTypeRegistration + impl $crate::type_registry::GetTypeRegistration for $ty { fn get_type_registration() -> $crate::type_registry::TypeRegistration { @@ -169,7 +169,7 @@ macro_rules! impl_reflect_for_veclike { } } - impl $crate::from_reflect::FromReflect for $ty { + impl $crate::from_reflect::FromReflect for $ty { fn from_reflect(reflect: &dyn $crate::reflect::PartialReflect) -> Option { let ref_list = reflect.reflect_ref().as_list().ok()?; diff --git a/crates/bevy_reflect/src/impls/macros/map.rs b/crates/bevy_reflect/src/impls/macros/map.rs index 5ac779f3a747d..46e062ad40427 100644 --- a/crates/bevy_reflect/src/impls/macros/map.rs +++ b/crates/bevy_reflect/src/impls/macros/map.rs @@ -3,8 +3,8 @@ macro_rules! impl_reflect_for_hashmap { const _: () = { impl $crate::map::Map for $ty where - K: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, - V: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration, + K: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, + V: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration, S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync, { fn get(&self, key: &dyn $crate::reflect::PartialReflect) -> Option<&dyn $crate::reflect::PartialReflect> { @@ -92,8 +92,8 @@ macro_rules! impl_reflect_for_hashmap { impl $crate::reflect::PartialReflect for $ty where - K: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, - V: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration, + K: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, + V: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration, S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync, { fn get_represented_type_info(&self) -> Option<&'static $crate::type_info::TypeInfo> { @@ -170,15 +170,15 @@ macro_rules! impl_reflect_for_hashmap { $crate::impl_full_reflect!( for $ty where - K: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, - V: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration, + K: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, + V: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration, S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync, ); impl $crate::type_info::Typed for $ty where - K: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, - V: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration, + K: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, + V: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration, S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync, { fn type_info() -> &'static $crate::type_info::TypeInfo { @@ -196,8 +196,8 @@ macro_rules! impl_reflect_for_hashmap { impl $crate::type_registry::GetTypeRegistration for $ty where - K: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, - V: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration, + K: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, + V: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration, S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync + Default, { fn get_type_registration() -> $crate::type_registry::TypeRegistration { @@ -215,8 +215,8 @@ macro_rules! impl_reflect_for_hashmap { impl $crate::from_reflect::FromReflect for $ty where - K: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, - V: $crate::from_reflect::FromReflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration, + K: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, + V: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_info::MaybeTyped + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration, S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync, { fn from_reflect(reflect: &dyn $crate::reflect::PartialReflect) -> Option { diff --git a/crates/bevy_reflect/src/impls/macros/set.rs b/crates/bevy_reflect/src/impls/macros/set.rs index 69506a88e4549..940d9a5d9a322 100644 --- a/crates/bevy_reflect/src/impls/macros/set.rs +++ b/crates/bevy_reflect/src/impls/macros/set.rs @@ -3,7 +3,7 @@ macro_rules! impl_reflect_for_hashset { const _: () = { impl $crate::set::Set for $ty where - V: $crate::from_reflect::FromReflect + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, + V: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync, { fn get(&self, value: &dyn $crate::reflect::PartialReflect) -> Option<&dyn $crate::reflect::PartialReflect> { @@ -67,7 +67,7 @@ macro_rules! impl_reflect_for_hashset { impl $crate::reflect::PartialReflect for $ty where - V: $crate::from_reflect::FromReflect + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, + V: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync, { fn get_represented_type_info(&self) -> Option<&'static $crate::type_info::TypeInfo> { @@ -143,7 +143,7 @@ macro_rules! impl_reflect_for_hashset { impl $crate::type_info::Typed for $ty where - V: $crate::from_reflect::FromReflect + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, + V: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync, { fn type_info() -> &'static $crate::type_info::TypeInfo { @@ -160,7 +160,7 @@ macro_rules! impl_reflect_for_hashset { impl $crate::type_registry::GetTypeRegistration for $ty where - V: $crate::from_reflect::FromReflect + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, + V: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync + Default, { fn get_type_registration() -> $crate::type_registry::TypeRegistration { @@ -178,13 +178,13 @@ macro_rules! impl_reflect_for_hashset { $crate::impl_full_reflect!( for $ty where - V: $crate::from_reflect::FromReflect + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, + V: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync, ); impl $crate::from_reflect::FromReflect for $ty where - V: $crate::from_reflect::FromReflect + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, + V: $crate::from_reflect::FromReflect + $crate::reflect::Reflect + $crate::type_path::TypePath + $crate::type_registry::GetTypeRegistration + Eq + core::hash::Hash, S: $crate::type_path::TypePath + core::hash::BuildHasher + Default + Send + Sync, { fn from_reflect(reflect: &dyn $crate::reflect::PartialReflect) -> Option { diff --git a/crates/bevy_reflect/src/impls/smallvec.rs b/crates/bevy_reflect/src/impls/smallvec.rs index 799992dbf374a..2b17b631d7d64 100644 --- a/crates/bevy_reflect/src/impls/smallvec.rs +++ b/crates/bevy_reflect/src/impls/smallvec.rs @@ -13,7 +13,7 @@ use smallvec::{Array as SmallArray, SmallVec}; impl List for SmallVec where - T::Item: FromReflect + MaybeTyped + TypePath, + T::Item: FromReflect + Reflect + MaybeTyped + TypePath, { fn get(&self, index: usize) -> Option<&dyn PartialReflect> { if index < SmallVec::len(self) { @@ -81,7 +81,7 @@ where impl PartialReflect for SmallVec where - T::Item: FromReflect + MaybeTyped + TypePath, + T::Item: FromReflect + Reflect + MaybeTyped + TypePath, { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { Some(::type_info()) @@ -158,7 +158,7 @@ where impl Reflect for SmallVec where - T::Item: FromReflect + MaybeTyped + TypePath, + T::Item: FromReflect + Reflect + MaybeTyped + TypePath, { fn into_any(self: Box) -> Box { self @@ -192,7 +192,7 @@ where impl Typed for SmallVec where - T::Item: FromReflect + MaybeTyped + TypePath, + T::Item: FromReflect + Reflect + MaybeTyped + TypePath, { fn type_info() -> &'static TypeInfo { static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new(); @@ -209,7 +209,7 @@ impl_type_path!(::smallvec::SmallVec); impl FromReflect for SmallVec where - T::Item: FromReflect + MaybeTyped + TypePath, + T::Item: FromReflect + Reflect + MaybeTyped + TypePath, { fn from_reflect(reflect: &dyn PartialReflect) -> Option { let ref_list = reflect.reflect_ref().as_list().ok()?; @@ -226,7 +226,7 @@ where impl GetTypeRegistration for SmallVec where - T::Item: FromReflect + MaybeTyped + TypePath, + T::Item: FromReflect + Reflect + MaybeTyped + TypePath, { fn get_type_registration() -> TypeRegistration { let mut registration = TypeRegistration::of::>(); @@ -236,4 +236,4 @@ where } #[cfg(feature = "functions")] -crate::func::macros::impl_function_traits!(SmallVec; where T::Item: FromReflect + MaybeTyped + TypePath); +crate::func::macros::impl_function_traits!(SmallVec; where T::Item: FromReflect + Reflect + MaybeTyped + TypePath); diff --git a/crates/bevy_reflect/src/impls/std/collections/hash_map.rs b/crates/bevy_reflect/src/impls/std/collections/hash_map.rs index 604c29f51736e..d69d7f761e2a6 100644 --- a/crates/bevy_reflect/src/impls/std/collections/hash_map.rs +++ b/crates/bevy_reflect/src/impls/std/collections/hash_map.rs @@ -3,7 +3,7 @@ use bevy_reflect_derive::impl_type_path; use crate::impls::macros::impl_reflect_for_hashmap; #[cfg(feature = "functions")] use crate::{ - from_reflect::FromReflect, type_info::MaybeTyped, type_path::TypePath, + from_reflect::FromReflect, reflect::Reflect, type_info::MaybeTyped, type_path::TypePath, type_registry::GetTypeRegistration, }; #[cfg(feature = "functions")] @@ -16,8 +16,8 @@ impl_type_path!(::std::collections::HashMap); #[cfg(feature = "functions")] crate::func::macros::impl_function_traits!(::std::collections::HashMap; < - K: FromReflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, - V: FromReflect + MaybeTyped + TypePath + GetTypeRegistration, + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, S: TypePath + BuildHasher + Default + Send + Sync > ); diff --git a/crates/bevy_reflect/src/impls/std/collections/hash_set.rs b/crates/bevy_reflect/src/impls/std/collections/hash_set.rs index 26d2dd47ca327..d44fb23f846aa 100644 --- a/crates/bevy_reflect/src/impls/std/collections/hash_set.rs +++ b/crates/bevy_reflect/src/impls/std/collections/hash_set.rs @@ -2,7 +2,10 @@ use bevy_reflect_derive::impl_type_path; use crate::impls::macros::impl_reflect_for_hashset; #[cfg(feature = "functions")] -use crate::{from_reflect::FromReflect, type_path::TypePath, type_registry::GetTypeRegistration}; +use crate::{ + from_reflect::FromReflect, reflect::Reflect, type_path::TypePath, + type_registry::GetTypeRegistration, +}; #[cfg(feature = "functions")] use core::hash::{BuildHasher, Hash}; @@ -11,7 +14,7 @@ impl_type_path!(::std::collections::HashSet); #[cfg(feature = "functions")] crate::func::macros::impl_function_traits!(::std::collections::HashSet; < - V: Hash + Eq + FromReflect + TypePath + GetTypeRegistration, + V: Hash + Eq + FromReflect + Reflect + TypePath + GetTypeRegistration, S: TypePath + BuildHasher + Default + Send + Sync > ); diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index 85ba09f98b0a7..ba274315cd398 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -133,7 +133,8 @@ pub struct ListInfo { impl ListInfo { /// Create a new [`ListInfo`]. - pub fn new() -> Self { + pub fn new( + ) -> Self { Self { ty: Type::of::(), generics: Generics::new(), diff --git a/crates/bevy_reflect/src/tuple.rs b/crates/bevy_reflect/src/tuple.rs index e3924d6a8590d..8735135b64276 100644 --- a/crates/bevy_reflect/src/tuple.rs +++ b/crates/bevy_reflect/src/tuple.rs @@ -668,7 +668,7 @@ macro_rules! impl_reflect_tuple { } } - impl<$($name: FromReflect + MaybeTyped + TypePath + GetTypeRegistration),*> FromReflect for ($($name,)*) + impl<$($name: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> FromReflect for ($($name,)*) { fn from_reflect(reflect: &dyn PartialReflect) -> Option { let _ref_tuple = reflect.reflect_ref().as_tuple().ok()?; @@ -796,7 +796,7 @@ const _: () = { macro_rules! impl_from_arg_tuple { ($(#[$meta:meta])* $($name: ident),*) => { $(#[$meta])* - $crate::func::args::impl_from_arg!(($($name,)*); <$($name: FromReflect + MaybeTyped + TypePath + GetTypeRegistration),*>); + $crate::func::args::impl_from_arg!(($($name,)*); <$($name: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration),*>); }; } @@ -811,7 +811,7 @@ const _: () = { macro_rules! impl_into_return_tuple { ($(#[$meta:meta])* $($name: ident),+) => { $(#[$meta])* - $crate::func::impl_into_return!(($($name,)*); <$($name: FromReflect + MaybeTyped + TypePath + GetTypeRegistration),*>); + $crate::func::impl_into_return!(($($name,)*); <$($name: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration),*>); }; } diff --git a/crates/bevy_state/src/app.rs b/crates/bevy_state/src/app.rs index 3d79fd7e8a56c..ea14e6ef74877 100644 --- a/crates/bevy_state/src/app.rs +++ b/crates/bevy_state/src/app.rs @@ -13,7 +13,7 @@ use crate::{ }; #[cfg(feature = "bevy_reflect")] -use bevy_reflect::{FromReflect, GetTypeRegistration, Typed}; +use bevy_reflect::{FromReflect, GetTypeRegistration, Reflect, Typed}; /// State installation methods for [`App`] and [`SubApp`]. pub trait AppExtStates { @@ -65,7 +65,7 @@ pub trait AppExtStates { /// This enables reflection code to access the state. For detailed information, see the docs on [`crate::reflect::ReflectState`] . fn register_type_state(&mut self) -> &mut Self where - S: States + FromReflect + GetTypeRegistration + Typed; + S: States + FromReflect + Reflect + GetTypeRegistration + Typed; #[cfg(feature = "bevy_reflect")] /// Registers the state type `T` using [`App::register_type`], @@ -75,7 +75,7 @@ pub trait AppExtStates { /// For detailed information, see the docs on [`crate::reflect::ReflectState`] and [`crate::reflect::ReflectFreelyMutableState`]. fn register_type_mutable_state(&mut self) -> &mut Self where - S: FreelyMutableState + FromReflect + GetTypeRegistration + Typed; + S: FreelyMutableState + FromReflect + Reflect + GetTypeRegistration + Typed; } /// Separate function to only warn once for all state installation methods. @@ -212,7 +212,7 @@ impl AppExtStates for SubApp { #[cfg(feature = "bevy_reflect")] fn register_type_state(&mut self) -> &mut Self where - S: States + FromReflect + GetTypeRegistration + Typed, + S: States + FromReflect + Reflect + GetTypeRegistration + Typed, { self.register_type::(); self.register_type::>(); @@ -224,7 +224,7 @@ impl AppExtStates for SubApp { #[cfg(feature = "bevy_reflect")] fn register_type_mutable_state(&mut self) -> &mut Self where - S: FreelyMutableState + FromReflect + GetTypeRegistration + Typed, + S: FreelyMutableState + FromReflect + Reflect + GetTypeRegistration + Typed, { self.register_type::(); self.register_type::>(); @@ -285,7 +285,7 @@ impl AppExtStates for App { #[cfg(feature = "bevy_reflect")] fn register_type_state(&mut self) -> &mut Self where - S: States + FromReflect + GetTypeRegistration + Typed, + S: States + FromReflect + Reflect + GetTypeRegistration + Typed, { self.main_mut().register_type_state::(); self @@ -294,7 +294,7 @@ impl AppExtStates for App { #[cfg(feature = "bevy_reflect")] fn register_type_mutable_state(&mut self) -> &mut Self where - S: FreelyMutableState + FromReflect + GetTypeRegistration + Typed, + S: FreelyMutableState + FromReflect + Reflect + GetTypeRegistration + Typed, { self.main_mut().register_type_mutable_state::(); self From 1b7dc49b92907a17d3c949e34ee0fd59dcf240d7 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 12:31:40 -0700 Subject: [PATCH 05/16] Removed `Reflect` bound on `TypeRegistration::of` --- crates/bevy_reflect/src/type_registry.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_reflect/src/type_registry.rs b/crates/bevy_reflect/src/type_registry.rs index 8ccd81ce710f7..3bdb45fb5a038 100644 --- a/crates/bevy_reflect/src/type_registry.rs +++ b/crates/bevy_reflect/src/type_registry.rs @@ -561,7 +561,7 @@ impl Debug for TypeRegistration { impl TypeRegistration { /// Creates type registration information for `T`. - pub fn of() -> Self { + pub fn of() -> Self { Self { data: Default::default(), type_info: T::type_info(), From 4dbf609d472ffbc53cd67959ee1e84fdb3c67fe7 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 12:33:18 -0700 Subject: [PATCH 06/16] Removed `Reflect` bound on `Typed` --- crates/bevy_reflect/src/type_info.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_reflect/src/type_info.rs b/crates/bevy_reflect/src/type_info.rs index 19baefaf4c479..43f95718797bd 100644 --- a/crates/bevy_reflect/src/type_info.rs +++ b/crates/bevy_reflect/src/type_info.rs @@ -96,7 +96,7 @@ use thiserror::Error; message = "`{Self}` does not implement `Typed` so cannot provide static type information", note = "consider annotating `{Self}` with `#[derive(Reflect)]`" )] -pub trait Typed: Reflect + TypePath { +pub trait Typed: TypePath { /// Returns the compile-time [info] for the underlying type. /// /// [info]: TypeInfo From 80ce8adbb4d35c6d448812480b87ad6cd13ef1c4 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 12:33:36 -0700 Subject: [PATCH 07/16] Removed `Reflect` bound on `OpaqueInfo::new` --- crates/bevy_reflect/src/type_info.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_reflect/src/type_info.rs b/crates/bevy_reflect/src/type_info.rs index 43f95718797bd..da3ba5144b9e1 100644 --- a/crates/bevy_reflect/src/type_info.rs +++ b/crates/bevy_reflect/src/type_info.rs @@ -7,7 +7,7 @@ use crate::{ structs::{DynamicStruct, StructInfo}, tuple::{DynamicTuple, TupleInfo}, tuple_struct::{DynamicTupleStruct, TupleStructInfo}, - Generics, Reflect, ReflectKind, TypePath, TypePathTable, + Generics, ReflectKind, TypePath, TypePathTable, }; use core::{ any::{Any, TypeId}, @@ -592,7 +592,7 @@ pub struct OpaqueInfo { impl OpaqueInfo { /// Creates a new [`OpaqueInfo`]. - pub fn new() -> Self { + pub fn new() -> Self { Self { ty: Type::of::(), generics: Generics::new(), From b5191ca15638e855e8e3f4559026d927e046eac4 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 12:37:01 -0700 Subject: [PATCH 08/16] Implemented casting traits for all types Also adds support for tuples of boxed values --- crates/bevy_ecs/src/reflect/event.rs | 2 +- crates/bevy_ecs/src/reflect/map_entities.rs | 4 +- .../bevy_reflect/derive/src/impls/casting.rs | 45 +++++++++ .../bevy_reflect/derive/src/impls/common.rs | 5 + crates/bevy_reflect/derive/src/impls/mod.rs | 1 + crates/bevy_reflect/src/array.rs | 7 +- crates/bevy_reflect/src/cast.rs | 94 ++++++++++++++++--- crates/bevy_reflect/src/enums/dynamic_enum.rs | 2 + .../bevy_reflect/src/func/dynamic_function.rs | 2 + crates/bevy_reflect/src/impls/core/panic.rs | 34 +------ .../bevy_reflect/src/impls/core/primitives.rs | 72 +++++++------- crates/bevy_reflect/src/impls/indexmap.rs | 87 +++-------------- crates/bevy_reflect/src/impls/smallvec.rs | 41 ++------ crates/bevy_reflect/src/impls/std/path.rs | 68 +------------- crates/bevy_reflect/src/list.rs | 2 + crates/bevy_reflect/src/map.rs | 7 +- crates/bevy_reflect/src/reflect.rs | 3 + crates/bevy_reflect/src/set.rs | 2 + crates/bevy_reflect/src/structs.rs | 2 + crates/bevy_reflect/src/tuple.rs | 68 ++++++++++---- crates/bevy_reflect/src/tuple_struct.rs | 2 + 21 files changed, 279 insertions(+), 271 deletions(-) create mode 100644 crates/bevy_reflect/derive/src/impls/casting.rs diff --git a/crates/bevy_ecs/src/reflect/event.rs b/crates/bevy_ecs/src/reflect/event.rs index 322a6ef85895f..46620fc189a32 100644 --- a/crates/bevy_ecs/src/reflect/event.rs +++ b/crates/bevy_ecs/src/reflect/event.rs @@ -45,7 +45,7 @@ impl ReflectEventFns { /// /// This is useful if you want to start with the default implementation /// before overriding some of the functions to create a custom implementation. - pub fn new<'a, T: Event + FromReflect + TypePath>() -> Self + pub fn new<'a, T: Event + FromReflect + Reflect + TypePath>() -> Self where T::Trigger<'a>: Default, { diff --git a/crates/bevy_ecs/src/reflect/map_entities.rs b/crates/bevy_ecs/src/reflect/map_entities.rs index 04fc25579906d..ee8cad82ef0cb 100644 --- a/crates/bevy_ecs/src/reflect/map_entities.rs +++ b/crates/bevy_ecs/src/reflect/map_entities.rs @@ -1,5 +1,5 @@ use crate::entity::{EntityMapper, MapEntities}; -use bevy_reflect::{FromReflect, FromType, PartialReflect}; +use bevy_reflect::{FromReflect, FromType, PartialReflect, Reflect}; /// For a specific type of value, this maps any fields with values of type [`Entity`] to a new world. /// @@ -25,7 +25,7 @@ impl ReflectMapEntities { } } -impl FromType for ReflectMapEntities { +impl FromType for ReflectMapEntities { fn from_type() -> Self { ReflectMapEntities { map_entities: |reflected, mut mapper| { diff --git a/crates/bevy_reflect/derive/src/impls/casting.rs b/crates/bevy_reflect/derive/src/impls/casting.rs new file mode 100644 index 0000000000000..2d635c74af67a --- /dev/null +++ b/crates/bevy_reflect/derive/src/impls/casting.rs @@ -0,0 +1,45 @@ +use crate::derive_data::ReflectMeta; +use crate::where_clause_options::WhereClauseOptions; +use proc_macro2::TokenStream; +use quote::quote; + +/// Generates impls for the `CastPartialReflect` and `CastReflect` traits. +pub(crate) fn impl_casting_traits( + meta: &ReflectMeta, + where_clause_options: &WhereClauseOptions, +) -> TokenStream { + let bevy_reflect_path = meta.bevy_reflect_path(); + let type_path = meta.type_path(); + let (impl_generics, ty_generics, where_clause) = type_path.generics().split_for_impl(); + let where_reflect_clause = where_clause_options.extend_where_clause(where_clause); + + quote! { + impl #impl_generics #bevy_reflect_path::cast::CastPartialReflect for #type_path #ty_generics #where_reflect_clause { + fn as_partial_reflect(&self) -> &dyn #bevy_reflect_path::PartialReflect { + self + } + + fn as_partial_reflect_mut(&mut self) -> &mut dyn #bevy_reflect_path::PartialReflect { + self + } + + fn into_partial_reflect(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box { + self + } + } + + impl #impl_generics #bevy_reflect_path::cast::CastReflect for #type_path #ty_generics #where_reflect_clause { + fn as_reflect(&self) -> &dyn #bevy_reflect_path::Reflect { + self + } + + fn as_reflect_mut(&mut self) -> &mut dyn #bevy_reflect_path::Reflect { + self + } + + fn into_reflect(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box { + self + } + } + } +} diff --git a/crates/bevy_reflect/derive/src/impls/common.rs b/crates/bevy_reflect/derive/src/impls/common.rs index 11e3883a23f2a..71f6a9df24693 100644 --- a/crates/bevy_reflect/derive/src/impls/common.rs +++ b/crates/bevy_reflect/derive/src/impls/common.rs @@ -2,6 +2,7 @@ use bevy_macro_utils::fq_std::{FQAny, FQOption, FQResult}; use quote::quote; +use crate::impls::casting::impl_casting_traits; use crate::{derive_data::ReflectMeta, where_clause_options::WhereClauseOptions}; pub fn impl_full_reflect(where_clause_options: &WhereClauseOptions) -> proc_macro2::TokenStream { @@ -48,6 +49,8 @@ pub fn impl_full_reflect(where_clause_options: &WhereClauseOptions) -> proc_macr } }; + let casting_impls = impl_casting_traits(meta, where_clause_options); + quote! { impl #impl_generics #bevy_reflect_path::Reflect for #type_path #ty_generics #where_reflect_clause { #any_impls @@ -76,6 +79,8 @@ pub fn impl_full_reflect(where_clause_options: &WhereClauseOptions) -> proc_macr #FQResult::Ok(()) } } + + #casting_impls } } diff --git a/crates/bevy_reflect/derive/src/impls/mod.rs b/crates/bevy_reflect/derive/src/impls/mod.rs index 48c8c84621d46..af9e6c1270baa 100644 --- a/crates/bevy_reflect/derive/src/impls/mod.rs +++ b/crates/bevy_reflect/derive/src/impls/mod.rs @@ -1,4 +1,5 @@ mod assertions; +mod casting; mod common; mod enums; #[cfg(feature = "functions")] diff --git a/crates/bevy_reflect/src/array.rs b/crates/bevy_reflect/src/array.rs index 5fcf8a57dba60..95e0b56e03d03 100644 --- a/crates/bevy_reflect/src/array.rs +++ b/crates/bevy_reflect/src/array.rs @@ -3,9 +3,9 @@ //! [array-like]: https://doc.rust-lang.org/book/ch03-02-data-types.html#the-array-type use crate::generics::impl_generic_info_methods; use crate::{ - type_info::impl_type_methods, utility::reflect_hasher, ApplyError, Generics, MaybeTyped, - PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, - TypePath, + cast::impl_cast_partial_reflect, type_info::impl_type_methods, utility::reflect_hasher, + ApplyError, Generics, MaybeTyped, PartialReflect, Reflect, ReflectKind, ReflectMut, + ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, }; use alloc::{boxed::Box, vec::Vec}; use bevy_reflect_derive::impl_type_path; @@ -348,6 +348,7 @@ impl<'a> IntoIterator for &'a DynamicArray { } impl_type_path!((in bevy_reflect) DynamicArray); +impl_cast_partial_reflect!(for DynamicArray); /// An iterator over an [`Array`]. pub struct ArrayIter<'a> { diff --git a/crates/bevy_reflect/src/cast.rs b/crates/bevy_reflect/src/cast.rs index ab14ea31a6104..3bf527eb3df09 100644 --- a/crates/bevy_reflect/src/cast.rs +++ b/crates/bevy_reflect/src/cast.rs @@ -1,25 +1,30 @@ use crate::__macro_exports::RegisterForReflection; -use crate::{MaybeTyped, PartialReflect, Reflect}; + +use crate::utility::GenericTypeInfoCell; +use crate::{ + GetTypeRegistration, MaybeTyped, OpaqueInfo, PartialReflect, Reflect, TypeInfo, TypePath, + TypeRegistration, Typed, +}; use alloc::boxed::Box; use bevy_reflect_derive::impl_type_path; -pub trait CastPartialReflect { +pub trait CastPartialReflect: Send + Sync + 'static { fn as_partial_reflect(&self) -> &dyn PartialReflect; fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect; fn into_partial_reflect(self: Box) -> Box; } -impl CastPartialReflect for T { +impl CastPartialReflect for Box { fn as_partial_reflect(&self) -> &dyn PartialReflect { - self + T::as_partial_reflect(self) } fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self + T::as_partial_reflect_mut(self) } fn into_partial_reflect(self: Box) -> Box { - self + T::into_partial_reflect(*self) } } @@ -85,17 +90,17 @@ pub trait CastReflect: CastPartialReflect { fn into_reflect(self: Box) -> Box; } -impl CastReflect for T { +impl CastReflect for Box { fn as_reflect(&self) -> &dyn Reflect { - self + T::as_reflect(self) } fn as_reflect_mut(&mut self) -> &mut dyn Reflect { - self + T::as_reflect_mut(self) } fn into_reflect(self: Box) -> Box { - self + T::into_reflect(*self) } } @@ -132,14 +137,70 @@ impl_type_path!(::alloc::boxed::Box); impl MaybeTyped for Box {} impl MaybeTyped for Box {} +impl Typed for Box { + fn type_info() -> &'static TypeInfo { + static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new(); + CELL.get_or_insert::(|| TypeInfo::Opaque(OpaqueInfo::new::())) + } +} + impl RegisterForReflection for Box {} impl RegisterForReflection for Box {} +impl GetTypeRegistration for Box { + fn get_type_registration() -> TypeRegistration { + TypeRegistration::of::() + } +} + +macro_rules! impl_cast_partial_reflect { + ($(<$($id:ident),* $(,)?>)? for $ty:ty $(where $($tt:tt)*)?) => { + impl $(<$($id),*>)? $crate::cast::CastPartialReflect for $ty $(where $($tt)*)? { + fn as_partial_reflect(&self) -> &dyn $crate::PartialReflect { + self + } + + fn as_partial_reflect_mut(&mut self) -> &mut dyn $crate::PartialReflect { + self + } + + fn into_partial_reflect(self: ::alloc::boxed::Box) -> ::alloc::boxed::Box { + self + } + } + }; +} + +pub(crate) use impl_cast_partial_reflect; + +macro_rules! impl_casting_traits { + ($(<$($id:ident),* $(,)?>)? for $ty:ty $(where $($tt:tt)*)?) => { + + $crate::cast::impl_cast_partial_reflect!($(<$($id),*>)? for $ty $(where $($tt)*)?); + + impl $(<$($id),*>)? $crate::cast::CastReflect for $ty $(where $($tt)*)? { + fn as_reflect(&self) -> &dyn $crate::Reflect { + self + } + + fn as_reflect_mut(&mut self) -> &mut dyn $crate::Reflect { + self + } + + fn into_reflect(self: ::alloc::boxed::Box) -> ::alloc::boxed::Box { + self + } + } + }; +} + +pub(crate) use impl_casting_traits; + #[cfg(test)] mod tests { use super::*; use crate as bevy_reflect; - use crate::{structs::Struct, tuple_struct::TupleStruct}; + use crate::{structs::Struct, tuple::Tuple, tuple_struct::TupleStruct}; use static_assertions::assert_not_impl_all; #[test] @@ -182,4 +243,15 @@ mod tests { let field_info = field.get_represented_type_info().unwrap(); assert!(field_info.ty().is::()); } + + #[test] + fn should_reflect_boxed_tuple_field() { + let my_struct: Box = Box::new((Box::new(10_i32),)); + + let field = my_struct.field(0).unwrap(); + assert_eq!(field.try_downcast_ref::(), Some(&10)); + + let field_info = field.get_represented_type_info().unwrap(); + assert!(field_info.ty().is::()); + } } diff --git a/crates/bevy_reflect/src/enums/dynamic_enum.rs b/crates/bevy_reflect/src/enums/dynamic_enum.rs index 3d6b79ee1d059..5758bde10239a 100644 --- a/crates/bevy_reflect/src/enums/dynamic_enum.rs +++ b/crates/bevy_reflect/src/enums/dynamic_enum.rs @@ -1,6 +1,7 @@ use bevy_reflect_derive::impl_type_path; use crate::{ + cast::impl_cast_partial_reflect, enums::{ enum_debug, enum_hash, enum_partial_cmp, enum_partial_eq, Enum, VariantFieldIter, VariantType, @@ -420,3 +421,4 @@ impl PartialReflect for DynamicEnum { } impl_type_path!((in bevy_reflect) DynamicEnum); +impl_cast_partial_reflect!(for DynamicEnum); diff --git a/crates/bevy_reflect/src/func/dynamic_function.rs b/crates/bevy_reflect/src/func/dynamic_function.rs index d9f881af33626..ed4258aa9bcb9 100644 --- a/crates/bevy_reflect/src/func/dynamic_function.rs +++ b/crates/bevy_reflect/src/func/dynamic_function.rs @@ -1,3 +1,4 @@ +use crate::cast::impl_cast_partial_reflect; use crate::{ __macro_exports::RegisterForReflection, func::{ @@ -443,6 +444,7 @@ impl MaybeTyped for DynamicFunction<'static> {} impl RegisterForReflection for DynamicFunction<'static> {} impl_type_path!((in bevy_reflect) DynamicFunction<'env>); +impl_cast_partial_reflect!(for DynamicFunction<'static>); /// Outputs the function's signature. /// diff --git a/crates/bevy_reflect/src/impls/core/panic.rs b/crates/bevy_reflect/src/impls/core/panic.rs index 1dd07d758cc68..4407e5068ec75 100644 --- a/crates/bevy_reflect/src/impls/core/panic.rs +++ b/crates/bevy_reflect/src/impls/core/panic.rs @@ -2,6 +2,7 @@ use crate::{ error::ReflectCloneError, kind::{ReflectKind, ReflectMut, ReflectOwned, ReflectRef}, prelude::*, + reflect::impl_full_reflect, reflect::ApplyError, type_info::{OpaqueInfo, TypeInfo, Typed}, type_path::DynamicTypePath, @@ -109,37 +110,6 @@ impl PartialReflect for &'static Location<'static> { } } -impl Reflect for &'static Location<'static> { - fn into_any(self: Box) -> Box { - self - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } - - fn into_reflect(self: Box) -> Box { - self - } - - fn as_reflect(&self) -> &dyn Reflect { - self - } - - fn as_reflect_mut(&mut self) -> &mut dyn Reflect { - self - } - - fn set(&mut self, value: Box) -> Result<(), Box> { - *self = value.take()?; - Ok(()) - } -} - impl Typed for &'static Location<'static> { fn type_info() -> &'static TypeInfo { static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new(); @@ -161,3 +131,5 @@ impl FromReflect for &'static Location<'static> { reflect.try_downcast_ref::().copied() } } + +impl_full_reflect!(for &'static Location<'static>); diff --git a/crates/bevy_reflect/src/impls/core/primitives.rs b/crates/bevy_reflect/src/impls/core/primitives.rs index 69466b7c025c2..a6e0e6bdcc237 100644 --- a/crates/bevy_reflect/src/impls/core/primitives.rs +++ b/crates/bevy_reflect/src/impls/core/primitives.rs @@ -1,9 +1,10 @@ use crate::{ array::{Array, ArrayInfo, ArrayIter}, + cast::{CastPartialReflect, CastReflect}, error::ReflectCloneError, kind::{ReflectKind, ReflectMut, ReflectOwned, ReflectRef}, prelude::*, - reflect::ApplyError, + reflect::{impl_full_reflect, ApplyError}, type_info::{MaybeTyped, OpaqueInfo, TypeInfo, Typed}, type_registry::{ FromType, GetTypeRegistration, ReflectDeserialize, ReflectFromPtr, ReflectSerialize, @@ -403,37 +404,6 @@ impl PartialReflect for &'static str { } } -impl Reflect for &'static str { - fn into_any(self: Box) -> Box { - self - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } - - fn into_reflect(self: Box) -> Box { - self - } - - fn as_reflect(&self) -> &dyn Reflect { - self - } - - fn as_reflect_mut(&mut self) -> &mut dyn Reflect { - self - } - - fn set(&mut self, value: Box) -> Result<(), Box> { - *self = value.take()?; - Ok(()) - } -} - impl Typed for &'static str { fn type_info() -> &'static TypeInfo { static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new(); @@ -457,6 +427,8 @@ impl FromReflect for &'static str { } } +impl_full_reflect!(for &'static str); + impl Array for [T; N] { #[inline] fn get(&self, index: usize) -> Option<&dyn PartialReflect> { @@ -601,8 +573,8 @@ impl R } } -impl FromReflect - for [T; N] +impl + FromReflect for [T; N] { fn from_reflect(reflect: &dyn PartialReflect) -> Option { let ref_array = reflect.reflect_ref().as_array().ok()?; @@ -648,6 +620,38 @@ impl G } } +impl CastPartialReflect + for [T; N] +{ + fn as_partial_reflect(&self) -> &dyn PartialReflect { + self + } + + fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { + self + } + + fn into_partial_reflect(self: Box) -> Box { + self + } +} + +impl CastReflect + for [T; N] +{ + fn as_reflect(&self) -> &dyn Reflect { + self + } + + fn as_reflect_mut(&mut self) -> &mut dyn Reflect { + self + } + + fn into_reflect(self: Box) -> Box { + self + } +} + #[cfg(feature = "functions")] crate::func::macros::impl_function_traits!([T; N]; [const N: usize]); diff --git a/crates/bevy_reflect/src/impls/indexmap.rs b/crates/bevy_reflect/src/impls/indexmap.rs index 60a86941b6f83..80a7f7ec57eb8 100644 --- a/crates/bevy_reflect/src/impls/indexmap.rs +++ b/crates/bevy_reflect/src/impls/indexmap.rs @@ -1,4 +1,5 @@ use crate::{ + reflect::impl_full_reflect, set::{Set, SetInfo}, utility::GenericTypeInfoCell, FromReflect, FromType, Generics, GetTypeRegistration, PartialReflect, Reflect, @@ -11,7 +12,7 @@ use bevy_reflect::{ MaybeTyped, ReflectFromReflect, ReflectKind, TypeRegistry, Typed, }; use bevy_reflect_derive::impl_type_path; -use core::{any::Any, hash::BuildHasher, hash::Hash}; +use core::{hash::BuildHasher, hash::Hash}; use indexmap::{IndexMap, IndexSet}; impl Map for IndexMap @@ -182,42 +183,6 @@ where } } -impl Reflect for IndexMap -where - K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, - V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, - S: TypePath + BuildHasher + Default + Send + Sync, -{ - fn into_any(self: Box) -> Box { - self - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } - - fn into_reflect(self: Box) -> Box { - self - } - - fn as_reflect(&self) -> &dyn Reflect { - self - } - - fn as_reflect_mut(&mut self) -> &mut dyn Reflect { - self - } - - fn set(&mut self, value: Box) -> Result<(), Box> { - *self = value.take()?; - Ok(()) - } -} - impl Typed for IndexMap where K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, @@ -277,6 +242,13 @@ where } } +impl_full_reflect!( + for IndexMap + where + K: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration + Eq + Hash, + V: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration, + S: TypePath + BuildHasher + Default + Send + Sync, +); impl_type_path!(::indexmap::IndexMap); impl Set for IndexSet @@ -415,41 +387,6 @@ where } } -impl Reflect for IndexSet -where - T: FromReflect + Reflect + TypePath + GetTypeRegistration + Eq + Hash, - S: TypePath + BuildHasher + Default + Send + Sync, -{ - fn into_any(self: Box) -> Box { - self - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } - - fn into_reflect(self: Box) -> Box { - self - } - - fn as_reflect(&self) -> &dyn Reflect { - self - } - - fn as_reflect_mut(&mut self) -> &mut dyn Reflect { - self - } - - fn set(&mut self, value: Box) -> Result<(), Box> { - *self = value.take()?; - Ok(()) - } -} - impl Typed for IndexSet where T: FromReflect + Reflect + TypePath + GetTypeRegistration + Eq + Hash, @@ -496,4 +433,10 @@ where } } +impl_full_reflect!( + for IndexSet + where + T: FromReflect + Reflect + TypePath + GetTypeRegistration + Eq + Hash, + S: TypePath + BuildHasher + Default + Send + Sync, +); impl_type_path!(::indexmap::IndexSet); diff --git a/crates/bevy_reflect/src/impls/smallvec.rs b/crates/bevy_reflect/src/impls/smallvec.rs index 2b17b631d7d64..e312f9d8031d9 100644 --- a/crates/bevy_reflect/src/impls/smallvec.rs +++ b/crates/bevy_reflect/src/impls/smallvec.rs @@ -1,4 +1,5 @@ use crate::{ + impl_full_reflect, list::{List, ListInfo, ListIter}, utility::GenericTypeInfoCell, ApplyError, FromReflect, FromType, Generics, GetTypeRegistration, MaybeTyped, PartialReflect, @@ -8,7 +9,6 @@ use crate::{ use alloc::{boxed::Box, vec::Vec}; use bevy_reflect::ReflectCloneError; use bevy_reflect_derive::impl_type_path; -use core::any::Any; use smallvec::{Array as SmallArray, SmallVec}; impl List for SmallVec @@ -156,39 +156,12 @@ where } } -impl Reflect for SmallVec -where - T::Item: FromReflect + Reflect + MaybeTyped + TypePath, -{ - fn into_any(self: Box) -> Box { - self - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } - - fn into_reflect(self: Box) -> Box { - self - } - - fn as_reflect(&self) -> &dyn Reflect { - self - } - - fn as_reflect_mut(&mut self) -> &mut dyn Reflect { - self - } - - fn set(&mut self, value: Box) -> Result<(), Box> { - *self = value.take()?; - Ok(()) - } -} +impl_full_reflect!( + for SmallVec + where + T: SmallArray + TypePath + Send + Sync, + T::Item: FromReflect + Reflect + MaybeTyped + TypePath +); impl Typed for SmallVec where diff --git a/crates/bevy_reflect/src/impls/std/path.rs b/crates/bevy_reflect/src/impls/std/path.rs index ea113951d8818..d9796c40e68ee 100644 --- a/crates/bevy_reflect/src/impls/std/path.rs +++ b/crates/bevy_reflect/src/impls/std/path.rs @@ -2,7 +2,7 @@ use crate::{ error::ReflectCloneError, kind::{ReflectKind, ReflectMut, ReflectOwned, ReflectRef}, prelude::*, - reflect::ApplyError, + reflect::{impl_full_reflect, ApplyError}, type_info::{OpaqueInfo, TypeInfo, Typed}, type_path::DynamicTypePath, type_registry::{ @@ -116,37 +116,6 @@ impl PartialReflect for &'static Path { } } -impl Reflect for &'static Path { - fn into_any(self: Box) -> Box { - self - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } - - fn into_reflect(self: Box) -> Box { - self - } - - fn as_reflect(&self) -> &dyn Reflect { - self - } - - fn as_reflect_mut(&mut self) -> &mut dyn Reflect { - self - } - - fn set(&mut self, value: Box) -> Result<(), Box> { - *self = value.take()?; - Ok(()) - } -} - impl Typed for &'static Path { fn type_info() -> &'static TypeInfo { static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new(); @@ -169,6 +138,8 @@ impl FromReflect for &'static Path { } } +impl_full_reflect!(for &'static Path); + impl PartialReflect for Cow<'static, Path> { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { Some(::type_info()) @@ -259,37 +230,6 @@ impl PartialReflect for Cow<'static, Path> { } } -impl Reflect for Cow<'static, Path> { - fn into_any(self: Box) -> Box { - self - } - - fn as_any(&self) -> &dyn Any { - self - } - - fn as_any_mut(&mut self) -> &mut dyn Any { - self - } - - fn into_reflect(self: Box) -> Box { - self - } - - fn as_reflect(&self) -> &dyn Reflect { - self - } - - fn as_reflect_mut(&mut self) -> &mut dyn Reflect { - self - } - - fn set(&mut self, value: Box) -> Result<(), Box> { - *self = value.take()?; - Ok(()) - } -} - impl Typed for Cow<'static, Path> { fn type_info() -> &'static TypeInfo { static CELL: NonGenericTypeInfoCell = NonGenericTypeInfoCell::new(); @@ -316,5 +256,7 @@ impl GetTypeRegistration for Cow<'static, Path> { } } +impl_full_reflect!(for Cow<'static, Path>); + #[cfg(feature = "functions")] crate::func::macros::impl_function_traits!(Cow<'static, Path>); diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index ba274315cd398..4cc728b235b7e 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -16,6 +16,7 @@ use crate::{ MaybeTyped, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, }; +use crate::cast::impl_cast_partial_reflect; /// A trait used to power [list-like] operations via [reflection]. /// @@ -338,6 +339,7 @@ impl PartialReflect for DynamicList { } impl_type_path!((in bevy_reflect) DynamicList); +impl_cast_partial_reflect!(for DynamicList); impl Debug for DynamicList { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { diff --git a/crates/bevy_reflect/src/map.rs b/crates/bevy_reflect/src/map.rs index a691e8e7507cc..cb04322d2378e 100644 --- a/crates/bevy_reflect/src/map.rs +++ b/crates/bevy_reflect/src/map.rs @@ -7,9 +7,9 @@ use bevy_platform::collections::HashTable; use bevy_reflect_derive::impl_type_path; use crate::{ - generics::impl_generic_info_methods, type_info::impl_type_methods, ApplyError, Generics, - MaybeTyped, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, - TypeInfo, TypePath, + cast::impl_cast_partial_reflect, generics::impl_generic_info_methods, + type_info::impl_type_methods, ApplyError, Generics, MaybeTyped, PartialReflect, Reflect, + ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, }; use alloc::{boxed::Box, format, vec::Vec}; @@ -407,6 +407,7 @@ impl PartialReflect for DynamicMap { } impl_type_path!((in bevy_reflect) DynamicMap); +impl_cast_partial_reflect!(for DynamicMap); impl Debug for DynamicMap { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { diff --git a/crates/bevy_reflect/src/reflect.rs b/crates/bevy_reflect/src/reflect.rs index be4abbf764a9e..4e40b81e4370d 100644 --- a/crates/bevy_reflect/src/reflect.rs +++ b/crates/bevy_reflect/src/reflect.rs @@ -616,6 +616,9 @@ impl TypePath for dyn Reflect { macro_rules! impl_full_reflect { ($(<$($id:ident),* $(,)?>)? for $ty:ty $(where $($tt:tt)*)?) => { + + $crate::cast::impl_casting_traits!($(<$($id),*>)? for $ty $(where $($tt)*)?); + impl $(<$($id),*>)? $crate::Reflect for $ty $(where $($tt)*)? { fn into_any(self: bevy_platform::prelude::Box) -> bevy_platform::prelude::Box { self diff --git a/crates/bevy_reflect/src/set.rs b/crates/bevy_reflect/src/set.rs index 815ae920a1826..c1ad911c5c630 100644 --- a/crates/bevy_reflect/src/set.rs +++ b/crates/bevy_reflect/src/set.rs @@ -7,6 +7,7 @@ use core::fmt::{Debug, Formatter}; use bevy_platform::collections::{hash_table::OccupiedEntry as HashTableOccupiedEntry, HashTable}; use bevy_reflect_derive::impl_type_path; +use crate::cast::impl_cast_partial_reflect; use crate::{ generics::impl_generic_info_methods, hash_error, type_info::impl_type_methods, ApplyError, Generics, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, @@ -333,6 +334,7 @@ impl PartialReflect for DynamicSet { } impl_type_path!((in bevy_reflect) DynamicSet); +impl_cast_partial_reflect!(for DynamicSet); impl Debug for DynamicSet { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { diff --git a/crates/bevy_reflect/src/structs.rs b/crates/bevy_reflect/src/structs.rs index 35393c8b3e9ee..df764a11385ad 100644 --- a/crates/bevy_reflect/src/structs.rs +++ b/crates/bevy_reflect/src/structs.rs @@ -4,6 +4,7 @@ use crate::generics::impl_generic_info_methods; use crate::{ attributes::{impl_custom_attribute_methods, CustomAttributes}, + cast::impl_cast_partial_reflect, type_info::impl_type_methods, ApplyError, Generics, NamedField, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, @@ -527,6 +528,7 @@ impl PartialReflect for DynamicStruct { } impl_type_path!((in bevy_reflect) DynamicStruct); +impl_cast_partial_reflect!(for DynamicStruct); impl Debug for DynamicStruct { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { diff --git a/crates/bevy_reflect/src/tuple.rs b/crates/bevy_reflect/src/tuple.rs index 8735135b64276..0120191bfc7c0 100644 --- a/crates/bevy_reflect/src/tuple.rs +++ b/crates/bevy_reflect/src/tuple.rs @@ -6,10 +6,13 @@ use variadics_please::all_tuples; use crate::generics::impl_generic_info_methods; use crate::{ - type_info::impl_type_methods, utility::GenericTypePathCell, ApplyError, FromReflect, Generics, - GetTypeRegistration, MaybeTyped, PartialReflect, Reflect, ReflectCloneError, ReflectKind, - ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, TypeRegistration, TypeRegistry, - Typed, UnnamedField, + cast::{impl_cast_partial_reflect, CastPartialReflect, CastReflect}, + type_info::impl_type_methods, + utility::GenericTypePathCell, + ApplyError, FromReflect, Generics, GetTypeRegistration, MaybeTyped, PartialReflect, Reflect, + ReflectCloneError, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, + TypeRegistration, TypeRegistry, Typed, UnnamedField, + __macro_exports::RegisterForReflection, }; use alloc::{boxed::Box, vec, vec::Vec}; use core::{ @@ -360,6 +363,7 @@ impl PartialReflect for DynamicTuple { } impl_type_path!((in bevy_reflect) DynamicTuple); +impl_cast_partial_reflect!(for DynamicTuple); impl FromIterator> for DynamicTuple { fn from_iter>>(fields: I) -> Self { @@ -503,11 +507,11 @@ pub fn tuple_debug(dyn_tuple: &dyn Tuple, f: &mut Formatter<'_>) -> core::fmt::R macro_rules! impl_reflect_tuple { {$($index:tt : $name:tt),*} => { - impl<$($name: Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> Tuple for ($($name,)*) { + impl<$($name: CastPartialReflect + MaybeTyped + TypePath + RegisterForReflection),*> Tuple for ($($name,)*) { #[inline] fn field(&self, index: usize) -> Option<&dyn PartialReflect> { match index { - $($index => Some(&self.$index as &dyn PartialReflect),)* + $($index => Some(CastPartialReflect::as_partial_reflect(&self.$index)),)* _ => None, } } @@ -515,7 +519,7 @@ macro_rules! impl_reflect_tuple { #[inline] fn field_mut(&mut self, index: usize) -> Option<&mut dyn PartialReflect> { match index { - $($index => Some(&mut self.$index as &mut dyn PartialReflect),)* + $($index => Some(CastPartialReflect::as_partial_reflect_mut(&mut self.$index)),)* _ => None, } } @@ -537,12 +541,12 @@ macro_rules! impl_reflect_tuple { #[inline] fn drain(self: Box) -> Vec> { vec![ - $(Box::new(self.$index),)* + $(CastPartialReflect::into_partial_reflect(Box::new(self.$index)),)* ] } } - impl<$($name: Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> PartialReflect for ($($name,)*) { + impl<$($name: CastPartialReflect + MaybeTyped + TypePath + RegisterForReflection),*> PartialReflect for ($($name,)*) { fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { Some(::type_info()) } @@ -606,7 +610,9 @@ macro_rules! impl_reflect_tuple { fn reflect_clone(&self) -> Result, ReflectCloneError> { Ok(Box::new(( $( - self.$index.reflect_clone()? + self.$index + .as_partial_reflect() + .reflect_clone()? .take::<$name>() .expect("`Reflect::reflect_clone` should return the same type"), )* @@ -614,7 +620,7 @@ macro_rules! impl_reflect_tuple { } } - impl<$($name: Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> Reflect for ($($name,)*) { + impl<$($name: CastPartialReflect + MaybeTyped + TypePath + RegisterForReflection),*> Reflect for ($($name,)*) { fn into_any(self: Box) -> Box { self } @@ -645,7 +651,35 @@ macro_rules! impl_reflect_tuple { } } - impl <$($name: Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> Typed for ($($name,)*) { + impl<$($name: CastPartialReflect + MaybeTyped + TypePath + RegisterForReflection),*> CastPartialReflect for ($($name,)*) { + fn as_partial_reflect(&self) -> &dyn PartialReflect { + self + } + + fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { + self + } + + fn into_partial_reflect(self: Box) -> Box { + self + } + } + + impl<$($name: CastPartialReflect + MaybeTyped + TypePath + RegisterForReflection),*> CastReflect for ($($name,)*) { + fn as_reflect(&self) -> &dyn Reflect { + self + } + + fn as_reflect_mut(&mut self) -> &mut dyn Reflect { + self + } + + fn into_reflect(self: Box) -> Box { + self + } + } + + impl<$($name: CastPartialReflect + MaybeTyped + TypePath + RegisterForReflection),*> Typed for ($($name,)*) { fn type_info() -> &'static TypeInfo { static CELL: $crate::utility::GenericTypeInfoCell = $crate::utility::GenericTypeInfoCell::new(); CELL.get_or_insert::(|| { @@ -658,17 +692,17 @@ macro_rules! impl_reflect_tuple { } } - impl<$($name: Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> GetTypeRegistration for ($($name,)*) { + impl<$($name: CastPartialReflect + MaybeTyped + TypePath + RegisterForReflection),*> GetTypeRegistration for ($($name,)*) { fn get_type_registration() -> TypeRegistration { TypeRegistration::of::<($($name,)*)>() } fn register_type_dependencies(_registry: &mut TypeRegistry) { - $(_registry.register::<$name>();)* + $(<$name as RegisterForReflection>::__register(_registry);)* } } - impl<$($name: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration),*> FromReflect for ($($name,)*) + impl<$($name: FromReflect + CastPartialReflect + MaybeTyped + TypePath + RegisterForReflection),*> FromReflect for ($($name,)*) { fn from_reflect(reflect: &dyn PartialReflect) -> Option { let _ref_tuple = reflect.reflect_ref().as_tuple().ok()?; @@ -796,7 +830,7 @@ const _: () = { macro_rules! impl_from_arg_tuple { ($(#[$meta:meta])* $($name: ident),*) => { $(#[$meta])* - $crate::func::args::impl_from_arg!(($($name,)*); <$($name: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration),*>); + $crate::func::args::impl_from_arg!(($($name,)*); <$($name: FromReflect + Reflect + MaybeTyped + TypePath + RegisterForReflection),*>); }; } @@ -811,7 +845,7 @@ const _: () = { macro_rules! impl_into_return_tuple { ($(#[$meta:meta])* $($name: ident),+) => { $(#[$meta])* - $crate::func::impl_into_return!(($($name,)*); <$($name: FromReflect + Reflect + MaybeTyped + TypePath + GetTypeRegistration),*>); + $crate::func::impl_into_return!(($($name,)*); <$($name: FromReflect + Reflect + MaybeTyped + TypePath + RegisterForReflection),*>); }; } diff --git a/crates/bevy_reflect/src/tuple_struct.rs b/crates/bevy_reflect/src/tuple_struct.rs index 3ddbf67761807..f69d5c8bdc5c9 100644 --- a/crates/bevy_reflect/src/tuple_struct.rs +++ b/crates/bevy_reflect/src/tuple_struct.rs @@ -6,6 +6,7 @@ use bevy_reflect_derive::impl_type_path; use crate::generics::impl_generic_info_methods; use crate::{ attributes::{impl_custom_attribute_methods, CustomAttributes}, + cast::impl_cast_partial_reflect, tuple::{DynamicTuple, Tuple}, type_info::impl_type_methods, ApplyError, Generics, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, @@ -377,6 +378,7 @@ impl PartialReflect for DynamicTupleStruct { } impl_type_path!((in bevy_reflect) DynamicTupleStruct); +impl_cast_partial_reflect!(for DynamicTupleStruct); impl Debug for DynamicTupleStruct { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { From 1816790e7e8f6bbe0bd82f70603265a6da62657b Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 13:58:20 -0700 Subject: [PATCH 09/16] Set casting traits as supertraits of `PartialReflect`/`Reflect` --- .../bevy_reflect/derive/src/impls/casting.rs | 6 +++ .../bevy_reflect/derive/src/impls/common.rs | 30 ------------- crates/bevy_reflect/src/array.rs | 17 +------- crates/bevy_reflect/src/cast.rs | 42 ------------------ crates/bevy_reflect/src/enums/dynamic_enum.rs | 15 ------- .../bevy_reflect/src/func/dynamic_function.rs | 12 ------ crates/bevy_reflect/src/impls/alloc/borrow.rs | 26 ----------- .../src/impls/alloc/collections/btree/map.rs | 11 ----- crates/bevy_reflect/src/impls/core/panic.rs | 13 ------ .../bevy_reflect/src/impls/core/primitives.rs | 41 ------------------ crates/bevy_reflect/src/impls/core/sync.rs | 12 ------ crates/bevy_reflect/src/impls/indexmap.rs | 26 ----------- crates/bevy_reflect/src/impls/macros/list.rs | 14 ------ crates/bevy_reflect/src/impls/macros/map.rs | 13 ------ crates/bevy_reflect/src/impls/macros/set.rs | 13 ------ crates/bevy_reflect/src/impls/smallvec.rs | 13 ------ crates/bevy_reflect/src/impls/std/path.rs | 26 ----------- crates/bevy_reflect/src/list.rs | 24 ++--------- crates/bevy_reflect/src/map.rs | 15 ------- crates/bevy_reflect/src/reflect.rs | 43 ++----------------- crates/bevy_reflect/src/serde/ser/mod.rs | 1 + crates/bevy_reflect/src/set.rs | 15 ------- crates/bevy_reflect/src/structs.rs | 15 ------- crates/bevy_reflect/src/tuple.rs | 38 ---------------- crates/bevy_reflect/src/tuple_struct.rs | 15 ------- crates/bevy_scene/src/reflect_utils.rs | 8 ++-- crates/bevy_scene/src/serde.rs | 3 +- examples/reflection/dynamic_types.rs | 1 + 28 files changed, 24 insertions(+), 484 deletions(-) diff --git a/crates/bevy_reflect/derive/src/impls/casting.rs b/crates/bevy_reflect/derive/src/impls/casting.rs index 2d635c74af67a..f5578a19e2678 100644 --- a/crates/bevy_reflect/derive/src/impls/casting.rs +++ b/crates/bevy_reflect/derive/src/impls/casting.rs @@ -15,28 +15,34 @@ pub(crate) fn impl_casting_traits( quote! { impl #impl_generics #bevy_reflect_path::cast::CastPartialReflect for #type_path #ty_generics #where_reflect_clause { + #[inline] fn as_partial_reflect(&self) -> &dyn #bevy_reflect_path::PartialReflect { self } + #[inline] fn as_partial_reflect_mut(&mut self) -> &mut dyn #bevy_reflect_path::PartialReflect { self } + #[inline] fn into_partial_reflect(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box { self } } impl #impl_generics #bevy_reflect_path::cast::CastReflect for #type_path #ty_generics #where_reflect_clause { + #[inline] fn as_reflect(&self) -> &dyn #bevy_reflect_path::Reflect { self } + #[inline] fn as_reflect_mut(&mut self) -> &mut dyn #bevy_reflect_path::Reflect { self } + #[inline] fn into_reflect(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box { self } diff --git a/crates/bevy_reflect/derive/src/impls/common.rs b/crates/bevy_reflect/derive/src/impls/common.rs index 71f6a9df24693..f7faf610326a4 100644 --- a/crates/bevy_reflect/derive/src/impls/common.rs +++ b/crates/bevy_reflect/derive/src/impls/common.rs @@ -55,21 +55,6 @@ pub fn impl_full_reflect(where_clause_options: &WhereClauseOptions) -> proc_macr impl #impl_generics #bevy_reflect_path::Reflect for #type_path #ty_generics #where_reflect_clause { #any_impls - #[inline] - fn into_reflect(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box { - self - } - - #[inline] - fn as_reflect(&self) -> &dyn #bevy_reflect_path::Reflect { - self - } - - #[inline] - fn as_reflect_mut(&mut self) -> &mut dyn #bevy_reflect_path::Reflect { - self - } - #[inline] fn set( &mut self, @@ -151,21 +136,6 @@ pub fn common_partial_reflect_methods( #FQOption::Some(self) } - #[inline] - fn into_partial_reflect(self: #bevy_reflect_path::__macro_exports::alloc_utils::Box) -> #bevy_reflect_path::__macro_exports::alloc_utils::Box { - self - } - - #[inline] - fn as_partial_reflect(&self) -> &dyn #bevy_reflect_path::PartialReflect { - self - } - - #[inline] - fn as_partial_reflect_mut(&mut self) -> &mut dyn #bevy_reflect_path::PartialReflect { - self - } - #hash_fn #partial_eq_fn diff --git a/crates/bevy_reflect/src/array.rs b/crates/bevy_reflect/src/array.rs index 95e0b56e03d03..4ddae73796c90 100644 --- a/crates/bevy_reflect/src/array.rs +++ b/crates/bevy_reflect/src/array.rs @@ -204,21 +204,6 @@ impl PartialReflect for DynamicArray { self.represented_type } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - #[inline] - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - #[inline] - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Err(self) } @@ -537,7 +522,7 @@ mod tests { usize::MAX }; - let b = Box::new([(); SIZE]).into_reflect(); + let b = (Box::new([(); SIZE]) as Box).into_reflect(); let array = b.reflect_ref().as_array().unwrap(); diff --git a/crates/bevy_reflect/src/cast.rs b/crates/bevy_reflect/src/cast.rs index 3bf527eb3df09..98a62b5ab5727 100644 --- a/crates/bevy_reflect/src/cast.rs +++ b/crates/bevy_reflect/src/cast.rs @@ -28,34 +28,6 @@ impl CastPartialReflect for Box { } } -impl CastPartialReflect for dyn PartialReflect { - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - - fn into_partial_reflect(self: Box) -> Box { - self - } -} - -impl CastPartialReflect for dyn Reflect { - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self.as_partial_reflect() - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self.as_partial_reflect_mut() - } - - fn into_partial_reflect(self: Box) -> Box { - self.into_partial_reflect() - } -} - impl CastPartialReflect for Box { fn as_partial_reflect(&self) -> &dyn PartialReflect { self.as_ref() @@ -104,20 +76,6 @@ impl CastReflect for Box { } } -impl CastReflect for dyn Reflect { - fn as_reflect(&self) -> &dyn Reflect { - self - } - - fn as_reflect_mut(&mut self) -> &mut dyn Reflect { - self - } - - fn into_reflect(self: Box) -> Box { - self - } -} - impl CastReflect for Box { fn as_reflect(&self) -> &dyn Reflect { self.as_ref() diff --git a/crates/bevy_reflect/src/enums/dynamic_enum.rs b/crates/bevy_reflect/src/enums/dynamic_enum.rs index 5758bde10239a..ef5366cde8b94 100644 --- a/crates/bevy_reflect/src/enums/dynamic_enum.rs +++ b/crates/bevy_reflect/src/enums/dynamic_enum.rs @@ -296,21 +296,6 @@ impl PartialReflect for DynamicEnum { self.represented_type } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - #[inline] - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - #[inline] - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Err(self) } diff --git a/crates/bevy_reflect/src/func/dynamic_function.rs b/crates/bevy_reflect/src/func/dynamic_function.rs index ed4258aa9bcb9..6b145d7a8632d 100644 --- a/crates/bevy_reflect/src/func/dynamic_function.rs +++ b/crates/bevy_reflect/src/func/dynamic_function.rs @@ -369,18 +369,6 @@ impl PartialReflect for DynamicFunction<'static> { None } - fn into_partial_reflect(self: Box) -> Box { - self - } - - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Err(self) } diff --git a/crates/bevy_reflect/src/impls/alloc/borrow.rs b/crates/bevy_reflect/src/impls/alloc/borrow.rs index 7e61298226bef..031a067c58c41 100644 --- a/crates/bevy_reflect/src/impls/alloc/borrow.rs +++ b/crates/bevy_reflect/src/impls/alloc/borrow.rs @@ -26,19 +26,6 @@ impl PartialReflect for Cow<'static, str> { Some(::type_info()) } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Ok(self) } @@ -207,19 +194,6 @@ impl::type_info()) } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Ok(self) } diff --git a/crates/bevy_reflect/src/impls/alloc/collections/btree/map.rs b/crates/bevy_reflect/src/impls/alloc/collections/btree/map.rs index 95aeb37ffe7cc..2a114010b3891 100644 --- a/crates/bevy_reflect/src/impls/alloc/collections/btree/map.rs +++ b/crates/bevy_reflect/src/impls/alloc/collections/btree/map.rs @@ -100,18 +100,7 @@ where fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { Some(::type_info()) } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } #[inline] fn try_into_reflect(self: Box) -> Result, Box> { Ok(self) diff --git a/crates/bevy_reflect/src/impls/core/panic.rs b/crates/bevy_reflect/src/impls/core/panic.rs index 4407e5068ec75..920af2a444b71 100644 --- a/crates/bevy_reflect/src/impls/core/panic.rs +++ b/crates/bevy_reflect/src/impls/core/panic.rs @@ -29,19 +29,6 @@ impl PartialReflect for &'static Location<'static> { Some(::type_info()) } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Ok(self) } diff --git a/crates/bevy_reflect/src/impls/core/primitives.rs b/crates/bevy_reflect/src/impls/core/primitives.rs index a6e0e6bdcc237..d085b276b523e 100644 --- a/crates/bevy_reflect/src/impls/core/primitives.rs +++ b/crates/bevy_reflect/src/impls/core/primitives.rs @@ -323,19 +323,6 @@ impl PartialReflect for &'static str { Some(::type_info()) } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Ok(self) } @@ -465,19 +452,6 @@ impl P Some(::type_info()) } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Ok(self) } @@ -551,21 +525,6 @@ impl R self } - #[inline] - fn into_reflect(self: Box) -> Box { - self - } - - #[inline] - fn as_reflect(&self) -> &dyn Reflect { - self - } - - #[inline] - fn as_reflect_mut(&mut self) -> &mut dyn Reflect { - self - } - #[inline] fn set(&mut self, value: Box) -> Result<(), Box> { *self = value.take()?; diff --git a/crates/bevy_reflect/src/impls/core/sync.rs b/crates/bevy_reflect/src/impls/core/sync.rs index 5cd46e7dc431d..51c1fa6931fed 100644 --- a/crates/bevy_reflect/src/impls/core/sync.rs +++ b/crates/bevy_reflect/src/impls/core/sync.rs @@ -54,18 +54,6 @@ macro_rules! impl_reflect_for_atomic { Some(::type_info()) } #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - #[inline] - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - #[inline] - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - #[inline] fn try_into_reflect( self: Box, ) -> Result, Box> { diff --git a/crates/bevy_reflect/src/impls/indexmap.rs b/crates/bevy_reflect/src/impls/indexmap.rs index 80a7f7ec57eb8..46da5f6bcea8f 100644 --- a/crates/bevy_reflect/src/impls/indexmap.rs +++ b/crates/bevy_reflect/src/impls/indexmap.rs @@ -117,19 +117,6 @@ where Some(::type_info()) } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - #[inline] fn try_into_reflect(self: Box) -> Result, Box> { Ok(self) @@ -324,19 +311,6 @@ where Some(::type_info()) } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - #[inline] fn try_into_reflect(self: Box) -> Result, Box> { Ok(self) diff --git a/crates/bevy_reflect/src/impls/macros/list.rs b/crates/bevy_reflect/src/impls/macros/list.rs index 131cb7283a193..caec12aa877a4 100644 --- a/crates/bevy_reflect/src/impls/macros/list.rs +++ b/crates/bevy_reflect/src/impls/macros/list.rs @@ -66,20 +66,6 @@ macro_rules! impl_reflect_for_veclike { Some(::type_info()) } - fn into_partial_reflect(self: bevy_platform::prelude::Box) -> bevy_platform::prelude::Box { - self - } - - #[inline] - fn as_partial_reflect(&self) -> &dyn $crate::reflect::PartialReflect { - self - } - - #[inline] - fn as_partial_reflect_mut(&mut self) -> &mut dyn $crate::reflect::PartialReflect { - self - } - fn try_into_reflect( self: bevy_platform::prelude::Box, ) -> Result, bevy_platform::prelude::Box> { diff --git a/crates/bevy_reflect/src/impls/macros/map.rs b/crates/bevy_reflect/src/impls/macros/map.rs index 46e062ad40427..0183853ab73d9 100644 --- a/crates/bevy_reflect/src/impls/macros/map.rs +++ b/crates/bevy_reflect/src/impls/macros/map.rs @@ -100,19 +100,6 @@ macro_rules! impl_reflect_for_hashmap { Some(::type_info()) } - #[inline] - fn into_partial_reflect(self: bevy_platform::prelude::Box) -> bevy_platform::prelude::Box { - self - } - - fn as_partial_reflect(&self) -> &dyn $crate::reflect::PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn $crate::reflect::PartialReflect { - self - } - fn try_into_reflect( self: bevy_platform::prelude::Box, ) -> Result, bevy_platform::prelude::Box> { diff --git a/crates/bevy_reflect/src/impls/macros/set.rs b/crates/bevy_reflect/src/impls/macros/set.rs index 940d9a5d9a322..b8207cb8459bc 100644 --- a/crates/bevy_reflect/src/impls/macros/set.rs +++ b/crates/bevy_reflect/src/impls/macros/set.rs @@ -74,19 +74,6 @@ macro_rules! impl_reflect_for_hashset { Some(::type_info()) } - #[inline] - fn into_partial_reflect(self: bevy_platform::prelude::Box) -> bevy_platform::prelude::Box { - self - } - - fn as_partial_reflect(&self) -> &dyn $crate::reflect::PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn $crate::reflect::PartialReflect { - self - } - #[inline] fn try_into_reflect( self: bevy_platform::prelude::Box, diff --git a/crates/bevy_reflect/src/impls/smallvec.rs b/crates/bevy_reflect/src/impls/smallvec.rs index e312f9d8031d9..159088c88e6fa 100644 --- a/crates/bevy_reflect/src/impls/smallvec.rs +++ b/crates/bevy_reflect/src/impls/smallvec.rs @@ -87,19 +87,6 @@ where Some(::type_info()) } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Ok(self) } diff --git a/crates/bevy_reflect/src/impls/std/path.rs b/crates/bevy_reflect/src/impls/std/path.rs index d9796c40e68ee..112c07417de82 100644 --- a/crates/bevy_reflect/src/impls/std/path.rs +++ b/crates/bevy_reflect/src/impls/std/path.rs @@ -35,19 +35,6 @@ impl PartialReflect for &'static Path { Some(::type_info()) } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Ok(self) } @@ -145,19 +132,6 @@ impl PartialReflect for Cow<'static, Path> { Some(::type_info()) } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Ok(self) } diff --git a/crates/bevy_reflect/src/list.rs b/crates/bevy_reflect/src/list.rs index 4cc728b235b7e..cb5cd8e2ba8b0 100644 --- a/crates/bevy_reflect/src/list.rs +++ b/crates/bevy_reflect/src/list.rs @@ -12,11 +12,10 @@ use bevy_reflect_derive::impl_type_path; use crate::generics::impl_generic_info_methods; use crate::{ - type_info::impl_type_methods, utility::reflect_hasher, ApplyError, FromReflect, Generics, - MaybeTyped, PartialReflect, Reflect, ReflectKind, ReflectMut, ReflectOwned, ReflectRef, Type, - TypeInfo, TypePath, + cast::impl_cast_partial_reflect, type_info::impl_type_methods, utility::reflect_hasher, + ApplyError, FromReflect, Generics, MaybeTyped, PartialReflect, Reflect, ReflectKind, + ReflectMut, ReflectOwned, ReflectRef, Type, TypeInfo, TypePath, }; -use crate::cast::impl_cast_partial_reflect; /// A trait used to power [list-like] operations via [reflection]. /// @@ -258,21 +257,6 @@ impl PartialReflect for DynamicList { self.represented_type } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - #[inline] - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - #[inline] - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Err(self) } @@ -580,7 +564,7 @@ mod tests { // If compiled in release mode, verify we dont overflow usize::MAX }; - let b = Box::new(vec![(); SIZE]).into_reflect(); + let b = (Box::new(vec![(); SIZE]) as Box).into_reflect(); let list = b.reflect_ref().as_list().unwrap(); diff --git a/crates/bevy_reflect/src/map.rs b/crates/bevy_reflect/src/map.rs index cb04322d2378e..658271a2e9be7 100644 --- a/crates/bevy_reflect/src/map.rs +++ b/crates/bevy_reflect/src/map.rs @@ -339,21 +339,6 @@ impl PartialReflect for DynamicMap { self.represented_type } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - #[inline] - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - #[inline] - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Err(self) } diff --git a/crates/bevy_reflect/src/reflect.rs b/crates/bevy_reflect/src/reflect.rs index 4e40b81e4370d..b4b73f993d286 100644 --- a/crates/bevy_reflect/src/reflect.rs +++ b/crates/bevy_reflect/src/reflect.rs @@ -98,7 +98,7 @@ impl From for ApplyError { message = "`{Self}` does not implement `PartialReflect` so cannot be introspected", note = "consider annotating `{Self}` with `#[derive(Reflect)]`" )] -pub trait PartialReflect: DynamicTypePath + Send + Sync +pub trait PartialReflect: CastPartialReflect + DynamicTypePath + Send + Sync where // NB: we don't use `Self: Any` since for downcasting, `Reflect` should be used. Self: 'static, @@ -120,21 +120,6 @@ where /// [`TypeRegistry::get_type_info`]: crate::TypeRegistry::get_type_info fn get_represented_type_info(&self) -> Option<&'static TypeInfo>; - /// Casts this type to a boxed, reflected value. - /// - /// This is useful for coercing trait objects. - fn into_partial_reflect(self: Box) -> Box; - - /// Casts this type to a reflected value. - /// - /// This is useful for coercing trait objects. - fn as_partial_reflect(&self) -> &dyn PartialReflect; - - /// Casts this type to a mutable, reflected value. - /// - /// This is useful for coercing trait objects. - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect; - /// Attempts to cast this type to a boxed, [fully-reflected] value. /// /// [fully-reflected]: Reflect @@ -421,7 +406,7 @@ where message = "`{Self}` does not implement `Reflect` so cannot be fully reflected", note = "consider annotating `{Self}` with `#[derive(Reflect)]`" )] -pub trait Reflect: PartialReflect + DynamicTyped + Any { +pub trait Reflect: PartialReflect + CastReflect + DynamicTyped + Any { /// Returns the value as a [`Box`][core::any::Any]. /// /// For remote wrapper types, this will return the remote type instead. @@ -437,15 +422,6 @@ pub trait Reflect: PartialReflect + DynamicTyped + Any { /// For remote wrapper types, this will return the remote type instead. fn as_any_mut(&mut self) -> &mut dyn Any; - /// Casts this type to a boxed, fully-reflected value. - fn into_reflect(self: Box) -> Box; - - /// Casts this type to a fully-reflected value. - fn as_reflect(&self) -> &dyn Reflect; - - /// Casts this type to a mutable, fully-reflected value. - fn as_reflect_mut(&mut self) -> &mut dyn Reflect; - /// Performs a type-checked assignment of a reflected value to this value. /// /// If `value` does not contain a value of type `T`, returns an `Err` @@ -475,7 +451,7 @@ impl dyn PartialReflect { ) -> Result, Box> { self.try_into_reflect()? .downcast() - .map_err(PartialReflect::into_partial_reflect) + .map_err(CastPartialReflect::into_partial_reflect) } /// Downcasts the value to type `T`, unboxing and consuming the trait object. @@ -632,18 +608,6 @@ macro_rules! impl_full_reflect { self } - fn into_reflect(self: bevy_platform::prelude::Box) -> bevy_platform::prelude::Box { - self - } - - fn as_reflect(&self) -> &dyn $crate::Reflect { - self - } - - fn as_reflect_mut(&mut self) -> &mut dyn $crate::Reflect { - self - } - fn set( &mut self, value: bevy_platform::prelude::Box, @@ -655,4 +619,5 @@ macro_rules! impl_full_reflect { }; } +use crate::cast::{CastPartialReflect, CastReflect}; pub(crate) use impl_full_reflect; diff --git a/crates/bevy_reflect/src/serde/ser/mod.rs b/crates/bevy_reflect/src/serde/ser/mod.rs index a2a3712921f37..efdaa631931ef 100644 --- a/crates/bevy_reflect/src/serde/ser/mod.rs +++ b/crates/bevy_reflect/src/serde/ser/mod.rs @@ -21,6 +21,7 @@ mod tuples; #[cfg(test)] mod tests { use crate::{ + cast::CastPartialReflect, serde::{ReflectSerializer, ReflectSerializerProcessor}, structs::Struct, PartialReflect, Reflect, ReflectSerialize, TypeRegistry, diff --git a/crates/bevy_reflect/src/set.rs b/crates/bevy_reflect/src/set.rs index c1ad911c5c630..2abf17f42c7e9 100644 --- a/crates/bevy_reflect/src/set.rs +++ b/crates/bevy_reflect/src/set.rs @@ -263,21 +263,6 @@ impl PartialReflect for DynamicSet { self.represented_type } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - #[inline] - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - #[inline] - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - #[inline] fn try_into_reflect(self: Box) -> Result, Box> { Err(self) diff --git a/crates/bevy_reflect/src/structs.rs b/crates/bevy_reflect/src/structs.rs index df764a11385ad..4ee7aaa36bba7 100644 --- a/crates/bevy_reflect/src/structs.rs +++ b/crates/bevy_reflect/src/structs.rs @@ -449,21 +449,6 @@ impl PartialReflect for DynamicStruct { self.represented_type } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - #[inline] - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - #[inline] - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Err(self) } diff --git a/crates/bevy_reflect/src/tuple.rs b/crates/bevy_reflect/src/tuple.rs index 0120191bfc7c0..4b34eb3ac762c 100644 --- a/crates/bevy_reflect/src/tuple.rs +++ b/crates/bevy_reflect/src/tuple.rs @@ -289,19 +289,6 @@ impl PartialReflect for DynamicTuple { self.represented_type } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Err(self) } @@ -551,19 +538,6 @@ macro_rules! impl_reflect_tuple { Some(::type_info()) } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Ok(self) } @@ -633,18 +607,6 @@ macro_rules! impl_reflect_tuple { self } - fn into_reflect(self: Box) -> Box { - self - } - - fn as_reflect(&self) -> &dyn Reflect { - self - } - - fn as_reflect_mut(&mut self) -> &mut dyn Reflect { - self - } - fn set(&mut self, value: Box) -> Result<(), Box> { *self = value.take()?; Ok(()) diff --git a/crates/bevy_reflect/src/tuple_struct.rs b/crates/bevy_reflect/src/tuple_struct.rs index f69d5c8bdc5c9..eac5284f0d09d 100644 --- a/crates/bevy_reflect/src/tuple_struct.rs +++ b/crates/bevy_reflect/src/tuple_struct.rs @@ -297,21 +297,6 @@ impl PartialReflect for DynamicTupleStruct { self.represented_type } - #[inline] - fn into_partial_reflect(self: Box) -> Box { - self - } - - #[inline] - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self - } - - #[inline] - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self - } - fn try_into_reflect(self: Box) -> Result, Box> { Err(self) } diff --git a/crates/bevy_scene/src/reflect_utils.rs b/crates/bevy_scene/src/reflect_utils.rs index bf69dd035295a..4813dca81cd9f 100644 --- a/crates/bevy_scene/src/reflect_utils.rs +++ b/crates/bevy_scene/src/reflect_utils.rs @@ -1,4 +1,6 @@ -use bevy_reflect::{PartialReflect, ReflectFromReflect, TypeRegistration}; +use bevy_reflect::{ + cast::CastPartialReflect, PartialReflect, ReflectFromReflect, TypeRegistration, +}; /// Attempts to clone a [`PartialReflect`] value using various methods. /// @@ -14,12 +16,12 @@ pub(super) fn clone_reflect_value( ) -> Box { value .reflect_clone() - .map(PartialReflect::into_partial_reflect) + .map(CastPartialReflect::into_partial_reflect) .unwrap_or_else(|_| { type_registration .data::() .and_then(|fr| fr.from_reflect(value.as_partial_reflect())) - .map(PartialReflect::into_partial_reflect) + .map(CastPartialReflect::into_partial_reflect) .unwrap_or_else(|| value.to_dynamic()) }) } diff --git a/crates/bevy_scene/src/serde.rs b/crates/bevy_scene/src/serde.rs index 4170f2a5414e2..4d486806991d5 100644 --- a/crates/bevy_scene/src/serde.rs +++ b/crates/bevy_scene/src/serde.rs @@ -4,6 +4,7 @@ use crate::{DynamicEntity, DynamicScene}; use bevy_ecs::entity::Entity; use bevy_platform::collections::HashSet; use bevy_reflect::{ + cast::CastPartialReflect, serde::{ ReflectDeserializer, TypeRegistrationDeserializer, TypedReflectDeserializer, TypedReflectSerializer, @@ -497,7 +498,7 @@ impl<'a, 'de> Visitor<'de> for SceneMapVisitor<'a> { .get(registration.type_id()) .and_then(|tr| tr.data::()) .and_then(|fr| fr.from_reflect(value.as_partial_reflect())) - .map(PartialReflect::into_partial_reflect) + .map(CastPartialReflect::into_partial_reflect) .unwrap_or(value); entries.push(value); diff --git a/examples/reflection/dynamic_types.rs b/examples/reflection/dynamic_types.rs index e5ba6b089f34f..5b2fb70ae242e 100644 --- a/examples/reflection/dynamic_types.rs +++ b/examples/reflection/dynamic_types.rs @@ -2,6 +2,7 @@ use bevy::reflect::{ array::DynamicArray, + cast::CastPartialReflect, enums::{DynamicEnum, DynamicVariant}, list::DynamicList, map::DynamicMap, From 1f8b2dc675f5d955cb3bbb4be119b7a8bffb013a Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 14:56:54 -0700 Subject: [PATCH 10/16] Merged impls to simplify custom boxed trait impl --- crates/bevy_reflect/src/cast.rs | 93 ++++++++++++++------------------- 1 file changed, 39 insertions(+), 54 deletions(-) diff --git a/crates/bevy_reflect/src/cast.rs b/crates/bevy_reflect/src/cast.rs index 98a62b5ab5727..096be6c450e44 100644 --- a/crates/bevy_reflect/src/cast.rs +++ b/crates/bevy_reflect/src/cast.rs @@ -2,8 +2,8 @@ use crate::__macro_exports::RegisterForReflection; use crate::utility::GenericTypeInfoCell; use crate::{ - GetTypeRegistration, MaybeTyped, OpaqueInfo, PartialReflect, Reflect, TypeInfo, TypePath, - TypeRegistration, Typed, + GetTypeRegistration, OpaqueInfo, PartialReflect, Reflect, TypeInfo, TypePath, TypeRegistration, + Typed, }; use alloc::boxed::Box; use bevy_reflect_derive::impl_type_path; @@ -14,7 +14,7 @@ pub trait CastPartialReflect: Send + Sync + 'static { fn into_partial_reflect(self: Box) -> Box; } -impl CastPartialReflect for Box { +impl CastPartialReflect for Box { fn as_partial_reflect(&self) -> &dyn PartialReflect { T::as_partial_reflect(self) } @@ -28,41 +28,13 @@ impl CastPartialReflect for Box { } } -impl CastPartialReflect for Box { - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self.as_ref() - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self.as_mut() - } - - fn into_partial_reflect(self: Box) -> Box { - *self - } -} - -impl CastPartialReflect for Box { - fn as_partial_reflect(&self) -> &dyn PartialReflect { - self.as_ref().as_partial_reflect() - } - - fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { - self.as_mut().as_partial_reflect_mut() - } - - fn into_partial_reflect(self: Box) -> Box { - self.into_reflect().into_partial_reflect() - } -} - pub trait CastReflect: CastPartialReflect { fn as_reflect(&self) -> &dyn Reflect; fn as_reflect_mut(&mut self) -> &mut dyn Reflect; fn into_reflect(self: Box) -> Box; } -impl CastReflect for Box { +impl CastReflect for Box { fn as_reflect(&self) -> &dyn Reflect { T::as_reflect(self) } @@ -76,36 +48,16 @@ impl CastReflect for Box { } } -impl CastReflect for Box { - fn as_reflect(&self) -> &dyn Reflect { - self.as_ref() - } - - fn as_reflect_mut(&mut self) -> &mut dyn Reflect { - self.as_mut() - } - - fn into_reflect(self: Box) -> Box { - *self - } -} - impl_type_path!(::alloc::boxed::Box); -impl MaybeTyped for Box {} -impl MaybeTyped for Box {} - -impl Typed for Box { +impl Typed for Box { fn type_info() -> &'static TypeInfo { static CELL: GenericTypeInfoCell = GenericTypeInfoCell::new(); CELL.get_or_insert::(|| TypeInfo::Opaque(OpaqueInfo::new::())) } } -impl RegisterForReflection for Box {} -impl RegisterForReflection for Box {} - -impl GetTypeRegistration for Box { +impl GetTypeRegistration for Box { fn get_type_registration() -> TypeRegistration { TypeRegistration::of::() } @@ -212,4 +164,37 @@ mod tests { let field_info = field.get_represented_type_info().unwrap(); assert!(field_info.ty().is::()); } + + #[test] + fn should_allow_custom_trait_objects() { + trait Equippable: Reflect {} + + impl TypePath for dyn Equippable { + fn type_path() -> &'static str { + "dyn my_crate::Equippable" + } + + fn short_type_path() -> &'static str { + "dyn Equippable" + } + } + + #[derive(Reflect)] + struct Sword(u32); + + impl Equippable for Sword {} + + #[derive(Reflect)] + #[reflect(from_reflect = false)] + struct Player { + weapon: Box, + } + + let player: Box = Box::new(Player { + weapon: Box::new(Sword(123)), + }); + + let weapon = player.field("weapon").unwrap(); + assert!(weapon.reflect_partial_eq(&Sword(123)).unwrap_or_default()); + } } From b2e0d0b4427ee745fed446097ee2f6f5b720b2bd Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 15:15:12 -0700 Subject: [PATCH 11/16] Fixed docs --- crates/bevy_reflect/src/enums/dynamic_enum.rs | 2 +- crates/bevy_reflect/src/lib.rs | 14 +++++--- crates/bevy_reflect/src/type_info.rs | 18 ++++++---- crates/bevy_reflect/src/utility.rs | 36 +++++++++++-------- 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/crates/bevy_reflect/src/enums/dynamic_enum.rs b/crates/bevy_reflect/src/enums/dynamic_enum.rs index ef5366cde8b94..60d5a2d3d8ad0 100644 --- a/crates/bevy_reflect/src/enums/dynamic_enum.rs +++ b/crates/bevy_reflect/src/enums/dynamic_enum.rs @@ -51,7 +51,7 @@ impl From<()> for DynamicVariant { /// # Example /// /// ``` -/// # use bevy_reflect::{enums::{DynamicEnum, DynamicVariant}, Reflect, PartialReflect}; +/// # use bevy_reflect::{cast::CastPartialReflect, enums::{DynamicEnum, DynamicVariant}, Reflect, PartialReflect}; /// /// // The original enum value /// let mut value: Option = Some(123); diff --git a/crates/bevy_reflect/src/lib.rs b/crates/bevy_reflect/src/lib.rs index ce4f1de189005..a284aa1d3e10d 100644 --- a/crates/bevy_reflect/src/lib.rs +++ b/crates/bevy_reflect/src/lib.rs @@ -69,9 +69,9 @@ //! Since `T: Reflect` implies `T: PartialReflect`, conversion from a `dyn Reflect` to a `dyn PartialReflect` //! trait object (upcasting) is infallible and can be performed with one of the following methods. //! Note that these are temporary while [the language feature for dyn upcasting coercion] is experimental: -//! * [`PartialReflect::as_partial_reflect`] for `&dyn PartialReflect` -//! * [`PartialReflect::as_partial_reflect_mut`] for `&mut dyn PartialReflect` -//! * [`PartialReflect::into_partial_reflect`] for `Box` +//! * [`CastPartialReflect::as_partial_reflect`] for `&dyn PartialReflect` +//! * [`CastPartialReflect::as_partial_reflect_mut`] for `&mut dyn PartialReflect` +//! * [`CastPartialReflect::into_partial_reflect`] for `Box` //! //! For conversion in the other direction — downcasting `dyn PartialReflect` to `dyn Reflect` — //! there are fallible methods: @@ -164,8 +164,8 @@ //! ``` //! //! And to go back to a general-purpose `dyn PartialReflect`, -//! we can just use the matching [`PartialReflect::as_partial_reflect`], [`PartialReflect::as_partial_reflect_mut`], -//! or [`PartialReflect::into_partial_reflect`] methods. +//! we can just use the matching [`CastPartialReflect::as_partial_reflect`], [`CastPartialReflect::as_partial_reflect_mut`], +//! or [`CastPartialReflect::into_partial_reflect`] methods. //! //! ## Opaque Types //! @@ -412,6 +412,7 @@ //! ``` //! # use serde::de::DeserializeSeed; //! # use bevy_reflect::{ +//! # cast::CastPartialReflect, //! # serde::{ReflectSerializer, ReflectDeserializer}, //! # Reflect, PartialReflect, FromReflect, TypeRegistry //! # }; @@ -539,6 +540,9 @@ //! [the type registry]: #type-registration //! [runtime cost]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#trait-objects-perform-dynamic-dispatch //! [the language feature for dyn upcasting coercion]: https://github.com/rust-lang/rust/issues/65991 +//! [`CastPartialReflect::as_partial_reflect`]: cast::CastPartialReflect::as_partial_reflect +//! [`CastPartialReflect::as_partial_reflect_mut`]: cast::CastPartialReflect::as_partial_reflect_mut +//! [`CastPartialReflect::into_partial_reflect`]: cast::CastPartialReflect::into_partial_reflect //! [derive macro]: derive@crate::Reflect //! [`'static` lifetime]: https://doc.rust-lang.org/rust-by-example/scope/lifetime/static_lifetime.html#trait-bound //! [`Tuple`]: crate::tuple::Tuple diff --git a/crates/bevy_reflect/src/type_info.rs b/crates/bevy_reflect/src/type_info.rs index da3ba5144b9e1..e7eee9ed2a607 100644 --- a/crates/bevy_reflect/src/type_info.rs +++ b/crates/bevy_reflect/src/type_info.rs @@ -39,7 +39,7 @@ use thiserror::Error; /// /// ``` /// # use core::any::Any; -/// # use bevy_reflect::{DynamicTypePath, NamedField, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, structs::StructInfo, TypeInfo, TypePath, OpaqueInfo, ApplyError}; +/// # use bevy_reflect::{cast::{CastPartialReflect, CastReflect}, DynamicTypePath, NamedField, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, structs::StructInfo, TypeInfo, TypePath, OpaqueInfo, ApplyError}; /// # use bevy_reflect::utility::NonGenericTypeInfoCell; /// use bevy_reflect::Typed; /// @@ -68,9 +68,6 @@ use thiserror::Error; /// # } /// # impl PartialReflect for MyStruct { /// # fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { todo!() } -/// # fn into_partial_reflect(self: Box) -> Box { todo!() } -/// # fn as_partial_reflect(&self) -> &dyn PartialReflect { todo!() } -/// # fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { todo!() } /// # fn try_into_reflect(self: Box) -> Result, Box> { todo!() } /// # fn try_as_reflect(&self) -> Option<&dyn Reflect> { todo!() } /// # fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> { todo!() } @@ -83,11 +80,18 @@ use thiserror::Error; /// # fn into_any(self: Box) -> Box { todo!() } /// # fn as_any(&self) -> &dyn Any { todo!() } /// # fn as_any_mut(&mut self) -> &mut dyn Any { todo!() } -/// # fn into_reflect(self: Box) -> Box { todo!() } -/// # fn as_reflect(&self) -> &dyn Reflect { todo!() } -/// # fn as_reflect_mut(&mut self) -> &mut dyn Reflect { todo!() } /// # fn set(&mut self, value: Box) -> Result<(), Box> { todo!() } /// # } +/// # impl CastPartialReflect for MyStruct { +/// # fn as_partial_reflect(&self) -> &dyn PartialReflect { self } +/// # fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { self } +/// # fn into_partial_reflect(self: Box) -> Box { self } +/// # } +/// # impl CastReflect for MyStruct { +/// # fn as_reflect(&self) -> &dyn Reflect { self } +/// # fn as_reflect_mut(&mut self) -> &mut dyn Reflect { self } +/// # fn into_reflect(self: Box) -> Box { self } +/// # } /// ``` /// /// [`Reflectable`]: crate::Reflectable diff --git a/crates/bevy_reflect/src/utility.rs b/crates/bevy_reflect/src/utility.rs index 65a45cf797aa6..8fefe8cb331cc 100644 --- a/crates/bevy_reflect/src/utility.rs +++ b/crates/bevy_reflect/src/utility.rs @@ -56,7 +56,7 @@ mod sealed { /// /// ``` /// # use core::any::Any; -/// # use bevy_reflect::{DynamicTypePath, NamedField, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, structs::StructInfo, Typed, TypeInfo, TypePath, ApplyError}; +/// # use bevy_reflect::{cast::{CastPartialReflect, CastReflect}, DynamicTypePath, NamedField, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, structs::StructInfo, Typed, TypeInfo, TypePath, ApplyError}; /// use bevy_reflect::utility::NonGenericTypeInfoCell; /// /// struct Foo { @@ -79,9 +79,6 @@ mod sealed { /// # } /// # impl PartialReflect for Foo { /// # fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { todo!() } -/// # fn into_partial_reflect(self: Box) -> Box { todo!() } -/// # fn as_partial_reflect(&self) -> &dyn PartialReflect { todo!() } -/// # fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { todo!() } /// # fn try_into_reflect(self: Box) -> Result, Box> { todo!() } /// # fn try_as_reflect(&self) -> Option<&dyn Reflect> { todo!() } /// # fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> { todo!() } @@ -94,11 +91,18 @@ mod sealed { /// # fn into_any(self: Box) -> Box { todo!() } /// # fn as_any(&self) -> &dyn Any { todo!() } /// # fn as_any_mut(&mut self) -> &mut dyn Any { todo!() } -/// # fn into_reflect(self: Box) -> Box { todo!() } -/// # fn as_reflect(&self) -> &dyn Reflect { todo!() } -/// # fn as_reflect_mut(&mut self) -> &mut dyn Reflect { todo!() } /// # fn set(&mut self, value: Box) -> Result<(), Box> { todo!() } /// # } +/// # impl CastPartialReflect for Foo { +/// # fn as_partial_reflect(&self) -> &dyn PartialReflect { self } +/// # fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { self } +/// # fn into_partial_reflect(self: Box) -> Box { self } +/// # } +/// # impl CastReflect for Foo { +/// # fn as_reflect(&self) -> &dyn Reflect { self } +/// # fn as_reflect_mut(&mut self) -> &mut dyn Reflect { self } +/// # fn into_reflect(self: Box) -> Box { self } +/// # } /// ``` /// /// [`TypePath`]: crate::TypePath @@ -144,7 +148,7 @@ impl Default for NonGenericTypeCell { /// /// ``` /// # use core::any::Any; -/// # use bevy_reflect::{DynamicTypePath, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, tuple_struct::TupleStructInfo, Typed, TypeInfo, TypePath, UnnamedField, ApplyError, Generics, TypeParamInfo}; +/// # use bevy_reflect::{cast::{CastPartialReflect, CastReflect}, DynamicTypePath, PartialReflect, Reflect, ReflectMut, ReflectOwned, ReflectRef, tuple_struct::TupleStructInfo, Typed, TypeInfo, TypePath, UnnamedField, ApplyError, Generics, TypeParamInfo}; /// use bevy_reflect::utility::GenericTypeInfoCell; /// /// struct Foo(T); @@ -166,9 +170,6 @@ impl Default for NonGenericTypeCell { /// # } /// # impl PartialReflect for Foo { /// # fn get_represented_type_info(&self) -> Option<&'static TypeInfo> { todo!() } -/// # fn into_partial_reflect(self: Box) -> Box { todo!() } -/// # fn as_partial_reflect(&self) -> &dyn PartialReflect { todo!() } -/// # fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { todo!() } /// # fn try_into_reflect(self: Box) -> Result, Box> { todo!() } /// # fn try_as_reflect(&self) -> Option<&dyn Reflect> { todo!() } /// # fn try_as_reflect_mut(&mut self) -> Option<&mut dyn Reflect> { todo!() } @@ -181,11 +182,18 @@ impl Default for NonGenericTypeCell { /// # fn into_any(self: Box) -> Box { todo!() } /// # fn as_any(&self) -> &dyn Any { todo!() } /// # fn as_any_mut(&mut self) -> &mut dyn Any { todo!() } -/// # fn into_reflect(self: Box) -> Box { todo!() } -/// # fn as_reflect(&self) -> &dyn Reflect { todo!() } -/// # fn as_reflect_mut(&mut self) -> &mut dyn Reflect { todo!() } /// # fn set(&mut self, value: Box) -> Result<(), Box> { todo!() } /// # } +/// # impl CastPartialReflect for Foo { +/// # fn as_partial_reflect(&self) -> &dyn PartialReflect { self } +/// # fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect { self } +/// # fn into_partial_reflect(self: Box) -> Box { self } +/// # } +/// # impl CastReflect for Foo { +/// # fn as_reflect(&self) -> &dyn Reflect { self } +/// # fn as_reflect_mut(&mut self) -> &mut dyn Reflect { self } +/// # fn into_reflect(self: Box) -> Box { self } +/// # } /// ``` /// /// Implementing [`TypePath`] with generics. From 6699f1d3397617541d2fb5af85d41715e0ce873c Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 15:21:30 -0700 Subject: [PATCH 12/16] Added docs --- crates/bevy_reflect/src/cast.rs | 105 +++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) diff --git a/crates/bevy_reflect/src/cast.rs b/crates/bevy_reflect/src/cast.rs index 096be6c450e44..c69c6ac6f6073 100644 --- a/crates/bevy_reflect/src/cast.rs +++ b/crates/bevy_reflect/src/cast.rs @@ -1,4 +1,57 @@ -use crate::__macro_exports::RegisterForReflection; +//! Traits for casting types to [`dyn PartialReflect`] and [`dyn Reflect`] trait objects. +//! +//! These traits are used internally by the [derive macro] and other [`Reflect`] implementations, +//! to allow for transparent wrapper types, such as [`Box`], to be used as fields. +//! +//! # Custom Trait Objects +//! +//! These traits also enable the usage of custom trait objects as reflected fields. +//! +//! The only requirements are: +//! - The trait must have at least [`CastPartialReflect`] as a supertrait. +//! This includes using [`CastReflect`], [`PartialReflect`], or [`Reflect`] as supertraits, +//! since they are all subtraits of [`CastPartialReflect`]. +//! - The trait must implement [`TypePath`] for its trait object +//! +//! ``` +//! # use bevy_reflect::{PartialReflect, Reflect, Struct, TypePath}; +//! # +//! trait Equippable: PartialReflect {} +//! +//! impl TypePath for dyn Equippable { +//! fn type_path() -> &'static str { +//! "dyn my_crate::Equippable" +//! } +//! +//! fn short_type_path() -> &'static str { +//! "dyn Equippable" +//! } +//! } +//! +//! #[derive(Reflect)] +//! struct Sword(u32); +//! +//! impl Equippable for Sword {} +//! +//! #[derive(Reflect)] +//! #[reflect(from_reflect = false)] +//! struct Player { +//! weapon: Box, +//! } +//! +//! let player: Box = Box::new(Player { +//! weapon: Box::new(Sword(123)), +//! }); +//! +//! let weapon = player.field("weapon").unwrap(); +//! assert!(weapon.reflect_partial_eq(&Sword(123)).unwrap_or_default()); +//! ``` +//! +//! [`dyn PartialReflect`]: PartialReflect +//! [`dyn Reflect`]: crate::Reflect +//! [derive macro]: derive@crate::Reflect +//! [`Reflect`]: crate::Reflect +//! [`TypePath`]: crate::TypePath use crate::utility::GenericTypeInfoCell; use crate::{ @@ -8,9 +61,33 @@ use crate::{ use alloc::boxed::Box; use bevy_reflect_derive::impl_type_path; +/// A trait used to cast `Self` to a [`dyn PartialReflect`] trait object. +/// +/// This is automatically implemented for any type that [derives `Reflect`], +/// as well as [`Box`] where `T` also implements [`CastPartialReflect`]. +/// +/// [`dyn PartialReflect`]: PartialReflect +/// [derives `Reflect`]: derive@crate::Reflect pub trait CastPartialReflect: Send + Sync + 'static { + /// Casts this type to a [`dyn PartialReflect`] reference. + /// + /// This is useful for coercing trait objects. + /// + /// [`dyn PartialReflect`]: PartialReflect fn as_partial_reflect(&self) -> &dyn PartialReflect; + + /// Casts this type to a mutable [`dyn PartialReflect`] reference. + /// + /// This is useful for coercing trait objects. + /// + /// [`dyn PartialReflect`]: PartialReflect fn as_partial_reflect_mut(&mut self) -> &mut dyn PartialReflect; + + /// Casts this type into a boxed [`dyn PartialReflect`] instance. + /// + /// This is useful for coercing trait objects. + /// + /// [`dyn PartialReflect`]: PartialReflect fn into_partial_reflect(self: Box) -> Box; } @@ -28,9 +105,33 @@ impl CastPartialReflect for Box { } } +/// A trait used to cast `Self` to a [`dyn Reflect`] trait object. +/// +/// This is automatically implemented for any type that [derives `Reflect`], +/// as well as [`Box`] where `T` also implements [`CastReflect`]. +/// +/// [`dyn Reflect`]: Reflect +/// [derives `Reflect`]: derive@crate::Reflect pub trait CastReflect: CastPartialReflect { + /// Casts this type to a [`dyn Reflect`] reference. + /// + /// This is useful for coercing trait objects. + /// + /// [`dyn Reflect`]: Reflect fn as_reflect(&self) -> &dyn Reflect; + + /// Casts this type to a mutable [`dyn Reflect`] reference. + /// + /// This is useful for coercing trait objects. + /// + /// [`dyn Reflect`]: Reflect fn as_reflect_mut(&mut self) -> &mut dyn Reflect; + + /// Casts this type into a boxed [`dyn Reflect`] instance. + /// + /// This is useful for coercing trait objects. + /// + /// [`dyn Reflect`]: Reflect fn into_reflect(self: Box) -> Box; } @@ -167,7 +268,7 @@ mod tests { #[test] fn should_allow_custom_trait_objects() { - trait Equippable: Reflect {} + trait Equippable: CastPartialReflect {} impl TypePath for dyn Equippable { fn type_path() -> &'static str { From f51b6f6f177fb52a801b1c16ff025d6dca0f0afb Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 15:22:01 -0700 Subject: [PATCH 13/16] Added trivial `#[inline]` annotations --- crates/bevy_reflect/src/cast.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/bevy_reflect/src/cast.rs b/crates/bevy_reflect/src/cast.rs index c69c6ac6f6073..be7de53714d67 100644 --- a/crates/bevy_reflect/src/cast.rs +++ b/crates/bevy_reflect/src/cast.rs @@ -167,14 +167,17 @@ impl GetTypeRegistration for Box { macro_rules! impl_cast_partial_reflect { ($(<$($id:ident),* $(,)?>)? for $ty:ty $(where $($tt:tt)*)?) => { impl $(<$($id),*>)? $crate::cast::CastPartialReflect for $ty $(where $($tt)*)? { + #[inline] fn as_partial_reflect(&self) -> &dyn $crate::PartialReflect { self } + #[inline] fn as_partial_reflect_mut(&mut self) -> &mut dyn $crate::PartialReflect { self } + #[inline] fn into_partial_reflect(self: ::alloc::boxed::Box) -> ::alloc::boxed::Box { self } @@ -190,14 +193,17 @@ macro_rules! impl_casting_traits { $crate::cast::impl_cast_partial_reflect!($(<$($id),*>)? for $ty $(where $($tt)*)?); impl $(<$($id),*>)? $crate::cast::CastReflect for $ty $(where $($tt)*)? { + #[inline] fn as_reflect(&self) -> &dyn $crate::Reflect { self } + #[inline] fn as_reflect_mut(&mut self) -> &mut dyn $crate::Reflect { self } + #[inline] fn into_reflect(self: ::alloc::boxed::Box) -> ::alloc::boxed::Box { self } From 908f25b3c158ec0d2b214f542f1271e7e3e6c7ae Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 16:28:06 -0700 Subject: [PATCH 14/16] Added test for type parameters --- crates/bevy_reflect/src/cast.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/crates/bevy_reflect/src/cast.rs b/crates/bevy_reflect/src/cast.rs index be7de53714d67..484229d28559f 100644 --- a/crates/bevy_reflect/src/cast.rs +++ b/crates/bevy_reflect/src/cast.rs @@ -272,6 +272,25 @@ mod tests { assert!(field_info.ty().is::()); } + #[test] + fn should_allow_boxed_type_parameter() { + #[derive(Reflect)] + #[reflect(from_reflect = false)] + struct MyStruct { + value: T, + } + + let my_struct: Box = Box::new(MyStruct { + value: Box::new(123_i32), + }); + + let field = my_struct.field("value").unwrap(); + assert_eq!(field.try_downcast_ref::(), Some(&123)); + + let field_info = field.get_represented_type_info().unwrap(); + assert!(field_info.ty().is::()); + } + #[test] fn should_allow_custom_trait_objects() { trait Equippable: CastPartialReflect {} From e93930239e38de7555d7add5a4a009920933ac90 Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 16:42:46 -0700 Subject: [PATCH 15/16] Added custom `diagnostic::on_unimplemented` attributes --- crates/bevy_reflect/src/cast.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crates/bevy_reflect/src/cast.rs b/crates/bevy_reflect/src/cast.rs index 484229d28559f..1855ec5d07b6a 100644 --- a/crates/bevy_reflect/src/cast.rs +++ b/crates/bevy_reflect/src/cast.rs @@ -68,6 +68,10 @@ use bevy_reflect_derive::impl_type_path; /// /// [`dyn PartialReflect`]: PartialReflect /// [derives `Reflect`]: derive@crate::Reflect +#[diagnostic::on_unimplemented( + message = "`{Self}` does not implement `CastPartialReflect` so cannot be cast to `dyn PartialReflect`", + note = "consider annotating `{Self}` with `#[derive(Reflect)]`" +)] pub trait CastPartialReflect: Send + Sync + 'static { /// Casts this type to a [`dyn PartialReflect`] reference. /// @@ -112,6 +116,10 @@ impl CastPartialReflect for Box { /// /// [`dyn Reflect`]: Reflect /// [derives `Reflect`]: derive@crate::Reflect +#[diagnostic::on_unimplemented( + message = "`{Self}` does not implement `CastReflect` so cannot be cast to `dyn Reflect`", + note = "consider annotating `{Self}` with `#[derive(Reflect)]`" +)] pub trait CastReflect: CastPartialReflect { /// Casts this type to a [`dyn Reflect`] reference. /// From 806c86a10dfeea8c211609322c5ba5fbd01a7e6f Mon Sep 17 00:00:00 2001 From: Gino Valente Date: Sun, 29 Sep 2024 16:43:03 -0700 Subject: [PATCH 16/16] Fixed compile fail tests --- .../compile_fail/tests/reflect_derive/generics_fail.rs | 1 + .../compile_fail/tests/reflect_remote/nested_fail.rs | 9 +++------ .../compile_fail/tests/reflect_remote/nested_pass.rs | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/crates/bevy_reflect/compile_fail/tests/reflect_derive/generics_fail.rs b/crates/bevy_reflect/compile_fail/tests/reflect_derive/generics_fail.rs index 497ffe29257cf..fb54473daa973 100644 --- a/crates/bevy_reflect/compile_fail/tests/reflect_derive/generics_fail.rs +++ b/crates/bevy_reflect/compile_fail/tests/reflect_derive/generics_fail.rs @@ -17,6 +17,7 @@ fn main() { let mut foo: Box = Box::new(Foo:: { a: NoReflect(42.0) }); //~^ ERROR: `NoReflect` does not implement `GetTypeRegistration` so cannot provide type registration information //~| ERROR: `NoReflect` does not implement `Typed` so cannot provide static type information + //~| ERROR: `NoReflect` does not implement `CastPartialReflect` so cannot be cast to `dyn PartialReflect` // foo doesn't implement Reflect because NoReflect doesn't implement Reflect foo.get_field::("a").unwrap(); diff --git a/crates/bevy_reflect/compile_fail/tests/reflect_remote/nested_fail.rs b/crates/bevy_reflect/compile_fail/tests/reflect_remote/nested_fail.rs index 391258ccc6507..3c0f37395dac7 100644 --- a/crates/bevy_reflect/compile_fail/tests/reflect_remote/nested_fail.rs +++ b/crates/bevy_reflect/compile_fail/tests/reflect_remote/nested_fail.rs @@ -19,16 +19,13 @@ mod missing_attribute { } mod incorrect_inner_type { - use bevy_reflect::{FromReflect, GetTypeRegistration, reflect_remote}; + use bevy_reflect::{FromReflect, GetTypeRegistration, Reflect, reflect_remote}; #[reflect_remote(super::external_crate::TheirOuter)] - //~^ ERROR: `TheirInner` does not implement `PartialReflect` so cannot be introspected - //~| ERROR: `TheirInner` does not implement `PartialReflect` so cannot be introspected - //~| ERROR: `TheirInner` does not implement `PartialReflect` so cannot be introspected - //~| ERROR: `TheirInner` does not implement `TypePath` so cannot provide dynamic type path information + //~^ ERROR: `TheirInner` does not implement `CastPartialReflect` so cannot be cast to `dyn PartialReflect` //~| ERROR: `?` operator has incompatible types //~| ERROR: mismatched types - struct MyOuter { + struct MyOuter { // Reason: Should not use `MyInner` directly pub inner: MyInner, //~^ ERROR: mismatched types diff --git a/crates/bevy_reflect/compile_fail/tests/reflect_remote/nested_pass.rs b/crates/bevy_reflect/compile_fail/tests/reflect_remote/nested_pass.rs index cd79ede57ab5d..7a5d56f954004 100644 --- a/crates/bevy_reflect/compile_fail/tests/reflect_remote/nested_pass.rs +++ b/crates/bevy_reflect/compile_fail/tests/reflect_remote/nested_pass.rs @@ -9,7 +9,7 @@ mod external_crate { } #[reflect_remote(external_crate::TheirOuter)] -struct MyOuter { +struct MyOuter { #[reflect(remote = MyInner)] pub inner: external_crate::TheirInner, }