Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[Merged by Bors] - Make Reflect safe to implement #5010

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9356871
Initial commit
PROMETHIA-27 Jun 14, 2022
c764de1
Made core changes to `Reflect`
PROMETHIA-27 Jun 14, 2022
9a71ebf
Updated impls until it compiles again
PROMETHIA-27 Jun 14, 2022
47e6802
Got tests compiling and passing
PROMETHIA-27 Jun 14, 2022
479e63d
Added downcast test
PROMETHIA-27 Jun 14, 2022
ff804f7
Remove missed safety comment
PROMETHIA-27 Jun 14, 2022
4611cc9
Updated example to use `Reflect::type_id()`
PROMETHIA-27 Jun 14, 2022
1916a2f
Type ID -> `TypeId`
PROMETHIA-27 Jun 14, 2022
4bcfc1f
Made type_id() impl default
PROMETHIA-27 Jun 14, 2022
2a7d0f0
Removed unused imports
PROMETHIA-27 Jun 14, 2022
6a04778
Type Name -> type name
PROMETHIA-27 Jun 17, 2022
cad5074
Merge branch 'bevyengine:main' into make-reflect-safe
PROMETHIA-27 Jun 21, 2022
05d01f9
change to better naming scheme
PROMETHIA-27 Jun 21, 2022
1073a84
Merge branch 'make-reflect-safe' of https://github.com/PROMETHIA-27/b…
PROMETHIA-27 Jun 21, 2022
48803b3
fixing ambiguities
PROMETHIA-27 Jun 21, 2022
e79a8c3
Remove unnecessary TypeId imports
PROMETHIA-27 Jun 21, 2022
bde44f2
Add `represents` method to `dyn Reflect`
PROMETHIA-27 Jun 26, 2022
ced94c7
underlying_type_id -> type_id
PROMETHIA-27 Jun 26, 2022
4df85c4
Merge branch 'bevyengine:main' into make-reflect-safe
PROMETHIA-27 Jun 26, 2022
03c97b4
Merge branch 'make-reflect-safe' of https://github.com/PROMETHIA-27/b…
PROMETHIA-27 Jun 26, 2022
cec23c0
Fix slightly broken test
PROMETHIA-27 Jun 26, 2022
2ae01fb
Un-fixing broken test
PROMETHIA-27 Jun 26, 2022
481823f
underlying_type_id -> type_id
PROMETHIA-27 Jun 26, 2022
29a9379
Doc links
PROMETHIA-27 Jun 27, 2022
7b66ee8
as_mut_any -> as_any_mut
PROMETHIA-27 Jun 27, 2022
2f557c1
Removed invalid doc links
PROMETHIA-27 Jun 27, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ impl ReflectTraits {
match &self.partial_eq {
TraitImpl::Implemented => Some(quote! {
fn reflect_partial_eq(&self, value: &dyn #bevy_reflect_path::Reflect) -> Option<bool> {
let value = value.any();
let value = value.as_any();
if let Some(value) = value.downcast_ref::<Self>() {
Some(std::cmp::PartialEq::eq(self, value))
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub(crate) fn impl_value(
TokenStream::from(quote! {
impl #impl_generics #bevy_reflect_path::FromReflect for #type_name #ty_generics #where_clause {
fn from_reflect(reflect: &dyn #bevy_reflect_path::Reflect) -> Option<Self> {
Some(reflect.any().downcast_ref::<#type_name #ty_generics>()?.clone())
Some(reflect.as_any().downcast_ref::<#type_name #ty_generics>()?.clone())
}
}
})
Expand Down
40 changes: 27 additions & 13 deletions crates/bevy_reflect/bevy_reflect_derive/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@ pub(crate) fn impl_struct(derive_data: &ReflectDeriveData) -> TokenStream {
}
}

// SAFE: any and any_mut both return self
unsafe impl #impl_generics #bevy_reflect_path::Reflect for #struct_name #ty_generics #where_clause {
impl #impl_generics #bevy_reflect_path::Reflect for #struct_name #ty_generics #where_clause {
#[inline]
fn type_name(&self) -> &str {
std::any::type_name::<Self>()
Expand All @@ -138,11 +137,17 @@ pub(crate) fn impl_struct(derive_data: &ReflectDeriveData) -> TokenStream {
}

#[inline]
fn any(&self) -> &dyn std::any::Any {
fn into_any(self: Box<Self>) -> Box<dyn std::any::Any> {
self
}

#[inline]
fn any_mut(&mut self) -> &mut dyn std::any::Any {
fn as_any(&self) -> &dyn std::any::Any {
self
}

#[inline]
fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
self
}

Expand Down Expand Up @@ -275,8 +280,7 @@ pub(crate) fn impl_tuple_struct(derive_data: &ReflectDeriveData) -> TokenStream
}
}

// SAFE: any and any_mut both return self
unsafe impl #impl_generics #bevy_reflect_path::Reflect for #struct_name #ty_generics #where_clause {
impl #impl_generics #bevy_reflect_path::Reflect for #struct_name #ty_generics #where_clause {
#[inline]
fn type_name(&self) -> &str {
std::any::type_name::<Self>()
Expand All @@ -288,11 +292,17 @@ pub(crate) fn impl_tuple_struct(derive_data: &ReflectDeriveData) -> TokenStream
}

#[inline]
fn any(&self) -> &dyn std::any::Any {
fn into_any(self: Box<Self>) -> Box<dyn std::any::Any> {
self
}

#[inline]
fn as_any(&self) -> &dyn std::any::Any {
self
}

#[inline]
fn any_mut(&mut self) -> &mut dyn std::any::Any {
fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
self
}

Expand Down Expand Up @@ -372,8 +382,7 @@ pub(crate) fn impl_value(

#typed_impl

// SAFE: any and any_mut both return self
unsafe impl #impl_generics #bevy_reflect_path::Reflect for #type_name #ty_generics #where_clause {
impl #impl_generics #bevy_reflect_path::Reflect for #type_name #ty_generics #where_clause {
#[inline]
fn type_name(&self) -> &str {
std::any::type_name::<Self>()
Expand All @@ -385,12 +394,17 @@ pub(crate) fn impl_value(
}

#[inline]
fn any(&self) -> &dyn std::any::Any {
fn into_any(self: Box<Self>) -> Box<dyn std::any::Any> {
self
}

#[inline]
fn as_any(&self) -> &dyn std::any::Any {
self
}

#[inline]
fn any_mut(&mut self) -> &mut dyn std::any::Any {
fn as_mut_any(&mut self) -> &mut dyn std::any::Any {
self
}

Expand All @@ -411,7 +425,7 @@ pub(crate) fn impl_value(

#[inline]
fn apply(&mut self, value: &dyn #bevy_reflect_path::Reflect) {
let value = value.any();
let value = value.as_any();
if let Some(value) = value.downcast_ref::<Self>() {
*self = value.clone();
} else {
Expand Down
12 changes: 8 additions & 4 deletions crates/bevy_reflect/src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,7 @@ impl DynamicArray {
}
}

// SAFE: any and any_mut both return self
unsafe impl Reflect for DynamicArray {
impl Reflect for DynamicArray {
#[inline]
fn type_name(&self) -> &str {
self.name.as_str()
Expand All @@ -164,12 +163,17 @@ unsafe impl Reflect for DynamicArray {
}

#[inline]
fn any(&self) -> &dyn Any {
fn into_any(self: Box<Self>) -> Box<dyn Any> {
self
}

#[inline]
fn any_mut(&mut self) -> &mut dyn Any {
fn as_any(&self) -> &dyn Any {
self
}

#[inline]
fn as_mut_any(&mut self) -> &mut dyn Any {
self
}

Expand Down
11 changes: 7 additions & 4 deletions crates/bevy_reflect/src/impls/smallvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ where
}
}

// SAFE: any and any_mut both return self
unsafe impl<T: smallvec::Array + Send + Sync + 'static> Reflect for SmallVec<T>
impl<T: smallvec::Array + Send + Sync + 'static> Reflect for SmallVec<T>
where
T::Item: FromReflect + Clone,
{
Expand All @@ -68,11 +67,15 @@ where
<Self as Typed>::type_info()
}

fn any(&self) -> &dyn Any {
fn into_any(self: Box<Self>) -> Box<dyn Any> {
self
}

fn any_mut(&mut self) -> &mut dyn Any {
fn as_any(&self) -> &dyn Any {
self
}

fn as_mut_any(&mut self) -> &mut dyn Any {
self
}

Expand Down
56 changes: 37 additions & 19 deletions crates/bevy_reflect/src/impls/std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,7 @@ impl<T: FromReflect> List for Vec<T> {
}
}

// SAFE: any and any_mut both return self
unsafe impl<T: FromReflect> Reflect for Vec<T> {
impl<T: FromReflect> Reflect for Vec<T> {
fn type_name(&self) -> &str {
std::any::type_name::<Self>()
}
Expand All @@ -115,11 +114,15 @@ unsafe impl<T: FromReflect> Reflect for Vec<T> {
<Self as Typed>::type_info()
}

fn any(&self) -> &dyn Any {
fn into_any(self: Box<Self>) -> Box<dyn Any> {
self
}

fn any_mut(&mut self) -> &mut dyn Any {
fn as_any(&self) -> &dyn Any {
self
}

fn as_mut_any(&mut self) -> &mut dyn Any {
self
}

Expand Down Expand Up @@ -230,8 +233,7 @@ impl<K: Reflect + Eq + Hash, V: Reflect> Map for HashMap<K, V> {
}
}

// SAFE: any and any_mut both return self
unsafe impl<K: Reflect + Eq + Hash, V: Reflect> Reflect for HashMap<K, V> {
impl<K: Reflect + Eq + Hash, V: Reflect> Reflect for HashMap<K, V> {
fn type_name(&self) -> &str {
std::any::type_name::<Self>()
}
Expand All @@ -240,11 +242,15 @@ unsafe impl<K: Reflect + Eq + Hash, V: Reflect> Reflect for HashMap<K, V> {
<Self as Typed>::type_info()
}

fn any(&self) -> &dyn Any {
fn into_any(self: Box<Self>) -> Box<dyn Any> {
self
}

fn any_mut(&mut self) -> &mut dyn Any {
fn as_any(&self) -> &dyn Any {
self
}

fn as_mut_any(&mut self) -> &mut dyn Any {
self
}

Expand Down Expand Up @@ -350,8 +356,7 @@ impl<T: Reflect, const N: usize> Array for [T; N] {
}
}

// SAFE: any and any_mut both return self
unsafe impl<T: Reflect, const N: usize> Reflect for [T; N] {
impl<T: Reflect, const N: usize> Reflect for [T; N] {
#[inline]
fn type_name(&self) -> &str {
std::any::type_name::<Self>()
Expand All @@ -362,12 +367,17 @@ unsafe impl<T: Reflect, const N: usize> Reflect for [T; N] {
}

#[inline]
fn any(&self) -> &dyn Any {
fn into_any(self: Box<Self>) -> Box<dyn Any> {
self
}

#[inline]
fn any_mut(&mut self) -> &mut dyn Any {
fn as_any(&self) -> &dyn Any {
self
}

#[inline]
fn as_mut_any(&mut self) -> &mut dyn Any {
self
}

Expand Down Expand Up @@ -465,8 +475,7 @@ impl_array_get_type_registration! {
30 31 32
}

// SAFE: any and any_mut both return self
unsafe impl Reflect for Cow<'static, str> {
impl Reflect for Cow<'static, str> {
fn type_name(&self) -> &str {
std::any::type_name::<Self>()
}
Expand All @@ -475,11 +484,15 @@ unsafe impl Reflect for Cow<'static, str> {
<Self as Typed>::type_info()
}

fn any(&self) -> &dyn Any {
fn into_any(self: Box<Self>) -> Box<dyn Any> {
self
}

fn as_any(&self) -> &dyn Any {
self
}

fn any_mut(&mut self) -> &mut dyn Any {
fn as_mut_any(&mut self) -> &mut dyn Any {
self
}

Expand All @@ -492,7 +505,7 @@ unsafe impl Reflect for Cow<'static, str> {
}

fn apply(&mut self, value: &dyn Reflect) {
let value = value.any();
let value = value.as_any();
if let Some(value) = value.downcast_ref::<Self>() {
*self = value.clone();
} else {
Expand Down Expand Up @@ -525,7 +538,7 @@ unsafe impl Reflect for Cow<'static, str> {
}

fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
let value = value.any();
let value = value.as_any();
if let Some(value) = value.downcast_ref::<Self>() {
Some(std::cmp::PartialEq::eq(self, value))
} else {
Expand All @@ -552,7 +565,12 @@ impl GetTypeRegistration for Cow<'static, str> {

impl FromReflect for Cow<'static, str> {
fn from_reflect(reflect: &dyn crate::Reflect) -> Option<Self> {
Some(reflect.any().downcast_ref::<Cow<'static, str>>()?.clone())
Some(
reflect
.as_any()
.downcast_ref::<Cow<'static, str>>()?
.clone(),
)
}
}

Expand Down
36 changes: 36 additions & 0 deletions crates/bevy_reflect/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,42 @@ mod tests {
assert!(foo.reflect_partial_eq(&dynamic_struct).unwrap());
}

#[test]
fn reflect_downcast() {
#[derive(Reflect, Clone, Debug, PartialEq)]
struct Bar {
y: u8,
z: ::glam::Mat4,
}

#[derive(Reflect, Clone, Debug, PartialEq)]
struct Foo {
x: i32,
s: String,
b: Bar,
u: usize,
t: (Vec3, String),
}

let foo = Foo {
x: 123,
s: "String".to_string(),
b: Bar {
y: 255,
z: ::glam::Mat4::from_cols_array(&[
0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0,
15.0,
]),
},
u: 1111111111111,
t: (Vec3::new(3.0, 2.0, 1.0), "Tuple String".to_string()),
PROMETHIA-27 marked this conversation as resolved.
Show resolved Hide resolved
};

let foo2: Box<dyn Reflect> = Box::new(foo.clone());

assert_eq!(foo, *foo2.downcast::<Foo>().unwrap());
}

#[test]
fn reflect_take() {
#[derive(Reflect, Debug, PartialEq)]
Expand Down
12 changes: 8 additions & 4 deletions crates/bevy_reflect/src/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,7 @@ impl List for DynamicList {
}
}

// SAFE: any and any_mut both return self
unsafe impl Reflect for DynamicList {
impl Reflect for DynamicList {
#[inline]
fn type_name(&self) -> &str {
self.name.as_str()
Expand All @@ -176,12 +175,17 @@ unsafe impl Reflect for DynamicList {
}

#[inline]
fn any(&self) -> &dyn Any {
fn into_any(self: Box<Self>) -> Box<dyn Any> {
self
}

#[inline]
fn any_mut(&mut self) -> &mut dyn Any {
fn as_any(&self) -> &dyn Any {
self
}

#[inline]
fn as_mut_any(&mut self) -> &mut dyn Any {
self
}

Expand Down
Loading