@@ -190,58 +190,79 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<
190
190
191
191
/// Strict inequality.
192
192
fn cs_op ( less : bool , equal : bool , cx : & mut ExtCtxt , span : Span , substr : & Substructure ) -> P < Expr > {
193
- let op = if less { BinOpKind :: Lt } else { BinOpKind :: Gt } ;
194
- cs_fold ( false , // need foldr,
195
- |cx, span, subexpr, self_f, other_fs| {
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. len ( ) , other_fs. get ( 0 ) ) {
213
- ( 1 , Some ( o_f) ) => o_f,
214
- _ => cx. span_bug ( span, "not exactly 2 arguments in `derive(PartialOrd)`" ) ,
215
- } ;
216
-
217
- let strict_ineq = cx. expr_binary ( span, op, self_f. clone ( ) , other_f. clone ( ) ) ;
193
+ let strict_op = if less { BinOpKind :: Lt } else { BinOpKind :: Gt } ;
194
+ cs_fold1 ( false , // need foldr,
195
+ |cx, span, subexpr, self_f, other_fs| {
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. len ( ) , other_fs. get ( 0 ) ) {
213
+ ( 1 , Some ( o_f) ) => o_f,
214
+ _ => cx. span_bug ( span, "not exactly 2 arguments in `derive(PartialOrd)`" ) ,
215
+ } ;
218
216
219
- let deleg_cmp = if !equal {
220
- cx. expr_unary ( span,
221
- ast:: UnOp :: Not ,
222
- cx. expr_binary ( span, op, other_f. clone ( ) , self_f) )
223
- } else {
224
- cx. expr_binary ( span, BinOpKind :: Eq , self_f, other_f. clone ( ) )
225
- } ;
217
+ let strict_ineq = cx. expr_binary ( span, strict_op, self_f. clone ( ) , other_f. clone ( ) ) ;
226
218
227
- let and = cx. expr_binary ( span, BinOpKind :: And , deleg_cmp, subexpr) ;
228
- cx. expr_binary ( span, BinOpKind :: Or , strict_ineq, and)
229
- } ,
230
- cx. expr_bool ( span, equal) ,
231
- Box :: new ( |cx, span, ( self_args, tag_tuple) , _non_self_args| {
232
- if self_args. len ( ) != 2 {
233
- cx. span_bug ( span, "not exactly 2 arguments in `derive(PartialOrd)`" )
234
- } else {
235
- let op = match ( less, equal) {
236
- ( true , true ) => LeOp ,
237
- ( true , false ) => LtOp ,
238
- ( false , true ) => GeOp ,
239
- ( false , false ) => GtOp ,
219
+ let deleg_cmp = if !equal {
220
+ cx. expr_unary ( span,
221
+ ast:: UnOp :: Not ,
222
+ cx. expr_binary ( span, strict_op, other_f. clone ( ) , self_f) )
223
+ } else {
224
+ cx. expr_binary ( span, BinOpKind :: Eq , self_f, other_f. clone ( ) )
240
225
} ;
241
- some_ordering_collapsed ( cx, span, op, tag_tuple)
242
- }
243
- } ) ,
244
- cx,
245
- span,
246
- substr)
226
+
227
+ let and = cx. expr_binary ( span, BinOpKind :: And , deleg_cmp, subexpr) ;
228
+ cx. expr_binary ( span, BinOpKind :: Or , strict_ineq, and)
229
+ } ,
230
+ |cx, args| {
231
+ match args {
232
+ Some ( ( span, self_f, other_fs) ) => {
233
+ // Special-case the base case to generate cleaner code with
234
+ // fewer operations (e.g. `<=` instead of `<` and `==`).
235
+ let other_f = match ( other_fs. len ( ) , other_fs. get ( 0 ) ) {
236
+ ( 1 , Some ( o_f) ) => o_f,
237
+ _ => cx. span_bug ( span, "not exactly 2 arguments in `derive(PartialOrd)`" ) ,
238
+ } ;
239
+
240
+ let op = match ( less, equal) {
241
+ ( false , false ) => BinOpKind :: Gt ,
242
+ ( false , true ) => BinOpKind :: Ge ,
243
+ ( true , false ) => BinOpKind :: Lt ,
244
+ ( true , true ) => BinOpKind :: Le ,
245
+ } ;
246
+
247
+ cx. expr_binary ( span, op, self_f, other_f. clone ( ) )
248
+ }
249
+ None => cx. expr_bool ( span, equal)
250
+ }
251
+ } ,
252
+ Box :: new ( |cx, span, ( self_args, tag_tuple) , _non_self_args| {
253
+ if self_args. len ( ) != 2 {
254
+ cx. span_bug ( span, "not exactly 2 arguments in `derive(PartialOrd)`" )
255
+ } else {
256
+ let op = match ( less, equal) {
257
+ ( false , false ) => GtOp ,
258
+ ( false , true ) => GeOp ,
259
+ ( true , false ) => LtOp ,
260
+ ( true , true ) => LeOp ,
261
+ } ;
262
+ some_ordering_collapsed ( cx, span, op, tag_tuple)
263
+ }
264
+ } ) ,
265
+ cx,
266
+ span,
267
+ substr)
247
268
}
0 commit comments