1
- pub use OrderingOp :: * ;
2
-
3
1
use crate :: deriving:: generic:: ty:: * ;
4
2
use crate :: deriving:: generic:: * ;
5
- use crate :: deriving:: { path_local , path_std, pathvec_std} ;
3
+ use crate :: deriving:: { path_std, pathvec_std} ;
6
4
7
5
use rustc_ast:: ptr:: P ;
8
- use rustc_ast:: { self as ast , BinOpKind , Expr , MetaItem } ;
6
+ use rustc_ast:: { Expr , MetaItem } ;
9
7
use rustc_expand:: base:: { Annotatable , ExtCtxt } ;
10
- use rustc_span:: symbol:: { sym, Ident , Symbol } ;
8
+ use rustc_span:: symbol:: { sym, Ident } ;
11
9
use rustc_span:: Span ;
12
10
13
11
pub fn expand_deriving_partial_ord (
@@ -17,26 +15,6 @@ pub fn expand_deriving_partial_ord(
17
15
item : & Annotatable ,
18
16
push : & mut dyn FnMut ( Annotatable ) ,
19
17
) {
20
- macro_rules! md {
21
- ( $name: expr, $op: expr, $equal: expr) => { {
22
- let inline = cx. meta_word( span, sym:: inline) ;
23
- let attrs = vec![ cx. attribute( inline) ] ;
24
- MethodDef {
25
- name: $name,
26
- generics: Bounds :: empty( ) ,
27
- explicit_self: borrowed_explicit_self( ) ,
28
- args: vec![ ( borrowed_self( ) , sym:: other) ] ,
29
- ret_ty: Literal ( path_local!( bool ) ) ,
30
- attributes: attrs,
31
- is_unsafe: false ,
32
- unify_fieldless_variants: true ,
33
- combine_substructure: combine_substructure( Box :: new( |cx, span, substr| {
34
- cs_op( $op, $equal, cx, span, substr)
35
- } ) ) ,
36
- }
37
- } } ;
38
- }
39
-
40
18
let ordering_ty = Literal ( path_std ! ( cmp:: Ordering ) ) ;
41
19
let ret_ty = Literal ( Path :: new_ (
42
20
pathvec_std ! ( option:: Option ) ,
@@ -62,21 +40,6 @@ pub fn expand_deriving_partial_ord(
62
40
} ) ) ,
63
41
} ;
64
42
65
- // avoid defining extra methods if we can
66
- // c-like enums, enums without any fields and structs without fields
67
- // can safely define only `partial_cmp`.
68
- let methods = if is_type_without_fields ( item) {
69
- vec ! [ partial_cmp_def]
70
- } else {
71
- vec ! [
72
- partial_cmp_def,
73
- md!( sym:: lt, true , false ) ,
74
- md!( sym:: le, true , true ) ,
75
- md!( sym:: gt, false , false ) ,
76
- md!( sym:: ge, false , true ) ,
77
- ]
78
- } ;
79
-
80
43
let trait_def = TraitDef {
81
44
span,
82
45
attributes : vec ! [ ] ,
@@ -85,39 +48,12 @@ pub fn expand_deriving_partial_ord(
85
48
generics : Bounds :: empty ( ) ,
86
49
is_unsafe : false ,
87
50
supports_unions : false ,
88
- methods,
51
+ methods : vec ! [ partial_cmp_def ] ,
89
52
associated_types : Vec :: new ( ) ,
90
53
} ;
91
54
trait_def. expand ( cx, mitem, item, push)
92
55
}
93
56
94
- #[ derive( Copy , Clone ) ]
95
- pub enum OrderingOp {
96
- PartialCmpOp ,
97
- LtOp ,
98
- LeOp ,
99
- GtOp ,
100
- GeOp ,
101
- }
102
-
103
- pub fn some_ordering_collapsed (
104
- cx : & mut ExtCtxt < ' _ > ,
105
- span : Span ,
106
- op : OrderingOp ,
107
- self_arg_tags : & [ Ident ] ,
108
- ) -> P < ast:: Expr > {
109
- let lft = cx. expr_ident ( span, self_arg_tags[ 0 ] ) ;
110
- let rgt = cx. expr_addr_of ( span, cx. expr_ident ( span, self_arg_tags[ 1 ] ) ) ;
111
- let op_sym = match op {
112
- PartialCmpOp => sym:: partial_cmp,
113
- LtOp => sym:: lt,
114
- LeOp => sym:: le,
115
- GtOp => sym:: gt,
116
- GeOp => sym:: ge,
117
- } ;
118
- cx. expr_method_call ( span, lft, Ident :: new ( op_sym, span) , vec ! [ rgt] )
119
- }
120
-
121
57
pub fn cs_partial_cmp ( cx : & mut ExtCtxt < ' _ > , span : Span , substr : & Substructure < ' _ > ) -> P < Expr > {
122
58
let test_id = Ident :: new ( sym:: cmp, span) ;
123
59
let ordering = cx. path_global ( span, cx. std_path ( & [ sym:: cmp, sym:: Ordering , sym:: Equal ] ) ) ;
@@ -171,132 +107,13 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_
171
107
if self_args. len ( ) != 2 {
172
108
cx. span_bug ( span, "not exactly 2 arguments in `derive(PartialOrd)`" )
173
109
} else {
174
- some_ordering_collapsed ( cx, span, PartialCmpOp , tag_tuple)
110
+ let lft = cx. expr_ident ( span, tag_tuple[ 0 ] ) ;
111
+ let rgt = cx. expr_addr_of ( span, cx. expr_ident ( span, tag_tuple[ 1 ] ) ) ;
112
+ cx. expr_method_call ( span, lft, Ident :: new ( sym:: partial_cmp, span) , vec ! [ rgt] )
175
113
}
176
114
} ) ,
177
115
cx,
178
116
span,
179
117
substr,
180
118
)
181
119
}
182
-
183
- /// Strict inequality.
184
- fn cs_op (
185
- less : bool ,
186
- inclusive : bool ,
187
- cx : & mut ExtCtxt < ' _ > ,
188
- span : Span ,
189
- substr : & Substructure < ' _ > ,
190
- ) -> P < Expr > {
191
- let ordering_path = |cx : & mut ExtCtxt < ' _ > , name : & str | {
192
- cx. expr_path (
193
- cx. path_global ( span, cx. std_path ( & [ sym:: cmp, sym:: Ordering , Symbol :: intern ( name) ] ) ) ,
194
- )
195
- } ;
196
-
197
- let par_cmp = |cx : & mut ExtCtxt < ' _ > , span, self_f : P < Expr > , other_fs : & [ P < Expr > ] , default| {
198
- let other_f = match other_fs {
199
- [ o_f] => o_f,
200
- _ => cx. span_bug ( span, "not exactly 2 arguments in `derive(PartialOrd)`" ) ,
201
- } ;
202
-
203
- // `PartialOrd::partial_cmp(self.fi, other.fi)`
204
- let cmp_path = cx. expr_path (
205
- cx. path_global ( span, cx. std_path ( & [ sym:: cmp, sym:: PartialOrd , sym:: partial_cmp] ) ) ,
206
- ) ;
207
- let cmp = cx. expr_call (
208
- span,
209
- cmp_path,
210
- vec ! [ cx. expr_addr_of( span, self_f) , cx. expr_addr_of( span, other_f. clone( ) ) ] ,
211
- ) ;
212
-
213
- let default = ordering_path ( cx, default) ;
214
- // `Option::unwrap_or(_, Ordering::Equal)`
215
- let unwrap_path = cx. expr_path (
216
- cx. path_global ( span, cx. std_path ( & [ sym:: option, sym:: Option , sym:: unwrap_or] ) ) ,
217
- ) ;
218
- cx. expr_call ( span, unwrap_path, vec ! [ cmp, default ] )
219
- } ;
220
-
221
- let fold = cs_fold1 (
222
- false , // need foldr
223
- |cx, span, subexpr, self_f, other_fs| {
224
- // build up a series of `partial_cmp`s from the inside
225
- // out (hence foldr) to get lexical ordering, i.e., for op ==
226
- // `ast::lt`
227
- //
228
- // ```
229
- // Ordering::then_with(
230
- // Option::unwrap_or(
231
- // PartialOrd::partial_cmp(self.f1, other.f1), Ordering::Equal)
232
- // ),
233
- // Option::unwrap_or(
234
- // PartialOrd::partial_cmp(self.f2, other.f2), Ordering::Greater)
235
- // )
236
- // )
237
- // == Ordering::Less
238
- // ```
239
- //
240
- // and for op ==
241
- // `ast::le`
242
- //
243
- // ```
244
- // Ordering::then_with(
245
- // Option::unwrap_or(
246
- // PartialOrd::partial_cmp(self.f1, other.f1), Ordering::Equal)
247
- // ),
248
- // Option::unwrap_or(
249
- // PartialOrd::partial_cmp(self.f2, other.f2), Ordering::Greater)
250
- // )
251
- // )
252
- // != Ordering::Greater
253
- // ```
254
- //
255
- // The optimiser should remove the redundancy. We explicitly
256
- // get use the binops to avoid auto-deref dereferencing too many
257
- // layers of pointers, if the type includes pointers.
258
-
259
- // `Option::unwrap_or(PartialOrd::partial_cmp(self.fi, other.fi), Ordering::Equal)`
260
- let par_cmp = par_cmp ( cx, span, self_f, other_fs, "Equal" ) ;
261
-
262
- // `Ordering::then_with(Option::unwrap_or(..), ..)`
263
- let then_with_path = cx. expr_path (
264
- cx. path_global ( span, cx. std_path ( & [ sym:: cmp, sym:: Ordering , sym:: then_with] ) ) ,
265
- ) ;
266
- cx. expr_call ( span, then_with_path, vec ! [ par_cmp, cx. lambda0( span, subexpr) ] )
267
- } ,
268
- |cx, args| match args {
269
- Some ( ( span, self_f, other_fs) ) => {
270
- let opposite = if less { "Greater" } else { "Less" } ;
271
- par_cmp ( cx, span, self_f, other_fs, opposite)
272
- }
273
- None => cx. expr_bool ( span, inclusive) ,
274
- } ,
275
- Box :: new ( |cx, span, ( self_args, tag_tuple) , _non_self_args| {
276
- if self_args. len ( ) != 2 {
277
- cx. span_bug ( span, "not exactly 2 arguments in `derive(PartialOrd)`" )
278
- } else {
279
- let op = match ( less, inclusive) {
280
- ( false , false ) => GtOp ,
281
- ( false , true ) => GeOp ,
282
- ( true , false ) => LtOp ,
283
- ( true , true ) => LeOp ,
284
- } ;
285
- some_ordering_collapsed ( cx, span, op, tag_tuple)
286
- }
287
- } ) ,
288
- cx,
289
- span,
290
- substr,
291
- ) ;
292
-
293
- match * substr. fields {
294
- EnumMatching ( .., ref all_fields) | Struct ( .., ref all_fields) if !all_fields. is_empty ( ) => {
295
- let ordering = ordering_path ( cx, if less ^ inclusive { "Less" } else { "Greater" } ) ;
296
- let comp_op = if inclusive { BinOpKind :: Ne } else { BinOpKind :: Eq } ;
297
-
298
- cx. expr_binary ( span, comp_op, fold, ordering)
299
- }
300
- _ => fold,
301
- }
302
- }
0 commit comments