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.
This commit is contained in:
Ulrik Sverdrup 2016-02-29 21:27:20 +01:00
parent 09130044ce
commit 190af51f30

View file

@ -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)