Skip to content

Commit 190af51

Browse files
committed
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.
1 parent 0913004 commit 190af51

File tree

1 file changed

+28
-5
lines changed

1 file changed

+28
-5
lines changed

src/libsyntax_ext/deriving/cmp/partial_eq.rs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,33 @@
1111
use deriving::generic::*;
1212
use deriving::generic::ty::*;
1313

14-
use syntax::ast::{MetaItem, Expr, BinOpKind};
14+
use syntax::ast::{MetaItem, Expr, BinOpKind, ItemKind, VariantData};
1515
use syntax::codemap::Span;
1616
use syntax::ext::base::{ExtCtxt, Annotatable};
1717
use syntax::ext::build::AstBuilder;
1818
use syntax::parse::token::InternedString;
1919
use syntax::ptr::P;
2020

21+
fn is_clike_enum(item: &Annotatable) -> bool {
22+
match *item {
23+
Annotatable::Item(ref item) => {
24+
match item.node {
25+
ItemKind::Enum(ref enum_def, _) => {
26+
enum_def.variants.iter().all(|v|
27+
if let VariantData::Unit(..) = v.node.data {
28+
true
29+
} else {
30+
false
31+
}
32+
)
33+
}
34+
_ => false,
35+
}
36+
}
37+
_ => false,
38+
}
39+
}
40+
2141
pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt,
2242
span: Span,
2343
mitem: &MetaItem,
@@ -80,17 +100,20 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt,
80100
} }
81101
}
82102

103+
// avoid defining `ne` if we can
104+
let mut methods = vec![md!("eq", cs_eq)];
105+
if !is_clike_enum(item) {
106+
methods.push(md!("ne", cs_ne));
107+
}
108+
83109
let trait_def = TraitDef {
84110
span: span,
85111
attributes: Vec::new(),
86112
path: path_std!(cx, core::cmp::PartialEq),
87113
additional_bounds: Vec::new(),
88114
generics: LifetimeBounds::empty(),
89115
is_unsafe: false,
90-
methods: vec!(
91-
md!("eq", cs_eq),
92-
md!("ne", cs_ne)
93-
),
116+
methods: methods,
94117
associated_types: Vec::new(),
95118
};
96119
trait_def.expand(cx, mitem, item, push)

0 commit comments

Comments
 (0)