diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2015-05-01 15:49:05 +0530 |
|---|---|---|
| committer | Manish Goregaokar <manishsmail@gmail.com> | 2015-05-01 15:49:05 +0530 |
| commit | 4957ecce3ede95c4415dbcc7a136f9d4ebd5cb4e (patch) | |
| tree | 08a1b6374a942f44b67c1ef8565e43ebaf4d3ecc /src | |
| parent | ede7a6dc8ff5455f9d0d39a90e6d11e9a374e93b (diff) | |
| download | rust-4957ecce3ede95c4415dbcc7a136f9d4ebd5cb4e.tar.gz rust-4957ecce3ede95c4415dbcc7a136f9d4ebd5cb4e.zip | |
Add test for custom deriving plugins which rely on field attributes
Diffstat (limited to 'src')
| -rw-r--r-- | src/test/auxiliary/custom_derive_plugin_attr.rs | 86 | ||||
| -rw-r--r-- | src/test/run-pass-fulldeps/derive-totalsum-attr.rs | 74 |
2 files changed, 160 insertions, 0 deletions
diff --git a/src/test/auxiliary/custom_derive_plugin_attr.rs b/src/test/auxiliary/custom_derive_plugin_attr.rs new file mode 100644 index 00000000000..631645ec0c0 --- /dev/null +++ b/src/test/auxiliary/custom_derive_plugin_attr.rs @@ -0,0 +1,86 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// force-host + +#![feature(plugin_registrar)] +#![feature(box_syntax)] +#![feature(rustc_private)] + +extern crate syntax; +extern crate rustc; + +use syntax::ast; +use syntax::attr::AttrMetaMethods; +use syntax::codemap::Span; +use syntax::ext::base::{Decorator, ExtCtxt}; +use syntax::ext::build::AstBuilder; +use syntax::ext::deriving::generic::{cs_fold, TraitDef, MethodDef, combine_substructure}; +use syntax::ext::deriving::generic::{Substructure, Struct, EnumMatching}; +use syntax::ext::deriving::generic::ty::{Literal, LifetimeBounds, Path, borrowed_explicit_self}; +use syntax::parse::token; +use syntax::ptr::P; +use rustc::plugin::Registry; + +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_syntax_extension( + token::intern("derive_TotalSum"), + Decorator(box expand)); +} + +fn expand(cx: &mut ExtCtxt, + span: Span, + mitem: &ast::MetaItem, + item: &ast::Item, + push: &mut FnMut(P<ast::Item>)) { + let trait_def = TraitDef { + span: span, + attributes: vec![], + path: Path::new(vec!["TotalSum"]), + additional_bounds: vec![], + generics: LifetimeBounds::empty(), + associated_types: vec![], + methods: vec![ + MethodDef { + name: "total_sum", + generics: LifetimeBounds::empty(), + explicit_self: borrowed_explicit_self(), + args: vec![], + ret_ty: Literal(Path::new_local("isize")), + attributes: vec![], + combine_substructure: combine_substructure(Box::new(totalsum_substructure)), + }, + ], + }; + + trait_def.expand(cx, mitem, item, push) +} + +// Mostly copied from syntax::ext::deriving::hash +/// Defines how the implementation for `trace()` is to be generated +fn totalsum_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<ast::Expr> { + let fields = match *substr.fields { + Struct(ref fs) | EnumMatching(_, _, ref fs) => fs, + _ => cx.span_bug(trait_span, "impossible substructure") + }; + + fields.iter().fold(cx.expr_int(trait_span, 0), |acc, ref item| { + if item.attrs.iter().find(|a| a.check_name("ignore")).is_some() { + acc + } else { + cx.expr_binary(item.span, ast::BiAdd, acc, + cx.expr_method_call(item.span, + item.self_.clone(), + substr.method_ident, + Vec::new())) + } + }) +} diff --git a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs b/src/test/run-pass-fulldeps/derive-totalsum-attr.rs new file mode 100644 index 00000000000..ef5198b9ae0 --- /dev/null +++ b/src/test/run-pass-fulldeps/derive-totalsum-attr.rs @@ -0,0 +1,74 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:custom_derive_plugin_attr.rs +// ignore-stage1 + +#![feature(plugin, custom_derive, custom_attribute)] +#![plugin(custom_derive_plugin_attr)] + +trait TotalSum { + fn total_sum(&self) -> isize; +} + +impl TotalSum for isize { + fn total_sum(&self) -> isize { + *self + } +} + +struct Seven; + +impl TotalSum for Seven { + fn total_sum(&self) -> isize { + 7 + } +} + +#[derive(TotalSum)] +struct Foo { + seven: Seven, + bar: Bar, + baz: isize, + #[ignore] + nan: NaN, +} + +#[derive(TotalSum)] +struct Bar { + quux: isize, + bleh: isize, + #[ignore] + nan: NaN2 +} + +struct NaN; + +impl TotalSum for NaN { + fn total_sum(&self) -> isize { + panic!(); + } +} + +struct NaN2; + +pub fn main() { + let v = Foo { + seven: Seven, + bar: Bar { + quux: 9, + bleh: 3, + nan: NaN2 + }, + baz: 80, + nan: NaN + }; + assert_eq!(v.total_sum(), 99); +} |
