This could probably be achieved by using mem::discriminant
for simplicity + efficiency. Of course, it could also be done by match
statements, similar to the previous answer.
Regarding the code in my previous response, the structure is somewhat different from what derive(PartialEq)
gives you, e.g. expanding macros on
#[derive(PartialEq, Eq, Hash)]
struct Foo;
#[derive(PartialEq, Eq, Hash)]
struct Bar;
#[derive(PartialEq, Eq, Hash)]
enum Properties {
PropertiesFoo(Foo),
PropertiesBar(Bar),
}
produces
struct Foo;
impl ::core::marker::StructuralPartialEq for Foo {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for Foo {
#[inline]
fn eq(&self, other: &Foo) -> bool {
match *other { Self => match *self { Self => true, }, }
}
}
impl ::core::marker::StructuralEq for Foo {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Eq for Foo {
#[inline]
#[doc(hidden)]
#[no_coverage]
fn assert_receiver_is_total_eq(&self) -> () { {} }
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::hash::Hash for Foo {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
match *self { Self => {} }
}
}
struct Bar;
impl ::core::marker::StructuralPartialEq for Bar {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for Bar {
#[inline]
fn eq(&self, other: &Bar) -> bool {
match *other { Self => match *self { Self => true, }, }
}
}
impl ::core::marker::StructuralEq for Bar {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Eq for Bar {
#[inline]
#[doc(hidden)]
#[no_coverage]
fn assert_receiver_is_total_eq(&self) -> () { {} }
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::hash::Hash for Bar {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
match *self { Self => {} }
}
}
enum Properties { PropertiesFoo(Foo), PropertiesBar(Bar), }
impl ::core::marker::StructuralPartialEq for Properties {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::PartialEq for Properties {
#[inline]
fn eq(&self, other: &Properties) -> bool {
{
let __self_vi = ::core::intrinsics::discriminant_value(&*self);
let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other);
if true && __self_vi == __arg_1_vi {
match (&*self, &*other) {
(&Properties::PropertiesFoo(ref __self_0),
&Properties::PropertiesFoo(ref __arg_1_0)) =>
(*__self_0) == (*__arg_1_0),
(&Properties::PropertiesBar(ref __self_0),
&Properties::PropertiesBar(ref __arg_1_0)) =>
(*__self_0) == (*__arg_1_0),
_ => unsafe { ::core::intrinsics::unreachable() }
}
} else { false }
}
}
#[inline]
fn ne(&self, other: &Properties) -> bool {
{
let __self_vi = ::core::intrinsics::discriminant_value(&*self);
let __arg_1_vi = ::core::intrinsics::discriminant_value(&*other);
if true && __self_vi == __arg_1_vi {
match (&*self, &*other) {
(&Properties::PropertiesFoo(ref __self_0),
&Properties::PropertiesFoo(ref __arg_1_0)) =>
(*__self_0) != (*__arg_1_0),
(&Properties::PropertiesBar(ref __self_0),
&Properties::PropertiesBar(ref __arg_1_0)) =>
(*__self_0) != (*__arg_1_0),
_ => unsafe { ::core::intrinsics::unreachable() }
}
} else { true }
}
}
}
impl ::core::marker::StructuralEq for Properties {}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::cmp::Eq for Properties {
#[inline]
#[doc(hidden)]
#[no_coverage]
fn assert_receiver_is_total_eq(&self) -> () {
{
let _: ::core::cmp::AssertParamIsEq<Foo>;
let _: ::core::cmp::AssertParamIsEq<Bar>;
}
}
}
#[automatically_derived]
#[allow(unused_qualifications)]
impl ::core::hash::Hash for Properties {
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) -> () {
match (&*self,) {
(&Properties::PropertiesFoo(ref __self_0),) => {
::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
state);
::core::hash::Hash::hash(&(*__self_0), state)
}
(&Properties::PropertiesBar(ref __self_0),) => {
::core::hash::Hash::hash(&::core::intrinsics::discriminant_value(self),
state);
::core::hash::Hash::hash(&(*__self_0), state)
}
}
}
}
which notably involves unsafe unreachable
, as well as using the discriminant
for the PartialEq
, too. I don't know how much (if any) performance benefits this has.