Skip to content

Commit a9643d3

Browse files
committed
auto merge of #5320 : apasel422/rust/metaderive, r=graydon
This is the first in a series of patches I'm working on to clean up the code related to `deriving`. This patch allows ``` #[deriving_eq] #[deriving_iter_bytes] #[deriving_clone] struct Foo { bar: uint } ``` to be replaced with: ``` #[deriving(Eq, IterBytes, Clone)] struct Foo { bar: uint } ``` It leaves the old attributes alone for the time being. Eventually I'd like to incorporate the new closest-match-suggestion infrastructure for mistyped trait names, and also pass the sub-attributes to the deriving code, so that the following will be possible: ``` #[deriving(TotalOrd(qux, bar))] struct Foo { bar: uint, baz: char, qux: int } ``` This says to derive an `impl` in which the objects' `qux` fields are compared first, followed by `bar`, while `baz` is ignored in the comparison. If no fields are specified explicitly, all fields will be compared in the order they're defined in the `struct`. This might also be useful for `Eq`. Coming soon.
2 parents 15d78fc + 24efea7 commit a9643d3

File tree

6 files changed

+134
-0
lines changed

6 files changed

+134
-0
lines changed

src/libsyntax/ext/base.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ pub fn syntax_expander_table() -> SyntaxEnv {
148148
syntax_expanders.insert(@~"log_syntax",
149149
builtin_normal_tt(
150150
ext::log_syntax::expand_syntax_ext));
151+
syntax_expanders.insert(@~"deriving",
152+
@SE(ItemDecorator(
153+
ext::deriving::expand_meta_deriving)));
151154
syntax_expanders.insert(@~"deriving_eq",
152155
@SE(ItemDecorator(
153156
ext::deriving::expand_deriving_eq)));

src/libsyntax/ext/deriving.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,48 @@ type ExpandDerivingEnumDefFn = &self/fn(ext_ctxt,
5656
ident,
5757
y: &Generics) -> @item;
5858

59+
pub fn expand_meta_deriving(cx: ext_ctxt,
60+
_span: span,
61+
mitem: @meta_item,
62+
in_items: ~[@item])
63+
-> ~[@item] {
64+
use ast::{meta_list, meta_name_value, meta_word};
65+
66+
match mitem.node {
67+
meta_name_value(_, l) => {
68+
cx.span_err(l.span, ~"unexpected value in `deriving`");
69+
in_items
70+
}
71+
meta_word(_) | meta_list(_, []) => {
72+
cx.span_warn(mitem.span, ~"empty trait list in `deriving`");
73+
in_items
74+
}
75+
meta_list(_, titems) => {
76+
do titems.foldr(in_items) |&titem, in_items| {
77+
match titem.node {
78+
meta_name_value(tname, _) |
79+
meta_list(tname, _) |
80+
meta_word(tname) => {
81+
match *tname {
82+
~"Clone" => expand_deriving_clone(cx,
83+
titem.span, titem, in_items),
84+
~"Eq" => expand_deriving_eq(cx, titem.span,
85+
titem, in_items),
86+
~"IterBytes" => expand_deriving_iter_bytes(cx,
87+
titem.span, titem, in_items),
88+
tname => {
89+
cx.span_err(titem.span, fmt!("unknown \
90+
`deriving` trait: `%s`", tname));
91+
in_items
92+
}
93+
}
94+
}
95+
}
96+
}
97+
}
98+
}
99+
}
100+
59101
pub fn expand_deriving_eq(cx: ext_ctxt,
60102
span: span,
61103
_mitem: @meta_item,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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+
#[deriving(Eqr)] //~ ERROR unknown `deriving` trait: `Eqr`
12+
struct Foo;
13+
14+
pub fn main() {}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// xfail-pretty
2+
3+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
4+
// file at the top-level directory of this distribution and at
5+
// http://rust-lang.org/COPYRIGHT.
6+
//
7+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
8+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
9+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
10+
// option. This file may not be copied, modified, or distributed
11+
// except according to those terms.
12+
13+
#[deriving] //~ WARNING empty trait list in `deriving`
14+
struct Foo;
15+
16+
#[deriving()] //~ WARNING empty trait list in `deriving`
17+
struct Bar;
18+
19+
pub fn main() {}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// xfail-fast
2+
3+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
4+
// file at the top-level directory of this distribution and at
5+
// http://rust-lang.org/COPYRIGHT.
6+
//
7+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
8+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
9+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
10+
// option. This file may not be copied, modified, or distributed
11+
// except according to those terms.
12+
13+
#[deriving(Eq)]
14+
#[deriving(Clone)]
15+
#[deriving(IterBytes)]
16+
struct Foo {
17+
bar: uint,
18+
baz: int
19+
}
20+
21+
pub fn main() {
22+
use core::hash::{Hash, HashUtil}; // necessary for IterBytes check
23+
24+
let a = Foo {bar: 4, baz: -3};
25+
26+
a == a; // check for Eq impl w/o testing its correctness
27+
a.clone(); // check for Clone impl w/o testing its correctness
28+
a.hash(); // check for IterBytes impl w/o testing its correctness
29+
}

src/test/run-pass/deriving-meta.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// xfail-fast
2+
3+
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
4+
// file at the top-level directory of this distribution and at
5+
// http://rust-lang.org/COPYRIGHT.
6+
//
7+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
8+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
9+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
10+
// option. This file may not be copied, modified, or distributed
11+
// except according to those terms.
12+
13+
#[deriving(Eq, Clone, IterBytes)]
14+
struct Foo {
15+
bar: uint,
16+
baz: int
17+
}
18+
19+
pub fn main() {
20+
use core::hash::{Hash, HashUtil}; // necessary for IterBytes check
21+
22+
let a = Foo {bar: 4, baz: -3};
23+
24+
a == a; // check for Eq impl w/o testing its correctness
25+
a.clone(); // check for Clone impl w/o testing its correctness
26+
a.hash(); // check for IterBytes impl w/o testing its correctness
27+
}

0 commit comments

Comments
 (0)