syntax: implement #[deriving(DeepClone)]. Fixes #6514.
This commit is contained in:
parent
2329651770
commit
cd2eb4701f
9 changed files with 94 additions and 18 deletions
|
@ -1562,7 +1562,7 @@ Supported traits for `deriving` are:
|
||||||
|
|
||||||
* Comparison traits: `Eq`, `TotalEq`, `Ord`, `TotalOrd`.
|
* Comparison traits: `Eq`, `TotalEq`, `Ord`, `TotalOrd`.
|
||||||
* Serialization: `Encodable`, `Decodable`. These require `std`.
|
* 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.
|
* `IterBytes`, to iterate over the bytes in a data type.
|
||||||
* `Rand`, to create a random instance of 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,
|
* `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`,
|
The full list of derivable traits is `Eq`, `TotalEq`, `Ord`,
|
||||||
`TotalOrd`, `Encodable` `Decodable`, `Clone`, `IterBytes`, `Rand` and
|
`TotalOrd`, `Encodable` `Decodable`, `Clone`, `DeepClone`,
|
||||||
`ToStr`.
|
`IterBytes`, `Rand` and `ToStr`.
|
||||||
|
|
||||||
# Modules and crates
|
# Modules and crates
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ pub fn expand_deriving_clone(cx: @ext_ctxt,
|
||||||
args: ~[],
|
args: ~[],
|
||||||
ret_ty: Self,
|
ret_ty: Self,
|
||||||
const_nonmatching: false,
|
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)
|
&trait_def)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cs_clone(cx: @ext_ctxt, span: span,
|
pub fn expand_deriving_deep_clone(cx: @ext_ctxt,
|
||||||
substr: &Substructure) -> @expr {
|
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 clone_ident = substr.method_ident;
|
||||||
let ctor_ident;
|
let ctor_ident;
|
||||||
let all_fields;
|
let all_fields;
|
||||||
|
@ -59,8 +90,12 @@ fn cs_clone(cx: @ext_ctxt, span: span,
|
||||||
ctor_ident = ~[ variant.node.name ];
|
ctor_ident = ~[ variant.node.name ];
|
||||||
all_fields = af;
|
all_fields = af;
|
||||||
},
|
},
|
||||||
EnumNonMatching(*) => cx.span_bug(span, "Non-matching enum variants in `deriving(Clone)`"),
|
EnumNonMatching(*) => cx.span_bug(span,
|
||||||
StaticEnum(*) | StaticStruct(*) => cx.span_bug(span, "Static method in `deriving(Clone)`")
|
~"Non-matching enum variants in `deriving(" +
|
||||||
|
name + ")`"),
|
||||||
|
StaticEnum(*) | StaticStruct(*) => cx.span_bug(span,
|
||||||
|
~"Static method in `deriving(" +
|
||||||
|
name + ")`")
|
||||||
}
|
}
|
||||||
|
|
||||||
match *all_fields {
|
match *all_fields {
|
||||||
|
@ -76,7 +111,7 @@ fn cs_clone(cx: @ext_ctxt, span: span,
|
||||||
Some(i) => i,
|
Some(i) => i,
|
||||||
None => cx.span_bug(span,
|
None => cx.span_bug(span,
|
||||||
~"unnamed field in normal struct \
|
~"unnamed field in normal struct \
|
||||||
in `deriving(Clone)`")
|
in `deriving(" + name + ")`")
|
||||||
};
|
};
|
||||||
build::Field { ident: ident, ex: subcall(self_f) }
|
build::Field { ident: ident, ex: subcall(self_f) }
|
||||||
};
|
};
|
||||||
|
|
|
@ -84,6 +84,7 @@ pub fn expand_meta_deriving(cx: @ext_ctxt,
|
||||||
titem, in_items)));
|
titem, in_items)));
|
||||||
match *tname {
|
match *tname {
|
||||||
~"Clone" => expand!(clone::expand_deriving_clone),
|
~"Clone" => expand!(clone::expand_deriving_clone),
|
||||||
|
~"DeepClone" => expand!(clone::expand_deriving_deep_clone),
|
||||||
|
|
||||||
~"IterBytes" => expand!(iter_bytes::expand_deriving_iter_bytes),
|
~"IterBytes" => expand!(iter_bytes::expand_deriving_iter_bytes),
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,14 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone, DeepClone)]
|
||||||
enum E {
|
enum E {
|
||||||
A,
|
A,
|
||||||
B(()),
|
B(()),
|
||||||
C
|
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> {
|
enum E<T,U> {
|
||||||
A(T),
|
A(T),
|
||||||
B(T,U),
|
B(T,U),
|
||||||
C
|
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
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone, DeepClone)]
|
||||||
struct S<T> {
|
struct S<T> {
|
||||||
foo: (),
|
foo: (),
|
||||||
bar: (),
|
bar: (),
|
||||||
baz: T,
|
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, ());
|
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 {
|
struct S {
|
||||||
_int: int,
|
_int: int,
|
||||||
_i8: i8,
|
_i8: i8,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue