diff options
| author | Ulrik Sverdrup <bluss@users.noreply.github.com> | 2016-03-01 02:27:27 +0100 |
|---|---|---|
| committer | Ulrik Sverdrup <bluss@users.noreply.github.com> | 2016-03-01 02:27:27 +0100 |
| commit | edcc02bfee262ce8bc3f087d9793ce68d73b1a40 (patch) | |
| tree | 209c1bbe422feed715024758bcbb7176227c549b /src/libsyntax_ext | |
| parent | 57e0a7e5d8872c8fcea47fc20239b8921bda2576 (diff) | |
| download | rust-edcc02bfee262ce8bc3f087d9793ce68d73b1a40.tar.gz rust-edcc02bfee262ce8bc3f087d9793ce68d73b1a40.zip | |
derive: Emit only PartialOrd::partial_cmp for simple enums
Using the same logic as for `PartialEq`, when possible define only `partial_cmp` and leave `lt, le, gt, ge` to their default implementations. This works well for c-like enums.
Diffstat (limited to 'src/libsyntax_ext')
| -rw-r--r-- | src/libsyntax_ext/deriving/cmp/partial_eq.rs | 18 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/cmp/partial_ord.rs | 23 | ||||
| -rw-r--r-- | src/libsyntax_ext/deriving/generic/mod.rs | 18 |
3 files changed, 35 insertions, 24 deletions
diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs index 24444c3c39b..6406ee59a5e 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs @@ -11,29 +11,13 @@ use deriving::generic::*; use deriving::generic::ty::*; -use syntax::ast::{MetaItem, Expr, BinOpKind, ItemKind}; +use syntax::ast::{MetaItem, Expr, BinOpKind}; 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_type_without_fields(item: &Annotatable) -> bool { - if let Annotatable::Item(ref item) = *item { - match item.node { - ItemKind::Enum(ref enum_def, _) => { - enum_def.variants.iter().all(|v| v.node.data.fields().is_empty()) - } - ItemKind::Struct(ref variant_data, _) => { - variant_data.fields().is_empty() - } - _ => false - } - } else { - false - } -} - pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs index e857f7d52f9..fafcf0ea960 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs @@ -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) diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index c0237a5d29a..e8954b1a2fc 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -1638,3 +1638,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 + } +} |
