Skip to content

Commit 0d0c004

Browse files
committed
auto merge of #6988 : huonw/rust/deriving-changes, r=bstrie
Several minor changes: - The clean-up I mentioned in #6851 (moving functions from deriving/mod.rs to deriving/generic.rs) - Move `expand_generic_deriving` to a method - Reimplement `deriving(Ord)` with no dependence on `Eq`
2 parents af863cf + a965f49 commit 0d0c004

File tree

12 files changed

+254
-365
lines changed

12 files changed

+254
-365
lines changed

src/libsyntax/ext/deriving/clone.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ pub fn expand_deriving_clone(cx: @ExtCtxt,
3838
]
3939
};
4040

41-
expand_deriving_generic(cx, span,
42-
mitem, in_items,
43-
&trait_def)
41+
trait_def.expand(cx, span, mitem, in_items)
4442
}
4543

4644
pub fn expand_deriving_deep_clone(cx: @ExtCtxt,
@@ -67,9 +65,7 @@ pub fn expand_deriving_deep_clone(cx: @ExtCtxt,
6765
]
6866
};
6967

70-
expand_deriving_generic(cx, span,
71-
mitem, in_items,
72-
&trait_def)
68+
trait_def.expand(cx, span, mitem, in_items)
7369
}
7470

7571
fn cs_clone(

src/libsyntax/ext/deriving/cmp/eq.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,5 @@ pub fn expand_deriving_eq(cx: @ExtCtxt,
5454
md!("ne", cs_ne)
5555
]
5656
};
57-
58-
expand_deriving_generic(cx, span, mitem, in_items,
59-
&trait_def)
57+
trait_def.expand(cx, span, mitem, in_items)
6058
}

src/libsyntax/ext/deriving/cmp/ord.rs

Lines changed: 41 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
use core::prelude::*;
1212

