syntax: implement #[deriving(DeepClone)]. Fixes #6514.
This commit is contained in:
parent
2329651770
commit
cd2eb4701f
@ -1562,7 +1562,7 @@ Supported traits for `deriving` are:
|
||||
|
||||
* Comparison traits: `Eq`, `TotalEq`, `Ord`, `TotalOrd`.
|
||||
* Serialization: `Encodable`, `Decodable`. These require `std`.
|
||||
* `Clone`, to perform deep copies.
|
||||
* `Clone` and `DeepClone`, to perform (deep) copies.
|
||||
* `IterBytes`, to iterate over the bytes in a data type.
|
||||
* `Rand`, to create a random instance of a data type.
|
||||
* `ToStr`, to convert to a string. For a type with this instance,
|
||||
|
@ -2308,8 +2308,8 @@ enum ABC { A, B, C }
|
||||
~~~
|
||||
|
||||
The full list of derivable traits is `Eq`, `TotalEq`, `Ord`,
|
||||
`TotalOrd`, `Encodable` `Decodable`, `Clone`, `IterBytes`, `Rand` and
|
||||
`ToStr`.
|
||||
`TotalOrd`, `Encodable` `Decodable`, `Clone`, `DeepClone`,
|
||||
`IterBytes`, `Rand` and `ToStr`.
|
||||
|
||||
# Modules and crates
|
||||
|
||||
|
@ -32,7 +32,7 @@ pub fn expand_deriving_clone(cx: @ext_ctxt,
|
||||
args: ~[],
|
||||
ret_ty: Self,
|
||||
const_nonmatching: false,
|
||||
combine_substructure: cs_clone
|
||||
combine_substructure: |c, s, sub| cs_clone("Clone", c, s, sub)
|
||||
}
|
||||
]
|
||||
};
|
||||
@ -42,8 +42,39 @@ pub fn expand_deriving_clone(cx: @ext_ctxt,
|
||||
&trait_def)
|
||||
}
|
||||
|
||||
fn cs_clone(cx: @ext_ctxt, span: span,
|
||||
substr: &Substructure) -> @expr {
|
||||
pub fn expand_deriving_deep_clone(cx: @ext_ctxt,
|
||||
span: span,
|
||||
mitem: @meta_item,
|
||||
in_items: ~[@item])
|
||||
-> ~[@item] {
|
||||
let trait_def = TraitDef {
|
||||
path: Path::new(~[~"core", ~"clone", ~"DeepClone"]),
|
||||
additional_bounds: ~[],
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: ~[
|
||||
MethodDef {
|
||||
name: ~"deep_clone",
|
||||
generics: LifetimeBounds::empty(),
|
||||
explicit_self: borrowed_explicit_self(),
|
||||
args: ~[],
|
||||
ret_ty: Self,
|
||||
const_nonmatching: false,
|
||||
// cs_clone uses the ident passed to it, i.e. it will
|
||||
// call deep_clone (not clone) here.
|
||||
combine_substructure: |c, s, sub| cs_clone("DeepClone", c, s, sub)
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
expand_deriving_generic(cx, span,
|
||||
mitem, in_items,
|
||||
&trait_def)
|
||||
}
|
||||
|
||||
fn cs_clone(
|
||||
name: &str,
|
||||
cx: @ext_ctxt, span: span,
|
||||
substr: &Substructure) -> @expr {
|
||||
let clone_ident = substr.method_ident;
|
||||
let ctor_ident;
|
||||
let all_fields;
|
||||
@ -59,8 +90,12 @@ fn cs_clone(cx: @ext_ctxt, span: span,
|
||||
ctor_ident = ~[ variant.node.name ];
|
||||
all_fields = af;
|
||||
},
|
||||
EnumNonMatching(*) => cx.span_bug(span, "Non-matching enum variants in `deriving(Clone)`"),
|
||||
StaticEnum(*) | StaticStruct(*) => cx.span_bug(span, "Static method in `deriving(Clone)`")
|
||||
EnumNonMatching(*) => cx.span_bug(span,
|
||||
~"Non-matching enum variants in `deriving(" +
|
||||
name + ")`"),
|
||||
StaticEnum(*) | StaticStruct(*) => cx.span_bug(span,
|
||||
~"Static method in `deriving(" +
|
||||
name + ")`")
|
||||
}
|
||||
|
||||
match *all_fields {
|
||||
@ -76,7 +111,7 @@ fn cs_clone(cx: @ext_ctxt, span: span,
|
||||
Some(i) => i,
|
||||
None => cx.span_bug(span,
|
||||
~"unnamed field in normal struct \
|
||||
in `deriving(Clone)`")
|
||||
in `deriving(" + name + ")`")
|
||||
};
|
||||
build::Field { ident: ident, ex: subcall(self_f) }
|
||||
};
|
||||
|
@ -84,6 +84,7 @@ macro_rules! expand(($func:path) => ($func(cx, titem.span,
|
||||
titem, in_items)));
|
||||
match *tname {
|
||||
~"Clone" => expand!(clone::expand_deriving_clone),
|
||||
~"DeepClone" => expand!(clone::expand_deriving_deep_clone),
|
||||
|
||||
~"IterBytes" => expand!(iter_bytes::expand_deriving_iter_bytes),
|
||||
|
||||
|
@ -8,11 +8,14 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[deriving(Clone, DeepClone)]
|
||||
enum E {
|
||||
A,
|
||||
B(()),
|
||||
C
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
pub fn main() {
|
||||
let _ = A.clone();
|
||||
let _ = B(()).deep_clone();
|
||||
}
|
||||
|
@ -1,8 +1,21 @@
|
||||
#[deriving(Clone)]
|
||||
// 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(Clone, DeepClone)]
|
||||
enum E<T,U> {
|
||||
A(T),
|
||||
B(T,U),
|
||||
C
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
fn main() {
|
||||
let _ = A::<int, int>(1i).clone();
|
||||
let _ = B(1i, 1.234).deep_clone();
|
||||
}
|
||||
|
@ -8,11 +8,13 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[deriving(Clone)]
|
||||
#[deriving(Clone, DeepClone)]
|
||||
struct S<T> {
|
||||
foo: (),
|
||||
bar: (),
|
||||
baz: T,
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
pub fn main() {
|
||||
let _ = S { foo: (), bar: (), baz: 1i }.clone().deep_clone();
|
||||
}
|
||||
|
@ -1,4 +1,16 @@
|
||||
#[deriving(Clone)]
|
||||
// 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(Clone, DeepClone)]
|
||||
struct S<T>(T, ());
|
||||
|
||||
fn main() {}
|
||||
fn main() {
|
||||
let _ = S(1i, ()).clone().deep_clone();
|
||||
}
|
||||
|
@ -1,4 +1,14 @@
|
||||
#[deriving(Clone)]
|
||||
// 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(Clone, DeepClone)]
|
||||
struct S {
|
||||
_int: int,
|
||||
_i8: i8,
|
||||
|
Loading…
Reference in New Issue
Block a user