Skip to content

Commit 53196bb

Browse files
committed
auto merge of #6530 : huonw/rust/deriving-deepclone, r=bstrie
2 parents f198832 + 47c9157 commit 53196bb

9 files changed

+95
-19
lines changed

doc/rust.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1562,7 +1562,7 @@ Supported traits for `deriving` are:
15621562

15631563
* Comparison traits: `Eq`, `TotalEq`, `Ord`, `TotalOrd`.
15641564
* Serialization: `Encodable`, `Decodable`. These require `std`.
1565-
* `Clone`, to perform deep copies.
1565+
* `Clone` and `DeepClone`, to perform (deep) copies.
15661566
* `IterBytes`, to iterate over the bytes in a data type.
15671567
* `Rand`, to create a random instance of a data type.
15681568
* `ToStr`, to convert to a string. For a type with this instance,

doc/tutorial.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2308,8 +2308,8 @@ enum ABC { A, B, C }
23082308
~~~
23092309

23102310
The full list of derivable traits is `Eq`, `TotalEq`, `Ord`,
2311-
`TotalOrd`, `Encodable` `Decodable`, `Clone`, `IterBytes`, `Rand` and
2312-
`ToStr`.
2311+
`TotalOrd`, `Encodable` `Decodable`, `Clone`, `DeepClone`,
2312+
`IterBytes`, `Rand` and `ToStr`.
23132313

23142314
# Modules and crates
23152315

src/libsyntax/ext/deriving/clone.rs

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub fn expand_deriving_clone(cx: @ext_ctxt,
3232
args: ~[],
3333
ret_ty: Self,
3434
const_nonmatching: false,
35-
combine_substructure: cs_clone
35+
combine_substructure: |c, s, sub| cs_clone("Clone", c, s, sub)
3636
}
3737
]
3838
};
@@ -42,8 +42,39 @@ pub fn expand_deriving_clone(cx: @ext_ctxt,
4242
&trait_def)
4343
}
4444

45-
fn cs_clone(cx: @ext_ctxt, span: span,
46-
substr: &Substructure) -> @expr {
45+
pub fn expand_deriving_deep_clone(cx: @ext_ctxt,
46+
span: span,
47+
mitem: @meta_item,
48+
in_items: ~[@item])
49+
-> ~[@item] {
50+
let trait_def = TraitDef {
51+
path: Path::new(~[~"core", ~"clone", ~"DeepClone"]),
52+
additional_bounds: ~[],
53+
generics: LifetimeBounds::empty(),
54+
methods: ~[
55+
MethodDef {
56+
name: ~"deep_clone",
57+
generics: LifetimeBounds::empty(),
58+
explicit_self: borrowed_explicit_self(),
59+
args: ~[],
60+
ret_ty: Self,
61+
const_nonmatching: false,
62+
// cs_clone uses the ident passed to it, i.e. it will
63+
// call deep_clone (not clone) here.
64+
combine_substructure: |c, s, sub| cs_clone("DeepClone", c, s, sub)
65+
}
66+
]
67+
};
68+
69+
expand_deriving_generic(cx, span,
70+
mitem, in_items,
71+
&trait_def)
72+
}
73+
74+
fn cs_clone(
75+
name: &str,
76+
cx: @ext_ctxt, span: span,
77+
substr: &Substructure) -> @expr {
4778
let clone_ident = substr.method_ident;
4879
let ctor_ident;
4980
let all_fields;
@@ -59,8 +90,12 @@ fn cs_clone(cx: @ext_ctxt, span: span,
5990
ctor_ident = ~[ variant.node.name ];
6091
all_fields = af;
6192
},
62-
EnumNonMatching(*) => cx.span_bug(span, "Non-matching enum variants in `deriving(Clone)`"),
63-
StaticEnum(*) | StaticStruct(*) => cx.span_bug(span, "Static method in `deriving(Clone)`")
93+
EnumNonMatching(*) => cx.span_bug(span,
94+
fmt!("Non-matching enum variants in `deriving(%s)`",
95+
name)),
96+
StaticEnum(*) | StaticStruct(*) => cx.span_bug(span,
97+
fmt!("Static method in `deriving(%s)`",
98+
name))
6499
}
65100

66101
match *all_fields {
@@ -75,8 +110,8 @@ fn cs_clone(cx: @ext_ctxt, span: span,
75110
let ident = match o_id {
76111
Some(i) => i,
77112
None => cx.span_bug(span,
78-
~"unnamed field in normal struct \
79-
in `deriving(Clone)`")
113+
fmt!("unnamed field in normal struct in `deriving(%s)`",
114+
name))
80115
};
81116
build::Field { ident: ident, ex: subcall(self_f) }
82117
};

src/libsyntax/ext/deriving/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ pub fn expand_meta_deriving(cx: @ext_ctxt,
8484
titem, in_items)));
8585
match *tname {
8686
~"Clone" => expand!(clone::expand_deriving_clone),
87+
~"DeepClone" => expand!(clone::expand_deriving_deep_clone),
8788

8889
~"IterBytes" => expand!(iter_bytes::expand_deriving_iter_bytes),
8990

src/test/run-pass/deriving-clone-enum.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#[deriving(Clone)]
11+
#[deriving(Clone, DeepClone)]
1212
enum E {
1313
A,
1414
B(()),
1515
C
1616
}
1717

18-
pub fn main() {}
18+
pub fn main() {
19+
let _ = A.clone();
20+
let _ = B(()).deep_clone();
21+
}
Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
1-
#[deriving(Clone)]
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(Clone, DeepClone)]
212
enum E<T,U> {
313
A(T),
414
B(T,U),
515
C
616
}
717

8-
fn main() {}
18+
fn main() {
19+
let _ = A::<int, int>(1i).clone();
20+
let _ = B(1i, 1.234).deep_clone();
21+
}

src/test/run-pass/deriving-clone-generic-struct.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#[deriving(Clone)]
11+
#[deriving(Clone, DeepClone)]
1212
struct S<T> {
1313
foo: (),
1414
bar: (),
1515
baz: T,
1616
}
1717

18-
pub fn main() {}
18+
pub fn main() {
19+
let _ = S { foo: (), bar: (), baz: 1i }.clone().deep_clone();
20+
}
Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,16 @@
1-
#[deriving(Clone)]
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(Clone, DeepClone)]
212
struct S<T>(T, ());
313

4-
fn main() {}
14+
fn main() {
15+
let _ = S(1i, ()).clone().deep_clone();
16+
}

src/test/run-pass/deriving-clone-struct.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,14 @@
1-
#[deriving(Clone)]
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(Clone, DeepClone)]
212
struct S {
313
_int: int,
414
_i8: i8,

0 commit comments

Comments
 (0)