]> git.lizzy.rs Git - rust.git/commitdiff
syntax: implement #[deriving] meta-attribute
authorAndrew Paseltiner <apaseltiner@gmail.com>
Mon, 11 Mar 2013 20:47:23 +0000 (16:47 -0400)
committerAndrew Paseltiner <apaseltiner@gmail.com>
Tue, 12 Mar 2013 16:52:39 +0000 (12:52 -0400)
src/libsyntax/ext/base.rs
src/libsyntax/ext/deriving.rs
src/test/compile-fail/deriving-meta-unknown-trait.rs [new file with mode: 0644]
src/test/run-pass/deriving-meta-empty-trait-list.rs [new file with mode: 0644]
src/test/run-pass/deriving-meta-multiple.rs [new file with mode: 0644]
src/test/run-pass/deriving-meta.rs [new file with mode: 0644]

index 23cabc099462f78f8f99d7b3808611fe822892f0..1edaebefedbc8888221cba689f04ad6852dc7ad8 100644 (file)
@@ -148,6 +148,9 @@ fn builtin_item_tt(f: SyntaxExpanderTTItemFun) -> @Transformer {
     syntax_expanders.insert(@~"log_syntax",
                             builtin_normal_tt(
                                 ext::log_syntax::expand_syntax_ext));
+    syntax_expanders.insert(@~"deriving",
+                            @SE(ItemDecorator(
+                                ext::deriving::expand_meta_deriving)));
     syntax_expanders.insert(@~"deriving_eq",
                             @SE(ItemDecorator(
                                 ext::deriving::expand_deriving_eq)));
index efea962a0892d67189b630e7bfb00909dc251392..093327ec32e0980a422002c85745f10f09315a29 100644 (file)
@@ -56,6 +56,48 @@ fn to_binop(self) -> binop {
                                         ident,
                                         y: &Generics) -> @item;
 
+pub fn expand_meta_deriving(cx: ext_ctxt,
+                            _span: span,
+                            mitem: @meta_item,
+                            in_items: ~[@item])
+                         -> ~[@item] {
+    use ast::{meta_list, meta_name_value, meta_word};
+
+    match mitem.node {
+        meta_name_value(_, l) => {
+            cx.span_err(l.span, ~"unexpected value in `deriving`");
+            in_items
+        }
+        meta_word(_) | meta_list(_, []) => {
+            cx.span_warn(mitem.span, ~"empty trait list in `deriving`");
+            in_items
+        }
+        meta_list(_, titems) => {
+            do titems.foldr(in_items) |&titem, in_items| {
+                match titem.node {
+                    meta_name_value(tname, _) |
+                    meta_list(tname, _) |
+                    meta_word(tname) => {
+                        match *tname {
+                            ~"Clone" => expand_deriving_clone(cx,
+                                titem.span, titem, in_items),
+                            ~"Eq" => expand_deriving_eq(cx, titem.span,
+                                titem, in_items),
+                            ~"IterBytes" => expand_deriving_iter_bytes(cx,
+                                titem.span, titem, in_items),
+                            tname => {
+                                cx.span_err(titem.span, fmt!("unknown \
+                                    `deriving` trait: `%s`", tname));
+                                in_items
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
 pub fn expand_deriving_eq(cx: ext_ctxt,
                           span: span,
                           _mitem: @meta_item,
diff --git a/src/test/compile-fail/deriving-meta-unknown-trait.rs b/src/test/compile-fail/deriving-meta-unknown-trait.rs
new file mode 100644 (file)
index 0000000..0b9f61d
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2013 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.
+
+#[deriving(Eqr)] //~ ERROR unknown `deriving` trait: `Eqr`
+struct Foo;
+
+pub fn main() {}
diff --git a/src/test/run-pass/deriving-meta-empty-trait-list.rs b/src/test/run-pass/deriving-meta-empty-trait-list.rs
new file mode 100644 (file)
index 0000000..8e7afff
--- /dev/null
@@ -0,0 +1,19 @@
+// xfail-pretty
+
+// Copyright 2013 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.
+
+#[deriving]   //~ WARNING empty trait list in `deriving`
+struct Foo;
+
+#[deriving()] //~ WARNING empty trait list in `deriving`
+struct Bar;
+
+pub fn main() {}
diff --git a/src/test/run-pass/deriving-meta-multiple.rs b/src/test/run-pass/deriving-meta-multiple.rs
new file mode 100644 (file)
index 0000000..d94b6fc
--- /dev/null
@@ -0,0 +1,29 @@
+// xfail-fast
+
+// Copyright 2013 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.
+
+#[deriving(Eq)]
+#[deriving(Clone)]
+#[deriving(IterBytes)]
+struct Foo {
+    bar: uint,
+    baz: int
+}
+
+pub fn main() {
+    use core::hash::{Hash, HashUtil}; // necessary for IterBytes check
+
+    let a = Foo {bar: 4, baz: -3};
+
+    a == a;    // check for Eq impl w/o testing its correctness
+    a.clone(); // check for Clone impl w/o testing its correctness
+    a.hash();  // check for IterBytes impl w/o testing its correctness
+}
diff --git a/src/test/run-pass/deriving-meta.rs b/src/test/run-pass/deriving-meta.rs
new file mode 100644 (file)
index 0000000..efb2020
--- /dev/null
@@ -0,0 +1,27 @@
+// xfail-fast
+
+// Copyright 2013 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.
+
+#[deriving(Eq, Clone, IterBytes)]
+struct Foo {
+    bar: uint,
+    baz: int
+}
+
+pub fn main() {
+    use core::hash::{Hash, HashUtil}; // necessary for IterBytes check
+
+    let a = Foo {bar: 4, baz: -3};
+
+    a == a;    // check for Eq impl w/o testing its correctness
+    a.clone(); // check for Clone impl w/o testing its correctness
+    a.hash();  // check for IterBytes impl w/o testing its correctness
+}