Auto merge of #31977 - bluss:partial-eq-save, r=brson
derive: Avoid emitting provided PartialEq, PartialOrd methods for c-like enums derive: Avoid emitting provided PartialEq, PartialOrd method 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:
commit
02954ae0a8
@ -80,6 +80,14 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt,
|
||||
} }
|
||||
}
|
||||
|
||||
// avoid defining `ne` if we can
|
||||
// c-like enums, enums without any fields and structs without fields
|
||||
// can safely define only `eq`.
|
||||
let mut methods = vec![md!("eq", cs_eq)];
|
||||
if !is_type_without_fields(item) {
|
||||
methods.push(md!("ne", cs_ne));
|
||||
}
|
||||
|
||||
let trait_def = TraitDef {
|
||||
span: span,
|
||||
attributes: Vec::new(),
|
||||
@ -87,10 +95,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)
|
||||
|
@ -67,6 +67,21 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt,
|
||||
}))
|
||||
};
|
||||
|
||||
// avoid defining extra methods if we can
|
||||
// c-like enums, enums without any fields and structs without fields
|
||||
// can safely define only `partial_cmp`.
|
||||
let methods = if is_type_without_fields(item) {
|
||||
vec![partial_cmp_def]
|
||||
} else {
|
||||
vec![
|
||||
partial_cmp_def,
|
||||
md!("lt", true, false),
|
||||
md!("le", true, true),
|
||||
md!("gt", false, false),
|
||||
md!("ge", false, true)
|
||||
]
|
||||
};
|
||||
|
||||
let trait_def = TraitDef {
|
||||
span: span,
|
||||
attributes: vec![],
|
||||
@ -74,13 +89,7 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt,
|
||||
additional_bounds: vec![],
|
||||
generics: LifetimeBounds::empty(),
|
||||
is_unsafe: false,
|
||||
methods: vec![
|
||||
partial_cmp_def,
|
||||
md!("lt", true, false),
|
||||
md!("le", true, true),
|
||||
md!("gt", false, false),
|
||||
md!("ge", false, true)
|
||||
],
|
||||
methods: methods,
|
||||
associated_types: Vec::new(),
|
||||
};
|
||||
trait_def.expand(cx, mitem, item, push)
|
||||
|
@ -1647,3 +1647,21 @@ pub fn cs_same_method<F>(f: F,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return true if the type has no value fields
|
||||
/// (for an enum, no variant has any fields)
|
||||
pub fn is_type_without_fields(item: &Annotatable) -> bool {
|
||||
if let Annotatable::Item(ref item) = *item {
|
||||
match item.node {
|
||||
ast::ItemKind::Enum(ref enum_def, _) => {
|
||||
enum_def.variants.iter().all(|v| v.node.data.fields().is_empty())
|
||||
}
|
||||
ast::ItemKind::Struct(ref variant_data, _) => {
|
||||
variant_data.fields().is_empty()
|
||||
}
|
||||
_ => false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user