File tree 3 files changed +35
-24
lines changed
src/libsyntax_ext/deriving
3 files changed +35
-24
lines changed Original file line number Diff line number Diff line change 11
11
use deriving:: generic:: * ;
12
12
use deriving:: generic:: ty:: * ;
13
13
14
- use syntax:: ast:: { MetaItem , Expr , BinOpKind , ItemKind } ;
14
+ use syntax:: ast:: { MetaItem , Expr , BinOpKind } ;
15
15
use syntax:: codemap:: Span ;
16
16
use syntax:: ext:: base:: { ExtCtxt , Annotatable } ;
17
17
use syntax:: ext:: build:: AstBuilder ;
18
18
use syntax:: parse:: token:: InternedString ;
19
19
use syntax:: ptr:: P ;
20
20
21
- fn is_type_without_fields ( item : & Annotatable ) -> bool {
22
- if let Annotatable :: Item ( ref item) = * item {
23
- match item. node {
24
- ItemKind :: Enum ( ref enum_def, _) => {
25
- enum_def. variants . iter ( ) . all ( |v| v. node . data . fields ( ) . is_empty ( ) )
26
- }
27
- ItemKind :: Struct ( ref variant_data, _) => {
28
- variant_data. fields ( ) . is_empty ( )
29
- }
30
- _ => false
31
- }
32
- } else {
33
- false
34
- }
35
- }
36
-
37
21
pub fn expand_deriving_partial_eq ( cx : & mut ExtCtxt ,
38
22
span : Span ,
39
23
mitem : & MetaItem ,
Original file line number Diff line number Diff line change @@ -67,20 +67,29 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt,
67
67
} ) )
68
68
} ;
69
69
70
+ // avoid defining extra methods if we can
71
+ // c-like enums, enums without any fields and structs without fields
72
+ // can safely define only `partial_cmp`.
73
+ let methods = if is_type_without_fields ( item) {
74
+ vec ! [ partial_cmp_def]
75
+ } else {
76
+ vec ! [
77
+ partial_cmp_def,
78
+ md!( "lt" , true , false ) ,
79
+ md!( "le" , true , true ) ,
80
+ md!( "gt" , false , false ) ,
81
+ md!( "ge" , false , true )
82
+ ]
83
+ } ;
84
+
70
85
let trait_def = TraitDef {
71
86
span : span,
72
87
attributes : vec ! [ ] ,
73
88
path : path_std ! ( cx, core:: cmp:: PartialOrd ) ,
74
89
additional_bounds : vec ! [ ] ,
75
90
generics : LifetimeBounds :: empty ( ) ,
76
91
is_unsafe : false ,
77
- methods : vec ! [
78
- partial_cmp_def,
79
- md!( "lt" , true , false ) ,
80
- md!( "le" , true , true ) ,
81
- md!( "gt" , false , false ) ,
82
- md!( "ge" , false , true )
83
- ] ,
92
+ methods : methods,
84
93
associated_types : Vec :: new ( ) ,
85
94
} ;
86
95
trait_def. expand ( cx, mitem, item, push)
Original file line number Diff line number Diff line change @@ -1638,3 +1638,21 @@ pub fn cs_same_method<F>(f: F,
1638
1638
}
1639
1639
}
1640
1640
}
1641
+
1642
+ /// Return true if the type has no value fields
1643
+ /// (for an enum, no variant has any fields)
1644
+ pub fn is_type_without_fields ( item : & Annotatable ) -> bool {
1645
+ if let Annotatable :: Item ( ref item) = * item {
1646
+ match item. node {
1647
+ ast:: ItemKind :: Enum ( ref enum_def, _) => {
1648
+ enum_def. variants . iter ( ) . all ( |v| v. node . data . fields ( ) . is_empty ( ) )
1649
+ }
1650
+ ast:: ItemKind :: Struct ( ref variant_data, _) => {
1651
+ variant_data. fields ( ) . is_empty ( )
1652
+ }
1653
+ _ => false
1654
+ }
1655
+ } else {
1656
+ false
1657
+ }
1658
+ }
You can’t perform that action at this time.
0 commit comments