Skip to content

Commit

Permalink
auto merge of #6988 : huonw/rust/deriving-changes, r=bstrie
Browse files Browse the repository at this point in the history
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`
  • Loading branch information
bors committed Jun 7, 2013
2 parents af863cf + a965f49 commit 0d0c004
Show file tree
Hide file tree
Showing 12 changed files with 254 additions and 365 deletions.
8 changes: 2 additions & 6 deletions src/libsyntax/ext/deriving/clone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ pub fn expand_deriving_clone(cx: @ExtCtxt,
]
};

expand_deriving_generic(cx, span,
mitem, in_items,
&trait_def)
trait_def.expand(cx, span, mitem, in_items)
}

pub fn expand_deriving_deep_clone(cx: @ExtCtxt,
Expand All @@ -67,9 +65,7 @@ pub fn expand_deriving_deep_clone(cx: @ExtCtxt,
]
};

expand_deriving_generic(cx, span,
mitem, in_items,
&trait_def)
trait_def.expand(cx, span, mitem, in_items)
}

fn cs_clone(
Expand Down
4 changes: 1 addition & 3 deletions src/libsyntax/ext/deriving/cmp/eq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,5 @@ pub fn expand_deriving_eq(cx: @ExtCtxt,
md!("ne", cs_ne)
]
};

expand_deriving_generic(cx, span, mitem, in_items,
&trait_def)
trait_def.expand(cx, span, mitem, in_items)
}
99 changes: 41 additions & 58 deletions src/libsyntax/ext/deriving/cmp/ord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use core::prelude::*;

use ast;
use ast::{meta_item, item, expr};
use codemap::span;
use ext::base::ExtCtxt;
Expand All @@ -21,104 +22,86 @@ pub fn expand_deriving_ord(cx: @ExtCtxt,
mitem: @meta_item,
in_items: ~[@item]) -> ~[@item] {
macro_rules! md (
($name:expr, $less:expr, $equal:expr) => {
($name:expr, $op:expr, $equal:expr) => {
MethodDef {
name: $name,
generics: LifetimeBounds::empty(),
explicit_self: borrowed_explicit_self(),
args: ~[borrowed_self()],
ret_ty: Literal(Path::new(~["bool"])),
const_nonmatching: false,
combine_substructure: |cx, span, substr|
cs_ord($less, $equal, cx, span, substr)
combine_substructure: |cx, span, substr| cs_op($op, $equal, cx, span, substr)
}
}
);



let trait_def = TraitDef {
path: Path::new(~["std", "cmp", "Ord"]),
// XXX: Ord doesn't imply Eq yet
additional_bounds: ~[Literal(Path::new(~["std", "cmp", "Eq"]))],
additional_bounds: ~[],
generics: LifetimeBounds::empty(),
methods: ~[
md!("lt", true, false),
md!("le", true, true),
md!("lt", true, false),
md!("le", true, true),
md!("gt", false, false),
md!("ge", false, true)
]
};

expand_deriving_generic(cx, span, mitem, in_items,
&trait_def)
trait_def.expand(cx, span, mitem, in_items)
}

/// `less`: is this `lt` or `le`? `equal`: is this `le` or `ge`?
fn cs_ord(less: bool, equal: bool,
cx: @ExtCtxt, span: span,
substr: &Substructure) -> @expr {
let binop = if less {
cx.ident_of("lt")
} else {
cx.ident_of("gt")
};
let base = cx.expr_bool(span, equal);

/// Strict inequality.
fn cs_op(less: bool, equal: bool, cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
let op = if less {ast::lt} else {ast::gt};
cs_fold(
false, // need foldr,
|cx, span, subexpr, self_f, other_fs| {
/*
build up a series of nested ifs from the inside out to get
lexical ordering (hence foldr), i.e.
build up a series of chain ||'s and &&'s from the inside
out (hence foldr) to get lexical ordering, i.e. for op ==
`ast::lt`
```
if self.f1 `binop` other.f1 {
true
} else if self.f1 == other.f1 {
if self.f2 `binop` other.f2 {
true
} else if self.f2 == other.f2 {
`equal`
} else {
false
}
} else {
false
}
self.f1 < other.f1 || (!(other.f1 < self.f1) &&
(self.f2 < other.f2 || (!(other.f2 < self.f2) &&
(false)
))
)
```
The inner "`equal`" case is only reached if the two
items have all fields equal.
The optimiser should remove the redundancy. We explicitly
get use the binops to avoid auto-deref derefencing too many
layers of pointers, if the type includes pointers.
*/
if other_fs.len() != 1 {
cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`");
}
let other_f = match other_fs {
[o_f] => o_f,
_ => cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`")
};

let cmp = cx.expr_binary(span, op,
cx.expr_deref(span, self_f),
cx.expr_deref(span, other_f));

let cmp = cx.expr_method_call(span,
self_f, cx.ident_of("eq"), other_fs.to_owned());
let elseif = cx.expr_if(span, cmp,
subexpr, Some(cx.expr_bool(span, false)));
let not_cmp = cx.expr_unary(span, ast::not,
cx.expr_binary(span, op,
cx.expr_deref(span, other_f),
cx.expr_deref(span, self_f)));

let cmp = cx.expr_method_call(span,
self_f, binop, other_fs.to_owned());
cx.expr_if(span, cmp,
cx.expr_bool(span, true), Some(elseif))
let and = cx.expr_binary(span, ast::and, not_cmp, subexpr);
cx.expr_binary(span, ast::or, cmp, and)
},
base,
cx.expr_bool(span, equal),
|cx, span, args, _| {
// nonmatching enums, order by the order the variants are
// written
match args {
[(self_var, _, _),
(other_var, _, _)] =>
cx.expr_bool(span,
if less {
self_var < other_var
} else {
self_var > other_var
}),
if less {
self_var < other_var
} else {
self_var > other_var
}),
_ => cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`")
}
},
Expand Down
4 changes: 1 addition & 3 deletions src/libsyntax/ext/deriving/cmp/totaleq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,5 @@ pub fn expand_deriving_totaleq(cx: @ExtCtxt,
}
]
};

expand_deriving_generic(cx, span, mitem, in_items,
&trait_def)
trait_def.expand(cx, span, mitem, in_items)
}
3 changes: 1 addition & 2 deletions src/libsyntax/ext/deriving/cmp/totalord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ pub fn expand_deriving_totalord(cx: @ExtCtxt,
]
};

expand_deriving_generic(cx, span, mitem, in_items,
&trait_def)
trait_def.expand(cx, span, mitem, in_items)
}


Expand Down
3 changes: 1 addition & 2 deletions src/libsyntax/ext/deriving/decodable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ pub fn expand_deriving_decodable(cx: @ExtCtxt,
]
};

expand_deriving_generic(cx, span, mitem, in_items,
&trait_def)
trait_def.expand(cx, span, mitem, in_items)
}

fn decodable_substructure(cx: @ExtCtxt, span: span,
Expand Down
3 changes: 1 addition & 2 deletions src/libsyntax/ext/deriving/encodable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,7 @@ pub fn expand_deriving_encodable(cx: @ExtCtxt,
]
};

expand_deriving_generic(cx, span, mitem, in_items,
&trait_def)
trait_def.expand(cx, span, mitem, in_items)
}

fn encodable_substructure(cx: @ExtCtxt, span: span,
Expand Down
Loading

0 comments on commit 0d0c004

Please sign in to comment.