8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- pub use self :: OrderingOp :: * ;
12
-
13
11
use ast;
14
12
use ast:: { MetaItem , Item , Expr } ;
15
13
use codemap:: Span ;
@@ -20,114 +18,72 @@ use ext::deriving::generic::ty::*;
20
18
use parse:: token:: InternedString ;
21
19
use ptr:: P ;
22
20
23
- pub fn expand_deriving_ord < F > ( cx : & mut ExtCtxt ,
24
- span : Span ,
25
- mitem : & MetaItem ,
26
- item : & Item ,
27
- push : F ) where
21
+ pub fn expand_deriving_totalord < F > ( cx : & mut ExtCtxt ,
22
+ span : Span ,
23
+ mitem : & MetaItem ,
24
+ item : & Item ,
25
+ push : F ) where
28
26
F : FnOnce ( P < Item > ) ,
29
27
{
30
- macro_rules! md {
31
- ( $name: expr, $op: expr, $equal: expr) => { {
32
- let inline = cx. meta_word( span, InternedString :: new( "inline" ) ) ;
33
- let attrs = vec!( cx. attribute( span, inline) ) ;
28
+ let inline = cx. meta_word ( span, InternedString :: new ( "inline" ) ) ;
29
+ let attrs = vec ! ( cx. attribute( span, inline) ) ;
30
+ let trait_def = TraitDef {
31
+ span : span,
32
+ attributes : Vec :: new ( ) ,
33
+ path : path_std ! ( cx, core:: cmp:: Ord ) ,
34
+ additional_bounds : Vec :: new ( ) ,
35
+ generics : LifetimeBounds :: empty ( ) ,
36
+ methods : vec ! (
34
37
MethodDef {
35
- name: $name ,
38
+ name: "cmp" ,
36
39
generics: LifetimeBounds :: empty( ) ,
37
40
explicit_self: borrowed_explicit_self( ) ,
38
41
args: vec!( borrowed_self( ) ) ,
39
- ret_ty: Literal ( path_local! ( bool ) ) ,
42
+ ret_ty: Literal ( path_std! ( cx , core :: cmp :: Ordering ) ) ,
40
43
attributes: attrs,
41
- combine_substructure: combine_substructure( Box :: new( |cx , span , substr | {
42
- cs_op ( $op , $equal , cx , span , substr )
43
- } ) )
44
+ combine_substructure: combine_substructure( Box :: new( |a , b , c | {
45
+ cs_cmp ( a , b , c )
46
+ } ) ) ,
44
47
}
45
- } }
46
- }
47
-
48
- let ordering_ty = Literal ( path_std ! ( cx, core:: cmp:: Ordering ) ) ;
49
- let ret_ty = Literal ( Path :: new_ ( pathvec_std ! ( cx, core:: option:: Option ) ,
50
- None ,
51
- vec ! [ box ordering_ty] ,
52
- true ) ) ;
53
-
54
- let inline = cx. meta_word ( span, InternedString :: new ( "inline" ) ) ;
55
- let attrs = vec ! ( cx. attribute( span, inline) ) ;
56
-
57
- let partial_cmp_def = MethodDef {
58
- name : "partial_cmp" ,
59
- generics : LifetimeBounds :: empty ( ) ,
60
- explicit_self : borrowed_explicit_self ( ) ,
61
- args : vec ! [ borrowed_self( ) ] ,
62
- ret_ty : ret_ty,
63
- attributes : attrs,
64
- combine_substructure : combine_substructure ( Box :: new ( |cx, span, substr| {
65
- cs_partial_cmp ( cx, span, substr)
66
- } ) )
67
- } ;
68
-
69
- let trait_def = TraitDef {
70
- span : span,
71
- attributes : vec ! [ ] ,
72
- path : path_std ! ( cx, core:: cmp:: PartialOrd ) ,
73
- additional_bounds : vec ! [ ] ,
74
- generics : LifetimeBounds :: empty ( ) ,
75
- methods : vec ! [
76
- partial_cmp_def,
77
- md!( "lt" , true , false ) ,
78
- md!( "le" , true , true ) ,
79
- md!( "gt" , false , false ) ,
80
- md!( "ge" , false , true )
81
- ] ,
48
+ ) ,
82
49
associated_types : Vec :: new ( ) ,
83
50
} ;
51
+
84
52
trait_def. expand ( cx, mitem, item, push)
85
53
}
86
54
87
- #[ derive( Copy , Clone ) ]
88
- pub enum OrderingOp {
89
- PartialCmpOp , LtOp , LeOp , GtOp , GeOp ,
90
- }
91
55
92
- pub fn some_ordering_collapsed ( cx : & mut ExtCtxt ,
93
- span : Span ,
94
- op : OrderingOp ,
95
- self_arg_tags : & [ ast:: Ident ] ) -> P < ast:: Expr > {
56
+ pub fn ordering_collapsed ( cx : & mut ExtCtxt ,
57
+ span : Span ,
58
+ self_arg_tags : & [ ast:: Ident ] ) -> P < ast:: Expr > {
96
59
let lft = cx. expr_ident ( span, self_arg_tags[ 0 ] ) ;
97
60
let rgt = cx. expr_addr_of ( span, cx. expr_ident ( span, self_arg_tags[ 1 ] ) ) ;
98
- let op_str = match op {
99
- PartialCmpOp => "partial_cmp" ,
100
- LtOp => "lt" , LeOp => "le" ,
101
- GtOp => "gt" , GeOp => "ge" ,
102
- } ;
103
- cx. expr_method_call ( span, lft, cx. ident_of ( op_str) , vec ! [ rgt] )
61
+ cx. expr_method_call ( span, lft, cx. ident_of ( "cmp" ) , vec ! [ rgt] )
104
62
}
105
63
106
- pub fn cs_partial_cmp ( cx : & mut ExtCtxt , span : Span ,
64
+ pub fn cs_cmp ( cx : & mut ExtCtxt , span : Span ,
107
65
substr : & Substructure ) -> P < Expr > {
108
66
let test_id = cx. ident_of ( "__test" ) ;
109
- let ordering = cx. path_global ( span,
110
- vec ! ( cx. ident_of_std( "core" ) ,
111
- cx. ident_of( "cmp" ) ,
112
- cx. ident_of( "Ordering" ) ,
113
- cx. ident_of( "Equal" ) ) ) ;
114
- let ordering = cx. expr_path ( ordering) ;
115
- let equals_expr = cx. expr_some ( span, ordering) ;
67
+ let equals_path = cx. path_global ( span,
68
+ vec ! ( cx. ident_of_std( "core" ) ,
69
+ cx. ident_of( "cmp" ) ,
70
+ cx. ident_of( "Ordering" ) ,
71
+ cx. ident_of( "Equal" ) ) ) ;
116
72
117
- let partial_cmp_path = vec ! [
73
+ let cmp_path = vec ! [
118
74
cx. ident_of_std( "core" ) ,
119
75
cx. ident_of( "cmp" ) ,
120
- cx. ident_of( "PartialOrd " ) ,
121
- cx. ident_of( "partial_cmp " ) ,
76
+ cx. ident_of( "Ord " ) ,
77
+ cx. ident_of( "cmp " ) ,
122
78
] ;
123
79
124
80
/*
125
81
Builds:
126
82
127
- let __test = ::std::cmp::PartialOrd::partial_cmp (&self_field1, &other_field1);
128
- if __test == ::std::option::Option::Some(::std:: cmp::Ordering::Equal) {
129
- let __test = ::std::cmp::PartialOrd::partial_cmp (&self_field2, &other_field2);
130
- if __test == ::std::option::Option::Some(::std:: cmp::Ordering::Equal) {
83
+ let __test = ::std::cmp::Ord::cmp (&self_field1, &other_field1);
84
+ if other == ::std::cmp::Ordering::Equal {
85
+ let __test = ::std::cmp::Ord::cmp (&self_field2, &other_field2);
86
+ if __test == ::std::cmp::Ordering::Equal {
131
87
...
132
88
} else {
133
89
__test
@@ -144,7 +100,7 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
144
100
false ,
145
101
|cx, span, old, self_f, other_fs| {
146
102
// let __test = new;
147
- // if __test == Some( ::std::cmp::Ordering::Equal) {
103
+ // if __test == ::std::cmp::Ordering::Equal {
148
104
// old
149
105
// } else {
150
106
// __test
@@ -161,77 +117,25 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
161
117
cx. expr_addr_of( span, other_f. clone( ) ) ,
162
118
] ;
163
119
164
- cx. expr_call_global ( span, partial_cmp_path . clone ( ) , args)
120
+ cx. expr_call_global ( span, cmp_path . clone ( ) , args)
165
121
} ;
166
122
167
123
let assign = cx. stmt_let ( span, false , test_id, new) ;
168
124
169
125
let cond = cx. expr_binary ( span, ast:: BiEq ,
170
126
cx. expr_ident ( span, test_id) ,
171
- equals_expr . clone ( ) ) ;
127
+ cx . expr_path ( equals_path . clone ( ) ) ) ;
172
128
let if_ = cx. expr_if ( span,
173
129
cond,
174
130
old, Some ( cx. expr_ident ( span, test_id) ) ) ;
175
131
cx. expr_block ( cx. block ( span, vec ! ( assign) , Some ( if_) ) )
176
132
} ,
177
- equals_expr . clone ( ) ,
133
+ cx . expr_path ( equals_path . clone ( ) ) ,
178
134
Box :: new ( |cx, span, ( self_args, tag_tuple) , _non_self_args| {
179
135
if self_args. len ( ) != 2 {
180
- cx. span_bug ( span, "not exactly 2 arguments in `derive(PartialOrd )`" )
136
+ cx. span_bug ( span, "not exactly 2 arguments in `derives(Ord )`" )
181
137
} else {
182
- some_ordering_collapsed ( cx, span, PartialCmpOp , tag_tuple)
183
- }
184
- } ) ,
185
- cx, span, substr)
186
- }
187
-
188
- /// Strict inequality.
189
- fn cs_op ( less : bool , equal : bool , cx : & mut ExtCtxt ,
190
- span : Span , substr : & Substructure ) -> P < Expr > {
191
- let op = if less { ast:: BiLt } else { ast:: BiGt } ;
192
- cs_fold (
193
- false , // need foldr,
194
- |cx, span, subexpr, self_f, other_fs| {
195
- /*
196
- build up a series of chain ||'s and &&'s from the inside
197
- out (hence foldr) to get lexical ordering, i.e. for op ==
198
- `ast::lt`
199
-
200
- ```
201
- self.f1 < other.f1 || (!(other.f1 < self.f1) &&
202
- (self.f2 < other.f2 || (!(other.f2 < self.f2) &&
203
- (false)
204
- ))
205
- )
206
- ```
207
-
208
- The optimiser should remove the redundancy. We explicitly
209
- get use the binops to avoid auto-deref dereferencing too many
210
- layers of pointers, if the type includes pointers.
211
- */
212
- let other_f = match other_fs {
213
- [ ref o_f] => o_f,
214
- _ => cx. span_bug ( span, "not exactly 2 arguments in `derive(PartialOrd)`" )
215
- } ;
216
-
217
- let cmp = cx. expr_binary ( span, op, self_f. clone ( ) , other_f. clone ( ) ) ;
218
-
219
- let not_cmp = cx. expr_unary ( span, ast:: UnNot ,
220
- cx. expr_binary ( span, op, other_f. clone ( ) , self_f) ) ;
221
-
222
- let and = cx. expr_binary ( span, ast:: BiAnd , not_cmp, subexpr) ;
223
- cx. expr_binary ( span, ast:: BiOr , cmp, and)
224
- } ,
225
- cx. expr_bool ( span, equal) ,
226
- Box :: new ( |cx, span, ( self_args, tag_tuple) , _non_self_args| {
227
- if self_args. len ( ) != 2 {
228
- cx. span_bug ( span, "not exactly 2 arguments in `derive(PartialOrd)`" )
229
- } else {
230
- let op = match ( less, equal) {
231
- ( true , true ) => LeOp , ( true , false ) => LtOp ,
232
- ( false , true ) => GeOp , ( false , false ) => GtOp ,
233
- } ;
234
- some_ordering_collapsed ( cx, span, op, tag_tuple)
138
+ ordering_collapsed ( cx, span, tag_tuple)
235
139
}
236
140
} ) ,
237
141
cx, span, substr)
0 commit comments