Rename reflect 'hash' method to 'reflect_hash' and partial_eq to reflect_partial_eq (#954)

* Rename reflect 'hash' method to 'reflect_hash' to avoid colliding with std:#️⃣:Hash::hash to resolve #943.

* Rename partial_eq to reflect_partial_eq to avoid collisions with implementations of PartialEq on primitives.
This commit is contained in:
Nathan Stocks 2020-12-01 12:15:07 -07:00 committed by GitHub
parent 0b818d7b32
commit 3cee95e59a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 43 additions and 43 deletions

View File

@ -102,7 +102,7 @@ let reflect_deserializer = ReflectDeserializer::new(&registry);
let value = reflect_deserializer.deserialize(&mut deserializer).unwrap(); let value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
let dynamic_struct = value.take::<DynamicStruct>().unwrap(); let dynamic_struct = value.take::<DynamicStruct>().unwrap();
assert!(foo.partial_eq(&dynamic_struct).unwrap()); assert!(foo.reflect_partial_eq(&dynamic_struct).unwrap());
``` ```
### Trait "reflection" ### Trait "reflection"

View File

@ -196,7 +196,7 @@ fn impl_struct(
let hash_fn = reflect_attrs.get_hash_impl(&bevy_reflect_path); let hash_fn = reflect_attrs.get_hash_impl(&bevy_reflect_path);
let serialize_fn = reflect_attrs.get_serialize_impl(&bevy_reflect_path); let serialize_fn = reflect_attrs.get_serialize_impl(&bevy_reflect_path);
let partial_eq_fn = match reflect_attrs.partial_eq { let partial_eq_fn = match reflect_attrs.reflect_partial_eq {
TraitImpl::NotImplemented => quote! { TraitImpl::NotImplemented => quote! {
use #bevy_reflect_path::Struct; use #bevy_reflect_path::Struct;
#bevy_reflect_path::struct_partial_eq(self, value) #bevy_reflect_path::struct_partial_eq(self, value)
@ -311,11 +311,11 @@ fn impl_struct(
#serialize_fn #serialize_fn
} }
fn hash(&self) -> Option<u64> { fn reflect_hash(&self) -> Option<u64> {
#hash_fn #hash_fn
} }
fn partial_eq(&self, value: &dyn #bevy_reflect_path::Reflect) -> Option<bool> { fn reflect_partial_eq(&self, value: &dyn #bevy_reflect_path::Reflect) -> Option<bool> {
#partial_eq_fn #partial_eq_fn
} }
} }
@ -339,7 +339,7 @@ fn impl_tuple_struct(
let hash_fn = reflect_attrs.get_hash_impl(&bevy_reflect_path); let hash_fn = reflect_attrs.get_hash_impl(&bevy_reflect_path);
let serialize_fn = reflect_attrs.get_serialize_impl(&bevy_reflect_path); let serialize_fn = reflect_attrs.get_serialize_impl(&bevy_reflect_path);
let partial_eq_fn = match reflect_attrs.partial_eq { let partial_eq_fn = match reflect_attrs.reflect_partial_eq {
TraitImpl::NotImplemented => quote! { TraitImpl::NotImplemented => quote! {
use #bevy_reflect_path::TupleStruct; use #bevy_reflect_path::TupleStruct;
#bevy_reflect_path::tuple_struct_partial_eq(self, value) #bevy_reflect_path::tuple_struct_partial_eq(self, value)
@ -430,11 +430,11 @@ fn impl_tuple_struct(
#serialize_fn #serialize_fn
} }
fn hash(&self) -> Option<u64> { fn reflect_hash(&self) -> Option<u64> {
#hash_fn #hash_fn
} }
fn partial_eq(&self, value: &dyn #bevy_reflect_path::Reflect) -> Option<bool> { fn reflect_partial_eq(&self, value: &dyn #bevy_reflect_path::Reflect) -> Option<bool> {
#partial_eq_fn #partial_eq_fn
} }
} }
@ -501,11 +501,11 @@ fn impl_value(
#bevy_reflect_path::ReflectMut::Value(self) #bevy_reflect_path::ReflectMut::Value(self)
} }
fn hash(&self) -> Option<u64> { fn reflect_hash(&self) -> Option<u64> {
#hash_fn #hash_fn
} }
fn partial_eq(&self, value: &dyn #bevy_reflect_path::Reflect) -> Option<bool> { fn reflect_partial_eq(&self, value: &dyn #bevy_reflect_path::Reflect) -> Option<bool> {
#partial_eq_fn #partial_eq_fn
} }
@ -585,8 +585,8 @@ pub fn impl_reflect_value(input: TokenStream) -> TokenStream {
#[derive(Default)] #[derive(Default)]
struct ReflectAttrs { struct ReflectAttrs {
hash: TraitImpl, reflect_hash: TraitImpl,
partial_eq: TraitImpl, reflect_partial_eq: TraitImpl,
serialize: TraitImpl, serialize: TraitImpl,
data: Vec<Ident>, data: Vec<Ident>,
} }
@ -602,8 +602,8 @@ impl ReflectAttrs {
if let Some(segment) = path.segments.iter().next() { if let Some(segment) = path.segments.iter().next() {
let ident = segment.ident.to_string(); let ident = segment.ident.to_string();
match ident.as_str() { match ident.as_str() {
"PartialEq" => attrs.partial_eq = TraitImpl::Implemented, "PartialEq" => attrs.reflect_partial_eq = TraitImpl::Implemented,
"Hash" => attrs.hash = TraitImpl::Implemented, "Hash" => attrs.reflect_hash = TraitImpl::Implemented,
"Serialize" => attrs.serialize = TraitImpl::Implemented, "Serialize" => attrs.serialize = TraitImpl::Implemented,
_ => attrs.data.push(Ident::new( _ => attrs.data.push(Ident::new(
&format!("Reflect{}", segment.ident), &format!("Reflect{}", segment.ident),
@ -626,11 +626,11 @@ impl ReflectAttrs {
if let Some(segment) = path.segments.iter().next() { if let Some(segment) = path.segments.iter().next() {
match ident.as_str() { match ident.as_str() {
"PartialEq" => { "PartialEq" => {
attrs.partial_eq = attrs.reflect_partial_eq =
TraitImpl::Custom(segment.ident.clone()) TraitImpl::Custom(segment.ident.clone())
} }
"Hash" => { "Hash" => {
attrs.hash = attrs.reflect_hash =
TraitImpl::Custom(segment.ident.clone()) TraitImpl::Custom(segment.ident.clone())
} }
"Serialize" => { "Serialize" => {
@ -657,7 +657,7 @@ impl ReflectAttrs {
} }
fn get_hash_impl(&self, path: &Path) -> proc_macro2::TokenStream { fn get_hash_impl(&self, path: &Path) -> proc_macro2::TokenStream {
match &self.hash { match &self.reflect_hash {
TraitImpl::Implemented => quote! { TraitImpl::Implemented => quote! {
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
let mut hasher = #path::ReflectHasher::default(); let mut hasher = #path::ReflectHasher::default();
@ -675,7 +675,7 @@ impl ReflectAttrs {
} }
fn get_partial_eq_impl(&self) -> proc_macro2::TokenStream { fn get_partial_eq_impl(&self) -> proc_macro2::TokenStream {
match &self.partial_eq { match &self.reflect_partial_eq {
TraitImpl::Implemented => quote! { TraitImpl::Implemented => quote! {
let value = value.any(); let value = value.any();
if let Some(value) = value.downcast_ref::<Self>() { if let Some(value) = value.downcast_ref::<Self>() {

View File

@ -82,11 +82,11 @@ where
Box::new(self.clone_dynamic()) Box::new(self.clone_dynamic())
} }
fn hash(&self) -> Option<u64> { fn reflect_hash(&self) -> Option<u64> {
None None
} }
fn partial_eq(&self, value: &dyn Reflect) -> Option<bool> { fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
crate::list_partial_eq(self, value) crate::list_partial_eq(self, value)
} }

View File

@ -93,11 +93,11 @@ impl<T: Reflect> Reflect for Vec<T> {
Box::new(self.clone_dynamic()) Box::new(self.clone_dynamic())
} }
fn hash(&self) -> Option<u64> { fn reflect_hash(&self) -> Option<u64> {
None None
} }
fn partial_eq(&self, value: &dyn Reflect) -> Option<bool> { fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
crate::list_partial_eq(self, value) crate::list_partial_eq(self, value)
} }
@ -187,11 +187,11 @@ impl<K: Reflect + Clone + Eq + Hash, V: Reflect + Clone> Reflect for HashMap<K,
Box::new(self.clone_dynamic()) Box::new(self.clone_dynamic())
} }
fn hash(&self) -> Option<u64> { fn reflect_hash(&self) -> Option<u64> {
None None
} }
fn partial_eq(&self, value: &dyn Reflect) -> Option<bool> { fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
map_partial_eq(self, value) map_partial_eq(self, value)
} }

View File

@ -306,7 +306,7 @@ mod tests {
let value = reflect_deserializer.deserialize(&mut deserializer).unwrap(); let value = reflect_deserializer.deserialize(&mut deserializer).unwrap();
let dynamic_struct = value.take::<DynamicStruct>().unwrap(); let dynamic_struct = value.take::<DynamicStruct>().unwrap();
assert!(foo.partial_eq(&dynamic_struct).unwrap()); assert!(foo.reflect_partial_eq(&dynamic_struct).unwrap());
} }
#[test] #[test]

View File

@ -111,11 +111,11 @@ impl Reflect for DynamicList {
} }
#[inline] #[inline]
fn hash(&self) -> Option<u64> { fn reflect_hash(&self) -> Option<u64> {
None None
} }
fn partial_eq(&self, value: &dyn Reflect) -> Option<bool> { fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
list_partial_eq(self, value) list_partial_eq(self, value)
} }
@ -169,7 +169,7 @@ pub fn list_partial_eq<L: List>(a: &L, b: &dyn Reflect) -> Option<bool> {
} }
for (a_value, b_value) in a.iter().zip(list.iter()) { for (a_value, b_value) in a.iter().zip(list.iter()) {
if let Some(false) | None = a_value.partial_eq(b_value) { if let Some(false) | None = a_value.reflect_partial_eq(b_value) {
return Some(false); return Some(false);
} }
} }

View File

@ -33,7 +33,7 @@ impl DynamicMap {
} }
pub fn insert_boxed(&mut self, key: Box<dyn Reflect>, value: Box<dyn Reflect>) { pub fn insert_boxed(&mut self, key: Box<dyn Reflect>, value: Box<dyn Reflect>) {
match self.indices.entry(key.hash().expect(HASH_ERROR)) { match self.indices.entry(key.reflect_hash().expect(HASH_ERROR)) {
Entry::Occupied(entry) => { Entry::Occupied(entry) => {
self.values[*entry.get()] = (key, value); self.values[*entry.get()] = (key, value);
} }
@ -48,13 +48,13 @@ impl DynamicMap {
impl Map for DynamicMap { impl Map for DynamicMap {
fn get(&self, key: &dyn Reflect) -> Option<&dyn Reflect> { fn get(&self, key: &dyn Reflect) -> Option<&dyn Reflect> {
self.indices self.indices
.get(&key.hash().expect(HASH_ERROR)) .get(&key.reflect_hash().expect(HASH_ERROR))
.map(|index| &*self.values.get(*index).unwrap().1) .map(|index| &*self.values.get(*index).unwrap().1)
} }
fn get_mut(&mut self, key: &dyn Reflect) -> Option<&mut dyn Reflect> { fn get_mut(&mut self, key: &dyn Reflect) -> Option<&mut dyn Reflect> {
self.indices self.indices
.get(&key.hash().expect(HASH_ERROR)) .get(&key.reflect_hash().expect(HASH_ERROR))
.cloned() .cloned()
.map(move |index| &mut *self.values.get_mut(index).unwrap().1) .map(move |index| &mut *self.values.get_mut(index).unwrap().1)
} }
@ -130,11 +130,11 @@ impl Reflect for DynamicMap {
Box::new(self.clone_dynamic()) Box::new(self.clone_dynamic())
} }
fn hash(&self) -> Option<u64> { fn reflect_hash(&self) -> Option<u64> {
None None
} }
fn partial_eq(&self, value: &dyn Reflect) -> Option<bool> { fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
map_partial_eq(self, value) map_partial_eq(self, value)
} }
@ -172,7 +172,7 @@ pub fn map_partial_eq<M: Map>(a: &M, b: &dyn Reflect) -> Option<bool> {
for (key, value) in a.iter() { for (key, value) in a.iter() {
if let Some(map_value) = map.get(key) { if let Some(map_value) = map.get(key) {
if let Some(false) | None = value.partial_eq(map_value) { if let Some(false) | None = value.reflect_partial_eq(map_value) {
return Some(false); return Some(false);
} }
} else { } else {

View File

@ -30,9 +30,9 @@ pub trait Reflect: Any + Send + Sync {
fn reflect_mut(&mut self) -> ReflectMut; fn reflect_mut(&mut self) -> ReflectMut;
fn clone_value(&self) -> Box<dyn Reflect>; fn clone_value(&self) -> Box<dyn Reflect>;
/// Returns a hash of the value (which includes the type) if hashing is supported. Otherwise `None` will be returned. /// Returns a hash of the value (which includes the type) if hashing is supported. Otherwise `None` will be returned.
fn hash(&self) -> Option<u64>; fn reflect_hash(&self) -> Option<u64>;
/// Returns a "partial equal" comparison result if comparison is supported. Otherwise `None` will be returned. /// Returns a "partial equal" comparison result if comparison is supported. Otherwise `None` will be returned.
fn partial_eq(&self, _value: &dyn Reflect) -> Option<bool>; fn reflect_partial_eq(&self, _value: &dyn Reflect) -> Option<bool>;
/// Returns a serializable value, if serialization is supported. Otherwise `None` will be returned. /// Returns a serializable value, if serialization is supported. Otherwise `None` will be returned.
fn serializable(&self) -> Option<Serializable>; fn serializable(&self) -> Option<Serializable>;
} }

View File

@ -216,11 +216,11 @@ impl Reflect for DynamicStruct {
Ok(()) Ok(())
} }
fn hash(&self) -> Option<u64> { fn reflect_hash(&self) -> Option<u64> {
None None
} }
fn partial_eq(&self, value: &dyn Reflect) -> Option<bool> { fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
struct_partial_eq(self, value) struct_partial_eq(self, value)
} }
@ -244,7 +244,7 @@ pub fn struct_partial_eq<S: Struct>(a: &S, b: &dyn Reflect) -> Option<bool> {
for (i, value) in struct_value.iter_fields().enumerate() { for (i, value) in struct_value.iter_fields().enumerate() {
let name = struct_value.name_at(i).unwrap(); let name = struct_value.name_at(i).unwrap();
if let Some(field_value) = a.field(name) { if let Some(field_value) = a.field(name) {
if let Some(false) | None = field_value.partial_eq(value) { if let Some(false) | None = field_value.reflect_partial_eq(value) {
return Some(false); return Some(false);
} }
} else { } else {

View File

@ -171,11 +171,11 @@ impl Reflect for DynamicTupleStruct {
Ok(()) Ok(())
} }
fn hash(&self) -> Option<u64> { fn reflect_hash(&self) -> Option<u64> {
None None
} }
fn partial_eq(&self, value: &dyn Reflect) -> Option<bool> { fn reflect_partial_eq(&self, value: &dyn Reflect) -> Option<bool> {
tuple_struct_partial_eq(self, value) tuple_struct_partial_eq(self, value)
} }
@ -198,7 +198,7 @@ pub fn tuple_struct_partial_eq<S: TupleStruct>(a: &S, b: &dyn Reflect) -> Option
for (i, value) in tuple_struct.iter_fields().enumerate() { for (i, value) in tuple_struct.iter_fields().enumerate() {
if let Some(field_value) = a.field(i) { if let Some(field_value) = a.field(i) {
if let Some(false) | None = field_value.partial_eq(value) { if let Some(false) | None = field_value.reflect_partial_eq(value) {
return Some(false); return Some(false);
} }
} else { } else {

View File

@ -84,9 +84,9 @@ fn setup(type_registry: Res<TypeRegistry>) {
// as themselves. // as themselves.
let _deserialized_struct = reflect_value.downcast_ref::<DynamicStruct>(); let _deserialized_struct = reflect_value.downcast_ref::<DynamicStruct>();
// Reflect has its own `partial_eq` implementation. This behaves like normal `partial_eq`, but it treats "dynamic" and // Reflect has its own `partial_eq` implementation, named `reflect_partial_eq`. This behaves like normal `partial_eq`, but it treats "dynamic" and
// "non-dynamic" types the same. The `Foo` struct and deserialized `DynamicStruct` are considered equal for this reason: // "non-dynamic" types the same. The `Foo` struct and deserialized `DynamicStruct` are considered equal for this reason:
assert!(reflect_value.partial_eq(&value).unwrap()); assert!(reflect_value.reflect_partial_eq(&value).unwrap());
// By "patching" `Foo` with the deserialized DynamicStruct, we can "Deserialize" Foo. // By "patching" `Foo` with the deserialized DynamicStruct, we can "Deserialize" Foo.
// This means we can serialize and deserialize with a single `Reflect` derive! // This means we can serialize and deserialize with a single `Reflect` derive!