about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-04-08 14:12:55 -0700
committerbors <bors@rust-lang.org>2013-04-08 14:12:55 -0700
commit1968130885985dcf10ca19157d2e90c11566ae5c (patch)
treefdee8f045bd4e6c92e0c529345aa1d7e79715056
parent5a0f62850107edab30e51c1e31c8b0c7e443f972 (diff)
parent68d17bca4b12f514331322f938b56331f987ad68 (diff)
downloadrust-1968130885985dcf10ca19157d2e90c11566ae5c.tar.gz
rust-1968130885985dcf10ca19157d2e90c11566ae5c.zip
auto merge of #5763 : thestinger/rust/clone, r=nikomatsakis
Performing a deep copy isn't ever desired for a persistent data
structure, and it requires a more complex implementation to do
correctly. A deep copy needs to check for cycles to avoid an infinite
loop.
-rw-r--r--src/libcore/clone.rs30
-rw-r--r--src/test/run-pass/borrowck-borrow-from-expr-block.rs2
2 files changed, 20 insertions, 12 deletions
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index c4b5bb8d98b..9da970918b0 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -14,7 +14,7 @@ In Rust, some simple types are "implicitly copyable" and when you
 assign them or pass them as arguments, the receiver will get a copy,
 leaving the original value in place. These types do not require
 allocation to copy and do not have finalizers (i.e. they do not
-contain owned pointers or implement `Drop`), so the compiler considers
+contain owned boxes or implement `Drop`), so the compiler considers
 them cheap and safe to copy and automatically implements the `Copy`
 trait for them. For other types copies must be made explicitly,
 by convention implementing the `Clone` trait and calling the
@@ -23,32 +23,38 @@ by convention implementing the `Clone` trait and calling the
 */
 
 pub trait Clone {
+    /// Return a deep copy of the owned object tree. Managed boxes are cloned with a shallow copy.
     fn clone(&self) -> Self;
 }
 
 impl Clone for () {
+    /// Return a copy of the value.
     #[inline(always)]
     fn clone(&self) -> () { () }
 }
 
 impl<T:Clone> Clone for ~T {
+    /// Return a deep copy of the owned box.
     #[inline(always)]
     fn clone(&self) -> ~T { ~(**self).clone() }
 }
 
-impl<T:Clone> Clone for @T {
+impl<T> Clone for @T {
+    /// Return a shallow copy of the managed box.
     #[inline(always)]
-    fn clone(&self) -> @T { @(**self).clone() }
+    fn clone(&self) -> @T { *self }
 }
 
-impl<T:Clone> Clone for @mut T {
+impl<T> Clone for @mut T {
+    /// Return a shallow copy of the managed box.
     #[inline(always)]
-    fn clone(&self) -> @mut T { @mut (**self).clone() }
+    fn clone(&self) -> @mut T { *self }
 }
 
 macro_rules! clone_impl(
     ($t:ty) => {
         impl Clone for $t {
+            /// Return a copy of the value.
             #[inline(always)]
             fn clone(&self) -> $t { *self }
         }
@@ -76,21 +82,23 @@ clone_impl!(char)
 
 #[test]
 fn test_owned_clone() {
-    let a : ~int = ~5i;
-    let b : ~int = a.clone();
+    let a: ~int = ~5i;
+    let b: ~int = a.clone();
     assert!(a == b);
 }
 
 #[test]
 fn test_managed_clone() {
-    let a : @int = @5i;
-    let b : @int = a.clone();
+    let a: @int = @5i;
+    let b: @int = a.clone();
     assert!(a == b);
 }
 
 #[test]
 fn test_managed_mut_clone() {
-    let a : @int = @5i;
-    let b : @int = a.clone();
+    let a: @mut int = @mut 5i;
+    let b: @mut int = a.clone();
+    assert!(a == b);
+    *b = 10;
     assert!(a == b);
 }
diff --git a/src/test/run-pass/borrowck-borrow-from-expr-block.rs b/src/test/run-pass/borrowck-borrow-from-expr-block.rs
index 077de5c7eb1..afa312ea35e 100644
--- a/src/test/run-pass/borrowck-borrow-from-expr-block.rs
+++ b/src/test/run-pass/borrowck-borrow-from-expr-block.rs
@@ -13,7 +13,7 @@ fn borrow(x: &int, f: &fn(x: &int)) {
 }
 
 fn test1(x: @~int) {
-    do borrow(&**x.clone()) |p| {
+    do borrow(&*(*x).clone()) |p| {
         let x_a = ptr::addr_of(&(**x));
         assert!((x_a as uint) != ptr::to_uint(p));
         assert!(unsafe{*x_a} == *p);