]>
git.proxmox.com Git - rustc.git/blob - src/libsyntax/ext/deriving/cmp/totalord.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.
12 use ast
::{MetaItem, Item, Expr}
;
14 use ext
::base
::ExtCtxt
;
15 use ext
::build
::AstBuilder
;
16 use ext
::deriving
::generic
::*;
17 use ext
::deriving
::generic
::ty
::*;
18 use parse
::token
::InternedString
;
21 pub fn expand_deriving_totalord
<F
>(cx
: &mut ExtCtxt
,
28 let inline
= cx
.meta_word(span
, InternedString
::new("inline"));
29 let attrs
= vec
!(cx
.attribute(span
, inline
));
30 let trait_def
= TraitDef
{
32 attributes
: Vec
::new(),
33 path
: Path
::new(vec
!("std", "cmp", "Ord")),
34 additional_bounds
: Vec
::new(),
35 generics
: LifetimeBounds
::empty(),
39 generics
: LifetimeBounds
::empty(),
40 explicit_self
: borrowed_explicit_self(),
41 args
: vec
!(borrowed_self()),
42 ret_ty
: Literal(Path
::new(vec
!("std", "cmp", "Ordering"))),
44 combine_substructure
: combine_substructure(box |a
, b
, c
| {
51 trait_def
.expand(cx
, mitem
, item
, push
)
55 pub fn ordering_collapsed(cx
: &mut ExtCtxt
,
57 self_arg_tags
: &[ast
::Ident
]) -> P
<ast
::Expr
> {
58 let lft
= cx
.expr_ident(span
, self_arg_tags
[0]);
59 let rgt
= cx
.expr_addr_of(span
, cx
.expr_ident(span
, self_arg_tags
[1]));
60 cx
.expr_method_call(span
, lft
, cx
.ident_of("cmp"), vec
![rgt
])
63 pub fn cs_cmp(cx
: &mut ExtCtxt
, span
: Span
,
64 substr
: &Substructure
) -> P
<Expr
> {
65 let test_id
= cx
.ident_of("__test");
66 let equals_path
= cx
.path_global(span
,
67 vec
!(cx
.ident_of("std"),
69 cx
.ident_of("Ordering"),
70 cx
.ident_of("Equal")));
82 let __test = ::std::cmp::Ord::cmp(&self_field1, &other_field1);
83 if other == ::std::cmp::Ordering::Equal {
84 let __test = ::std::cmp::Ord::cmp(&self_field2, &other_field2);
85 if __test == ::std::cmp::Ordering::Equal {
94 FIXME #6449: These `if`s could/should be `match`es.
97 // foldr nests the if-elses correctly, leaving the first field
98 // as the outermost one, and the last as the innermost.
100 |cx
, span
, old
, self_f
, other_fs
| {
102 // if __test == ::std::cmp::Ordering::Equal {
109 let other_f
= match other_fs
{
111 _
=> cx
.span_bug(span
, "not exactly 2 arguments in `deriving(PartialOrd)`"),
115 cx
.expr_addr_of(span
, self_f
),
116 cx
.expr_addr_of(span
, other_f
.clone()),
119 cx
.expr_call_global(span
, cmp_path
.clone(), args
)
122 let assign
= cx
.stmt_let(span
, false, test_id
, new
);
124 let cond
= cx
.expr_binary(span
, ast
::BiEq
,
125 cx
.expr_ident(span
, test_id
),
126 cx
.expr_path(equals_path
.clone()));
127 let if_
= cx
.expr_if(span
,
129 old
, Some(cx
.expr_ident(span
, test_id
)));
130 cx
.expr_block(cx
.block(span
, vec
!(assign
), Some(if_
)))
132 cx
.expr_path(equals_path
.clone()),
133 box |cx
, span
, (self_args
, tag_tuple
), _non_self_args
| {
134 if self_args
.len() != 2 {
135 cx
.span_bug(span
, "not exactly 2 arguments in `deriving(Ord)`")
137 ordering_collapsed(cx
, span
, tag_tuple
)