(index<- )        ./libsyntax/ext/deriving/cmp/totaleq.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri Apr 25 22:40:04 2014
  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.
  4  //
  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.
 10  
 11  use ast::{MetaItem, Item, Expr};
 12  use codemap::Span;
 13  use ext::base::ExtCtxt;
 14  use ext::build::AstBuilder;
 15  use ext::deriving::generic::*;
 16  use parse::token::InternedString;
 17  
 18  pub fn expand_deriving_totaleq(cx: &mut ExtCtxt,
 19                                 spanSpan,
 20                                 mitem: @MetaItem,
 21                                 item: @Item,
 22                                 push: |@Item|) {
 23      fn cs_total_eq_assert(cx&mut ExtCtxt, spanSpan, substr&Substructure) -> @Expr {
 24          cs_same_method(|cx, span, exprs| {
 25              // create `a.<method>(); b.<method>(); c.<method>(); ...`
 26              // (where method is `assert_receiver_is_total_eq`)
 27              let stmts = exprs.move_iter().map(|e| cx.stmt_expr(e)).collect();
 28              let block = cx.block(span, stmts, None);
 29              cx.expr_block(block)
 30          },
 31                         |cx, sp, _, _| cx.span_bug(sp, "non matching enums in deriving(TotalEq)?"),
 32                         cx,
 33                         span,
 34                         substr)
 35      }
 36  
 37      let inline = cx.meta_word(span, InternedString::new("inline"));
 38      let hidden = cx.meta_word(span, InternedString::new("hidden"));
 39      let doc = cx.meta_list(span, InternedString::new("doc"), vec!(hidden));
 40      let attrs = vec!(cx.attribute(span, inline),
 41                       cx.attribute(span, doc));
 42      let trait_def = TraitDef {
 43          span: span,
 44          attributes: Vec::new(),
 45          path: Path::new(vec!("std", "cmp", "TotalEq")),
 46          additional_bounds: Vec::new(),
 47          generics: LifetimeBounds::empty(),
 48          methods: vec!(
 49              MethodDef {
 50                  name: "assert_receiver_is_total_eq",
 51                  generics: LifetimeBounds::empty(),
 52                  explicit_self: borrowed_explicit_self(),
 53                  args: vec!(),
 54                  ret_ty: nil_ty(),
 55                  attributes: attrs,
 56                  const_nonmatching: true,
 57                  combine_substructure: combine_substructure(|a, b, c| {
 58                      cs_total_eq_assert(a, b, c)
 59                  })
 60              }
 61          )
 62      };
 63      trait_def.expand(cx, mitem, item, push)
 64  }