Skip to content

Commit d34016d

Browse files
committed
auto merge of #8109 : blake2-ppc/rust/extern-fn-clone, r=thestinger
Implement Clone and DeepClone for functions with 0 to 8 arguments. `extern fn()` is implicitly copyable so it's simple, except there is no way to implement it generically over #n function arguments. Allows deriving of Clone on structs containing `extern "Rust" fn`.
2 parents 2830d7d + 11aad20 commit d34016d

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

src/libstd/clone.rs

+58
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,26 @@ clone_impl!(())
9797
clone_impl!(bool)
9898
clone_impl!(char)
9999

100+
macro_rules! extern_fn_clone(
101+
($($A:ident),*) => (
102+
impl<$($A,)* ReturnType> Clone for extern "Rust" fn($($A),*) -> ReturnType {
103+
/// Return a copy of a function pointer
104+
#[inline]
105+
fn clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self }
106+
}
107+
)
108+
)
109+
110+
extern_fn_clone!()
111+
extern_fn_clone!(A)
112+
extern_fn_clone!(A, B)
113+
extern_fn_clone!(A, B, C)
114+
extern_fn_clone!(A, B, C, D)
115+
extern_fn_clone!(A, B, C, D, E)
116+
extern_fn_clone!(A, B, C, D, E, F)
117+
extern_fn_clone!(A, B, C, D, E, F, G)
118+
extern_fn_clone!(A, B, C, D, E, F, G, H)
119+
100120
/// A trait distinct from `Clone` which represents "deep copies" of things like
101121
/// managed boxes which would otherwise not be copied.
102122
pub trait DeepClone {
@@ -157,6 +177,26 @@ deep_clone_impl!(())
157177
deep_clone_impl!(bool)
158178
deep_clone_impl!(char)
159179

180+
macro_rules! extern_fn_deep_clone(
181+
($($A:ident),*) => (
182+
impl<$($A,)* ReturnType> DeepClone for extern "Rust" fn($($A),*) -> ReturnType {
183+
/// Return a copy of a function pointer
184+
#[inline]
185+
fn deep_clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self }
186+
}
187+
)
188+
)
189+
190+
extern_fn_deep_clone!()
191+
extern_fn_deep_clone!(A)
192+
extern_fn_deep_clone!(A, B)
193+
extern_fn_deep_clone!(A, B, C)
194+
extern_fn_deep_clone!(A, B, C, D)
195+
extern_fn_deep_clone!(A, B, C, D, E)
196+
extern_fn_deep_clone!(A, B, C, D, E, F)
197+
extern_fn_deep_clone!(A, B, C, D, E, F, G)
198+
extern_fn_deep_clone!(A, B, C, D, E, F, G, H)
199+
160200
#[test]
161201
fn test_owned_clone() {
162202
let a = ~5i;
@@ -195,3 +235,21 @@ fn test_borrowed_clone() {
195235
let z: &int = (&y).clone();
196236
assert_eq!(*z, 5);
197237
}
238+
239+
#[test]
240+
fn test_extern_fn_clone() {
241+
trait Empty {}
242+
impl Empty for int {}
243+
244+
fn test_fn_a() -> float { 1.0 }
245+
fn test_fn_b<T: Empty>(x: T) -> T { x }
246+
fn test_fn_c(_: int, _: float, _: ~[int], _: int, _: int, _: int) {}
247+
248+
let _ = test_fn_a.clone();
249+
let _ = test_fn_b::<int>.clone();
250+
let _ = test_fn_c.clone();
251+
252+
let _ = test_fn_a.deep_clone();
253+
let _ = test_fn_b::<int>.deep_clone();
254+
let _ = test_fn_c.deep_clone();
255+
}

0 commit comments

Comments
 (0)