about summary refs log tree commit diff
path: root/src/libsyntax_ext
diff options
context:
space:
mode:
authorUlrik Sverdrup <bluss@users.noreply.github.com>2016-02-29 21:27:20 +0100
committerUlrik Sverdrup <bluss@users.noreply.github.com>2016-02-29 21:27:20 +0100
commit190af51f303e21e22ea0a4d7dffeb09805d19010 (patch)
tree8b67a748b9c4b880533a465a0b1927a2ea2f1ff0 /src/libsyntax_ext
parent09130044ce7429beb95742afa7fd371960dbe607 (diff)
downloadrust-190af51f303e21e22ea0a4d7dffeb09805d19010.tar.gz
rust-190af51f303e21e22ea0a4d7dffeb09805d19010.zip
derive: Avoid emitting PartialEq::ne for c-like enums
`ne` is completely symmetrical with the method `eq`, and we can save
rust code size and compilation time here if we only emit one of them
when possible.

One case where it's easy to recognize is when it's a C-like enum. Most
other cases can not omit ne, because any value field may have a custom
PartialEq implementation.
Diffstat (limited to 'src/libsyntax_ext')
-rw-r--r--src/libsyntax_ext/deriving/cmp/partial_eq.rs33
1 files changed, 28 insertions, 5 deletions
diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs
index 0150a073b07..dac25112112 100644
--- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs
+++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs
@@ -11,13 +11,33 @@
 use deriving::generic::*;
 use deriving::generic::ty::*;
 
-use syntax::ast::{MetaItem, Expr, BinOpKind};
+use syntax::ast::{MetaItem, Expr, BinOpKind, ItemKind, VariantData};
 use syntax::codemap::Span;
 use syntax::ext::base::{ExtCtxt, Annotatable};
 use syntax::ext::build::AstBuilder;
 use syntax::parse::token::InternedString;
 use syntax::ptr::P;
 
+fn is_clike_enum(item: &Annotatable) -> bool {
+    match *item {
+        Annotatable::Item(ref item) => {
+            match item.node {
+                ItemKind::Enum(ref enum_def, _) => {
+                    enum_def.variants.iter().all(|v|
+                        if let VariantData::Unit(..) = v.node.data {
+                            true
+                        } else {
+                            false
+                        }
+                    )
+                }
+                _ => false,
+            }
+        }
+        _ => false,
+    }
+}
+
 pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt,
                                   span: Span,
                                   mitem: &MetaItem,
@@ -80,6 +100,12 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt,
         } }
     }
 
+    // avoid defining `ne` if we can
+    let mut methods = vec![md!("eq", cs_eq)];
+    if !is_clike_enum(item) {
+        methods.push(md!("ne", cs_ne));
+    }
+
     let trait_def = TraitDef {
         span: span,
         attributes: Vec::new(),
@@ -87,10 +113,7 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt,
         additional_bounds: Vec::new(),
         generics: LifetimeBounds::empty(),
         is_unsafe: false,
-        methods: vec!(
-            md!("eq", cs_eq),
-            md!("ne", cs_ne)
-        ),
+        methods: methods,
         associated_types: Vec::new(),
     };
     trait_def.expand(cx, mitem, item, push)