]>
git.proxmox.com Git - rustc.git/blob - src/libsyntax_ext/deriving/cmp/eq.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
::{self, Expr, MetaItem}
;
15 use syntax
::ext
::base
::{Annotatable, ExtCtxt}
;
16 use syntax
::ext
::build
::AstBuilder
;
18 use syntax
::symbol
::Symbol
;
21 pub fn expand_deriving_eq(cx
: &mut ExtCtxt
,
25 push
: &mut FnMut(Annotatable
)) {
26 let inline
= cx
.meta_word(span
, Symbol
::intern("inline"));
27 let hidden
= cx
.meta_list_item_word(span
, Symbol
::intern("hidden"));
28 let doc
= cx
.meta_list(span
, Symbol
::intern("doc"), vec
![hidden
]);
29 let attrs
= vec
![cx
.attribute(span
, inline
), cx
.attribute(span
, doc
)];
30 let trait_def
= TraitDef
{
32 attributes
: Vec
::new(),
33 path
: path_std
!(cx
, core
::cmp
::Eq
),
34 additional_bounds
: Vec
::new(),
35 generics
: LifetimeBounds
::empty(),
37 supports_unions
: true,
38 methods
: vec
![MethodDef
{
39 name
: "assert_receiver_is_total_eq",
40 generics
: LifetimeBounds
::empty(),
41 explicit_self
: borrowed_explicit_self(),
46 unify_fieldless_variants
: true,
47 combine_substructure
: combine_substructure(Box
::new(|a
, b
, c
| {
48 cs_total_eq_assert(a
, b
, c
)
51 associated_types
: Vec
::new(),
53 trait_def
.expand_ext(cx
, mitem
, item
, push
, true)
56 fn cs_total_eq_assert(cx
: &mut ExtCtxt
, trait_span
: Span
, substr
: &Substructure
) -> P
<Expr
> {
57 fn assert_ty_bounds(cx
: &mut ExtCtxt
, stmts
: &mut Vec
<ast
::Stmt
>,
58 ty
: P
<ast
::Ty
>, span
: Span
, helper_name
: &str) {
59 // Generate statement `let _: helper_name<ty>;`,
60 // set the expn ID so we can use the unstable struct.
61 let span
= super::allow_unstable(cx
, span
, "derive(Eq)");
62 let assert_path
= cx
.path_all(span
, true,
63 cx
.std_path(&["cmp", helper_name
]),
64 vec
![], vec
![ty
], vec
![]);
65 stmts
.push(cx
.stmt_let_type_only(span
, cx
.ty_path(assert_path
)));
67 fn process_variant(cx
: &mut ExtCtxt
, stmts
: &mut Vec
<ast
::Stmt
>, variant
: &ast
::VariantData
) {
68 for field
in variant
.fields() {
69 // let _: AssertParamIsEq<FieldTy>;
70 assert_ty_bounds(cx
, stmts
, field
.ty
.clone(), field
.span
, "AssertParamIsEq");
74 let mut stmts
= Vec
::new();
75 match *substr
.fields
{
76 StaticStruct(vdata
, ..) => {
77 process_variant(cx
, &mut stmts
, vdata
);
79 StaticEnum(enum_def
, ..) => {
80 for variant
in &enum_def
.variants
{
81 process_variant(cx
, &mut stmts
, &variant
.node
.data
);
84 _
=> cx
.span_bug(trait_span
, "unexpected substructure in `derive(Eq)`")
86 cx
.expr_block(cx
.block(trait_span
, stmts
))