13+
use ast;
1314
use ast::{meta_item, item, expr};
1415
use codemap::span;
1516
use ext::base::ExtCtxt;
@@ -21,104 +22,86 @@ pub fn expand_deriving_ord(cx: @ExtCtxt,
2122
mitem: @meta_item,
2223
in_items: ~[@item]) -> ~[@item] {
2324
macro_rules! md (
24-
($name:expr, $less:expr, $equal:expr) => {
25+
($name:expr, $op:expr, $equal:expr) => {
2526
MethodDef {
2627
name: $name,
2728
generics: LifetimeBounds::empty(),
2829
explicit_self: borrowed_explicit_self(),
2930
args: ~[borrowed_self()],
3031
ret_ty: Literal(Path::new(~["bool"])),
3132
const_nonmatching: false,
32-
combine_substructure: |cx, span, substr|
33-
cs_ord($less, $equal, cx, span, substr)
33+
combine_substructure: |cx, span, substr| cs_op($op, $equal, cx, span, substr)
3434
}
3535
}
3636
);
3737

38-
39-
4038
let trait_def = TraitDef {
4139
path: Path::new(~["std", "cmp", "Ord"]),
42-
// XXX: Ord doesn't imply Eq yet
43-
additional_bounds: ~[Literal(Path::new(~["std", "cmp", "Eq"]))],
40+
additional_bounds: ~[],
4441
generics: LifetimeBounds::empty(),
4542
methods: ~[
46-
md!("lt", true, false),
47-
md!("le", true, true),
43+
md!("lt", true, false),
44+
md!("le", true, true),
4845
md!("gt", false, false),
4946
md!("ge", false, true)
5047
]
5148
};
52-
53-
expand_deriving_generic(cx, span, mitem, in_items,
54-
&trait_def)
49+
trait_def.expand(cx, span, mitem, in_items)
5550
}
5651

57-
/// `less`: is this `lt` or `le`? `equal`: is this `le` or `ge`?
58-
fn cs_ord(less: bool, equal: bool,
59-
cx: @ExtCtxt, span: span,
60-
substr: &Substructure) -> @expr {
61-
let binop = if less {
62-
cx.ident_of("lt")
63-
} else {
64-
cx.ident_of("gt")
65-
};
66-
let base = cx.expr_bool(span, equal);
67-
52+
/// Strict inequality.
53+
fn cs_op(less: bool, equal: bool, cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
54+
let op = if less {ast::lt} else {ast::gt};
6855
cs_fold(
6956
false, // need foldr,
7057
|cx, span, subexpr, self_f, other_fs| {
7158
/*
72-
73-
build up a series of nested ifs from the inside out to get
74-
lexical ordering (hence foldr), i.e.
59+
build up a series of chain ||'s and &&'s from the inside
60+
out (hence foldr) to get lexical ordering, i.e. for op ==
61+
`ast::lt`
7562
7663
```
77-
if self.f1 `binop` other.f1 {
78-
true
79-
} else if self.f1 == other.f1 {
80-
if self.f2 `binop` other.f2 {
81-
true
82-
} else if self.f2 == other.f2 {
83-
`equal`
84-
} else {
85-
false
86-
}
87-
} else {
88-
false
89-
}
64+
self.f1 < other.f1 || (!(other.f1 < self.f1) &&
65+
(self.f2 < other.f2 || (!(other.f2 < self.f2) &&
66+
(false)
67+
))
68+
)
9069
```
9170
92-
The inner "`equal`" case is only reached if the two
93-
items have all fields equal.
71+
The optimiser should remove the redundancy. We explicitly
72+
get use the binops to avoid auto-deref derefencing too many
73+
layers of pointers, if the type includes pointers.
9474
*/
95-
if other_fs.len() != 1 {
96-
cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`");
97-
}
75+
let other_f = match other_fs {
76+
[o_f] => o_f,
77+
_ => cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`")
78+
};
79+
80+
let cmp = cx.expr_binary(span, op,
81+
cx.expr_deref(span, self_f),
82+
cx.expr_deref(span, other_f));
9883

99-
let cmp = cx.expr_method_call(span,
100-
self_f, cx.ident_of("eq"), other_fs.to_owned());
101-
let elseif = cx.expr_if(span, cmp,
102-
subexpr, Some(cx.expr_bool(span, false)));
84+
let not_cmp = cx.expr_unary(span, ast::not,
85+
cx.expr_binary(span, op,
86+
cx.expr_deref(span, other_f),
87+
cx.expr_deref(span, self_f)));
10388

104-
let cmp = cx.expr_method_call(span,
105-
self_f, binop, other_fs.to_owned());
106-
cx.expr_if(span, cmp,
107-
cx.expr_bool(span, true), Some(elseif))
89+
let and = cx.expr_binary(span, ast::and, not_cmp, subexpr);
90+
cx.expr_binary(span, ast::or, cmp, and)
10891
},
109-
base,
92+
cx.expr_bool(span, equal),
11093
|cx, span, args, _| {
11194
// nonmatching enums, order by the order the variants are
11295
// written
11396
match args {
11497
[(self_var, _, _),
11598
(other_var, _, _)] =>
11699
cx.expr_bool(span,
117-
if less {
118-
self_var < other_var
119-
} else {
120-
self_var > other_var
121-
}),
100+
if less {
101+
self_var < other_var
102+
} else {
103+
self_var > other_var
104+
}),
122105
_ => cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`")
123106
}
124107
},

src/libsyntax/ext/deriving/cmp/totaleq.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,5 @@ pub fn expand_deriving_totaleq(cx: @ExtCtxt,
4242
}
4343
]
4444
};
45-
46-
expand_deriving_generic(cx, span, mitem, in_items,
47-
&trait_def)
45+
trait_def.expand(cx, span, mitem, in_items)
4846
}

src/libsyntax/ext/deriving/cmp/totalord.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ pub fn expand_deriving_totalord(cx: @ExtCtxt,
3838
]
3939
};
4040

41-
expand_deriving_generic(cx, span, mitem, in_items,
42-
&trait_def)
41+
trait_def.expand(cx, span, mitem, in_items)
4342
}
4443

4544

src/libsyntax/ext/deriving/decodable.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,7 @@ pub fn expand_deriving_decodable(cx: @ExtCtxt,
4949
]
5050
};
5151

52-
expand_deriving_generic(cx, span, mitem, in_items,
53-
&trait_def)
52+
trait_def.expand(cx, span, mitem, in_items)
5453
}
5554

5655
fn decodable_substructure(cx: @ExtCtxt, span: span,

src/libsyntax/ext/deriving/encodable.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,7 @@ pub fn expand_deriving_encodable(cx: @ExtCtxt,
109109
]
110110
};
111111

112-
expand_deriving_generic(cx, span, mitem, in_items,
113-
&trait_def)
112+
trait_def.expand(cx, span, mitem, in_items)
114113
}
115114

116115
fn encodable_substructure(cx: @ExtCtxt, span: span,

0 commit comments

Comments
 (0)