From 456c18f767104a6b69dbf41a1e3b6a3cc99800d7 Mon Sep 17 00:00:00 2001 From: Anthony Ramine Date: Mon, 5 Feb 2018 23:51:45 +0100 Subject: [PATCH] =?UTF-8?q?Implement=20PartialEq=20for=20PropertyDeclarati?= =?UTF-8?q?on=20by=20hand=20=F0=9F=90=89=F0=9F=90=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We first check that the discriminants are equal, then we pattern match only on `*self` and use `PropertyDeclarationVariantRepr` to look into `other` directly. --- .../style/properties/properties.mako.rs | 43 +++++++++++++++---- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index a71d6e7e95e..ef7f4f7926b 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -268,7 +268,6 @@ pub mod animated_properties { /// Servo's representation for a property declaration. #[cfg_attr(feature = "gecko", derive(MallocSizeOf))] -#[derive(PartialEq)] #[repr(u16)] pub enum PropertyDeclaration { % for variant in variants: @@ -277,17 +276,17 @@ pub enum PropertyDeclaration { % endfor } +#[repr(C)] +struct PropertyDeclarationVariantRepr { + tag: u16, + value: T +} + impl Clone for PropertyDeclaration { #[inline] fn clone(&self) -> Self { use self::PropertyDeclaration::*; - #[repr(C)] - struct VariantRepr { - tag: u16, - value: T - } - match *self { % for ty, variants in groups.iteritems(): % if len(variants) == 1: @@ -299,8 +298,8 @@ impl Clone for PropertyDeclaration { unsafe { let mut out = ManuallyDrop::new(mem::uninitialized()); ptr::write( - &mut out as *mut _ as *mut VariantRepr<${ty}>, - VariantRepr { + &mut out as *mut _ as *mut PropertyDeclarationVariantRepr<${ty}>, + PropertyDeclarationVariantRepr { tag: *(self as *const _ as *const u16), value: value.clone(), }, @@ -314,6 +313,32 @@ impl Clone for PropertyDeclaration { } } +impl PartialEq for PropertyDeclaration { + #[inline] + fn eq(&self, other: &Self) -> bool { + use self::PropertyDeclaration::*; + + unsafe { + let this_repr = + &*(self as *const _ as *const PropertyDeclarationVariantRepr<()>); + let other_repr = + &*(other as *const _ as *const PropertyDeclarationVariantRepr<()>); + if this_repr.tag != other_repr.tag { + return false; + } + match *self { + % for ty, variants in groups.iteritems(): + ${" | ".join("{}(ref this)".format(v) for v in variants)} => { + let other_repr = + &*(other as *const _ as *const PropertyDeclarationVariantRepr<${ty}>); + *this == other_repr.value + } + % endfor + } + } + } +} + impl PropertyDeclaration { /// Like the method on ToCss, but without the type parameter to avoid /// accidentally monomorphizing this large function multiple times for