]>
git.proxmox.com Git - rustc.git/blob - src/libsyntax_ext/deriving/cmp/ord.rs
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use deriving
::generic
::*;
12 use deriving
::generic
::ty
::*;
14 use syntax
::ast
::{MetaItem, Expr, self}
;
15 use syntax
::codemap
::Span
;
16 use syntax
::ext
::base
::{ExtCtxt, Annotatable}
;
17 use syntax
::ext
::build
::AstBuilder
;
18 use syntax
::parse
::token
::InternedString
;
21 pub fn expand_deriving_ord(cx
: &mut ExtCtxt
,
25 push
: &mut FnMut(Annotatable
))
27 let inline
= cx
.meta_word(span
, InternedString
::new("inline"));
28 let attrs
= vec
!(cx
.attribute(span
, inline
));
29 let trait_def
= TraitDef
{
31 attributes
: Vec
::new(),
32 path
: path_std
!(cx
, core
::cmp
::Ord
),
33 additional_bounds
: Vec
::new(),
34 generics
: LifetimeBounds
::empty(),
39 generics
: LifetimeBounds
::empty(),
40 explicit_self
: borrowed_explicit_self(),
41 args
: vec
!(borrowed_self()),
42 ret_ty
: Literal(path_std
!(cx
, core
::cmp
::Ordering
)),
45 combine_substructure
: combine_substructure(Box
::new(|a
, b
, c
| {
50 associated_types
: Vec
::new(),
53 trait_def
.expand(cx
, mitem
, item
, push
)
57 pub fn ordering_collapsed(cx
: &mut ExtCtxt
,
59 self_arg_tags
: &[ast
::Ident
]) -> P
<ast
::Expr
> {
60 let lft
= cx
.expr_ident(span
, self_arg_tags
[0]);
61 let rgt
= cx
.expr_addr_of(span
, cx
.expr_ident(span
, self_arg_tags
[1]));
62 cx
.expr_method_call(span
, lft
, cx
.ident_of("cmp"), vec
![rgt
])
65 pub fn cs_cmp(cx
: &mut ExtCtxt
, span
: Span
,
66 substr
: &Substructure
) -> P
<Expr
> {
67 let test_id
= cx
.ident_of("__cmp");
68 let equals_path
= cx
.path_global(span
,
69 cx
.std_path(&["cmp", "Ordering", "Equal"]));
71 let cmp_path
= cx
.std_path(&["cmp", "Ord", "cmp"]);
76 match ::std::cmp::Ord::cmp(&self_field1, &other_field1) {
77 ::std::cmp::Ordering::Equal =>
78 match ::std::cmp::Ord::cmp(&self_field2, &other_field2) {
79 ::std::cmp::Ordering::Equal => {
88 // foldr nests the if-elses correctly, leaving the first field
89 // as the outermost one, and the last as the innermost.
91 |cx
, span
, old
, self_f
, other_fs
| {
93 // ::std::cmp::Ordering::Equal => old,
98 let other_f
= match (other_fs
.len(), other_fs
.get(0)) {
99 (1, Some(o_f
)) => o_f
,
100 _
=> cx
.span_bug(span
, "not exactly 2 arguments in `derive(Ord)`"),
104 cx
.expr_addr_of(span
, self_f
),
105 cx
.expr_addr_of(span
, other_f
.clone()),
108 cx
.expr_call_global(span
, cmp_path
.clone(), args
)
111 let eq_arm
= cx
.arm(span
,
112 vec
![cx
.pat_enum(span
,
116 let neq_arm
= cx
.arm(span
,
117 vec
![cx
.pat_ident(span
, test_id
)],
118 cx
.expr_ident(span
, test_id
));
120 cx
.expr_match(span
, new
, vec
![eq_arm
, neq_arm
])
122 cx
.expr_path(equals_path
.clone()),
123 Box
::new(|cx
, span
, (self_args
, tag_tuple
), _non_self_args
| {
124 if self_args
.len() != 2 {
125 cx
.span_bug(span
, "not exactly 2 arguments in `derive(Ord)`")
127 ordering_collapsed(cx
, span
, tag_tuple
)