about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2013-07-02 12:47:32 -0700
committerPatrick Walton <pcwalton@mimiga.net>2013-07-17 14:57:51 -0700
commit99b33f721954bc5290f9201c8f64003c294d0571 (patch)
tree786c9bf75d54512d0a80f6975ad40516ab432c3a /src/libstd
parentb4e674f6e662bc80f2e7a5a1a9834f2152f08d32 (diff)
downloadrust-99b33f721954bc5290f9201c8f64003c294d0571.tar.gz
rust-99b33f721954bc5290f9201c8f64003c294d0571.zip
librustc: Remove all uses of "copy".
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/at_vec.rs35
-rw-r--r--src/libstd/cast.rs8
-rw-r--r--src/libstd/condition.rs2
-rw-r--r--src/libstd/either.rs10
-rw-r--r--src/libstd/hashmap.rs21
-rw-r--r--src/libstd/io.rs23
-rw-r--r--src/libstd/local_data.rs8
-rw-r--r--src/libstd/num/strconv.rs19
-rw-r--r--src/libstd/option.rs12
-rw-r--r--src/libstd/os.rs21
-rw-r--r--src/libstd/path.rs78
-rw-r--r--src/libstd/ptr.rs11
-rw-r--r--src/libstd/rand.rs33
-rw-r--r--src/libstd/result.rs60
-rw-r--r--src/libstd/rt/join_latch.rs18
-rw-r--r--src/libstd/run.rs3
-rw-r--r--src/libstd/str.rs9
-rw-r--r--src/libstd/tuple.rs24
-rw-r--r--src/libstd/util.rs6
-rw-r--r--src/libstd/vec.rs78
20 files changed, 273 insertions, 206 deletions
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index dfd39af093d..13354e61284 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -11,9 +11,9 @@
 //! Managed vectors
 
 use cast::transmute;
+use clone::Clone;
 use container::Container;
 use iterator::IteratorUtil;
-use kinds::Copy;
 use option::Option;
 use sys;
 use uint;
@@ -90,10 +90,14 @@ pub fn build_sized_opt<A>(size: Option<uint>,
 /// Iterates over the `rhs` vector, copying each element and appending it to the
 /// `lhs`. Afterwards, the `lhs` is then returned for use again.
 #[inline]
-pub fn append<T:Copy>(lhs: @[T], rhs: &[T]) -> @[T] {
+pub fn append<T:Clone>(lhs: @[T], rhs: &[T]) -> @[T] {
     do build_sized(lhs.len() + rhs.len()) |push| {
-        for lhs.iter().advance |x| { push(copy *x); }
-        for uint::range(0, rhs.len()) |i| { push(copy rhs[i]); }
+        for lhs.iter().advance |x| {
+            push((*x).clone());
+        }
+        for uint::range(0, rhs.len()) |i| {
+            push(rhs[i].clone());
+        }
     }
 }
 
@@ -126,10 +130,13 @@ pub fn from_fn<T>(n_elts: uint, op: &fn(uint) -> T) -> @[T] {
  * Creates an immutable vector of size `n_elts` and initializes the elements
  * to the value `t`.
  */
-pub fn from_elem<T:Copy>(n_elts: uint, t: T) -> @[T] {
+pub fn from_elem<T:Clone>(n_elts: uint, t: T) -> @[T] {
     do build_sized(n_elts) |push| {
         let mut i: uint = 0u;
-        while i < n_elts { push(copy t); i += 1u; }
+        while i < n_elts {
+            push(t.clone());
+            i += 1u;
+        }
     }
 }
 
@@ -152,18 +159,24 @@ pub fn to_managed_consume<T>(v: ~[T]) -> @[T] {
  * Creates and initializes an immutable managed vector by copying all the
  * elements of a slice.
  */
-pub fn to_managed<T:Copy>(v: &[T]) -> @[T] {
-    from_fn(v.len(), |i| copy v[i])
+pub fn to_managed<T:Clone>(v: &[T]) -> @[T] {
+    from_fn(v.len(), |i| v[i].clone())
+}
+
+impl<T> Clone for @[T] {
+    fn clone(&self) -> @[T] {
+        *self
+    }
 }
 
 #[cfg(not(test))]
 pub mod traits {
     use at_vec::append;
-    use vec::Vector;
-    use kinds::Copy;
+    use clone::Clone;
     use ops::Add;
+    use vec::Vector;
 
-    impl<'self,T:Copy, V: Vector<T>> Add<V,@[T]> for @[T] {
+    impl<'self,T:Clone, V: Vector<T>> Add<V,@[T]> for @[T] {
         #[inline]
         fn add(&self, rhs: &V) -> @[T] {
             append(*self, rhs.as_slice())
diff --git a/src/libstd/cast.rs b/src/libstd/cast.rs
index 50b5b2fcd29..86eec80ae6f 100644
--- a/src/libstd/cast.rs
+++ b/src/libstd/cast.rs
@@ -36,6 +36,14 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
 }
 
 /**
+ * Forces a copy of a value, even if that value is considered noncopyable.
+ */
+#[inline]
+pub unsafe fn unsafe_copy<T>(thing: &T) -> T {
+    transmute_copy(thing)
+}
+
+/**
  * Move a thing into the void
  *
  * The forget function will take ownership of the provided value but neglect
diff --git a/src/libstd/condition.rs b/src/libstd/condition.rs
index 3a5be12b3c5..80caa34ce06 100644
--- a/src/libstd/condition.rs
+++ b/src/libstd/condition.rs
@@ -86,7 +86,7 @@ impl<'self, T, U> Condition<'self, T, U> {
 
     pub fn raise(&self, t: T) -> U {
         let msg = fmt!("Unhandled condition: %s: %?", self.name, t);
-        self.raise_default(t, || fail!(copy msg))
+        self.raise_default(t, || fail!(msg.clone()))
     }
 
     pub fn raise_default(&self, t: T, default: &fn() -> U) -> U {
diff --git a/src/libstd/either.rs b/src/libstd/either.rs
index 8b9b3102831..fcbd98a79e7 100644
--- a/src/libstd/either.rs
+++ b/src/libstd/either.rs
@@ -12,9 +12,9 @@
 
 #[allow(missing_doc)];
 
+use clone::Clone;
 use container::Container;
 use cmp::Eq;
-use kinds::Copy;
 use iterator::IteratorUtil;
 use result::Result;
 use result;
@@ -43,11 +43,11 @@ pub fn either<T, U, V>(f_left: &fn(&T) -> V,
 }
 
 /// Extracts from a vector of either all the left values
-pub fn lefts<T:Copy,U>(eithers: &[Either<T, U>]) -> ~[T] {
+pub fn lefts<T:Clone,U>(eithers: &[Either<T, U>]) -> ~[T] {
     do vec::build_sized(eithers.len()) |push| {
         for eithers.iter().advance |elt| {
             match *elt {
-                Left(ref l) => { push(copy *l); }
+                Left(ref l) => { push((*l).clone()); }
                 _ => { /* fallthrough */ }
             }
         }
@@ -55,11 +55,11 @@ pub fn lefts<T:Copy,U>(eithers: &[Either<T, U>]) -> ~[T] {
 }
 
 /// Extracts from a vector of either all the right values
-pub fn rights<T, U: Copy>(eithers: &[Either<T, U>]) -> ~[U] {
+pub fn rights<T, U: Clone>(eithers: &[Either<T, U>]) -> ~[U] {
     do vec::build_sized(eithers.len()) |push| {
         for eithers.iter().advance |elt| {
             match *elt {
-                Right(ref r) => { push(copy *r); }
+                Right(ref r) => { push((*r).clone()); }
                 _ => { /* fallthrough */ }
             }
         }
diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs
index 79c6c4fb21d..7cf2c594202 100644
--- a/src/libstd/hashmap.rs
+++ b/src/libstd/hashmap.rs
@@ -25,10 +25,9 @@ use option::{None, Option, Some};
 use rand::RngUtil;
 use rand;
 use uint;
-use vec;
-use vec::{ImmutableVector, MutableVector, OwnedVector};
-use kinds::Copy;
 use util::{replace, unreachable};
+use vec::{ImmutableVector, MutableVector, OwnedVector};
+use vec;
 
 static INITIAL_CAPACITY: uint = 32u; // 2^5
 
@@ -525,15 +524,15 @@ impl<K: Hash + Eq, V> HashMap<K, V> {
     }
 }
 
-impl<K: Hash + Eq, V: Copy> HashMap<K, V> {
+impl<K: Hash + Eq, V: Clone> HashMap<K, V> {
     /// Like `find`, but returns a copy of the value.
     pub fn find_copy(&self, k: &K) -> Option<V> {
-        self.find(k).map_consume(|v| copy *v)
+        self.find(k).map_consume(|v| (*v).clone())
     }
 
     /// Like `get`, but returns a copy of the value.
     pub fn get_copy(&self, k: &K) -> V {
-        copy *self.get(k)
+        (*self.get(k)).clone()
     }
 }
 
@@ -554,6 +553,16 @@ impl<K:Hash + Eq,V:Eq> Eq for HashMap<K, V> {
     fn ne(&self, other: &HashMap<K, V>) -> bool { !self.eq(other) }
 }
 
+impl<K:Hash + Eq + Clone,V:Clone> Clone for HashMap<K,V> {
+    fn clone(&self) -> HashMap<K,V> {
+        let mut new_map = HashMap::with_capacity(self.len());
+        for self.iter().advance |(key, value)| {
+            new_map.insert((*key).clone(), (*value).clone());
+        }
+        new_map
+    }
+}
+
 /// HashMap iterator
 pub struct HashMapIterator<'self, K, V> {
     priv iter: vec::VecIterator<'self, Option<Bucket<K, V>>>,
diff --git a/src/libstd/io.rs b/src/libstd/io.rs
index 347fa988856..e074eba68ae 100644
--- a/src/libstd/io.rs
+++ b/src/libstd/io.rs
@@ -48,6 +48,7 @@ implement `Reader` and `Writer`, where appropriate.
 
 use result::Result;
 
+use clone::Clone;
 use container::Container;
 use int;
 use libc;
@@ -1697,7 +1698,7 @@ pub fn with_bytes_writer(f: &fn(@Writer)) -> ~[u8] {
     let wr = @BytesWriter::new();
     f(wr as @Writer);
     let @BytesWriter { bytes, _ } = wr;
-    copy *bytes
+    (*bytes).clone()
 }
 
 pub fn with_str_writer(f: &fn(@Writer)) -> ~str {
@@ -1750,7 +1751,6 @@ pub fn read_whole_file(file: &Path) -> Result<~[u8], ~str> {
 
 pub mod fsync {
     use io::{FILERes, FdRes, fd_t};
-    use kinds::Copy;
     use libc;
     use ops::Drop;
     use option::{None, Option, Some};
@@ -1775,21 +1775,20 @@ pub mod fsync {
         arg: Arg<t>,
     }
 
-    impl <t: Copy> Res<t> {
+    impl <t> Res<t> {
         pub fn new(arg: Arg<t>) -> Res<t> {
             Res { arg: arg }
         }
     }
 
     #[unsafe_destructor]
-    impl<T:Copy> Drop for Res<T> {
+    impl<T> Drop for Res<T> {
         fn drop(&self) {
             match self.arg.opt_level {
                 None => (),
                 Some(level) => {
                   // fail hard if not succesful
-                  assert!(((self.arg.fsync_fn)(copy self.arg.val, level)
-                    != -1));
+                  assert!(((self.arg.fsync_fn)(&self.arg.val, level) != -1));
                 }
             }
         }
@@ -1798,7 +1797,7 @@ pub mod fsync {
     pub struct Arg<t> {
         val: t,
         opt_level: Option<Level>,
-        fsync_fn: @fn(f: t, Level) -> int,
+        fsync_fn: @fn(f: &t, Level) -> int,
     }
 
     // fsync file after executing blk
@@ -1810,7 +1809,7 @@ pub mod fsync {
             val: file.f, opt_level: opt_level,
             fsync_fn: |file, l| {
                 unsafe {
-                    os::fsync_fd(libc::fileno(file), l) as int
+                    os::fsync_fd(libc::fileno(*file), l) as int
                 }
             }
         }));
@@ -1821,7 +1820,7 @@ pub mod fsync {
                        blk: &fn(v: Res<fd_t>)) {
         blk(Res::new(Arg {
             val: fd.fd, opt_level: opt_level,
-            fsync_fn: |fd, l| os::fsync_fd(fd, l) as int
+            fsync_fn: |fd, l| os::fsync_fd(*fd, l) as int
         }));
     }
 
@@ -1833,7 +1832,7 @@ pub mod fsync {
                     blk: &fn(v: Res<@FSyncable>)) {
         blk(Res::new(Arg {
             val: o, opt_level: opt_level,
-            fsync_fn: |o, l| o.fsync(l)
+            fsync_fn: |o, l| (*o).fsync(l)
         }));
     }
 }
@@ -1854,7 +1853,7 @@ mod tests {
         debug!(tmpfile);
         let frood: ~str =
             ~"A hoopy frood who really knows where his towel is.";
-        debug!(copy frood);
+        debug!(frood.clone());
         {
             let out: @io::Writer =
                 result::get(
@@ -1863,7 +1862,7 @@ mod tests {
         }
         let inp: @io::Reader = result::get(&io::file_reader(tmpfile));
         let frood2: ~str = inp.read_c_str();
-        debug!(copy frood2);
+        debug!(frood2.clone());
         assert_eq!(frood, frood2);
     }
 
diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs
index 6c1640e683e..168bb7c14f0 100644
--- a/src/libstd/local_data.rs
+++ b/src/libstd/local_data.rs
@@ -135,9 +135,11 @@ pub fn modify<T: 'static>(key: Key<@T>, f: &fn(Option<@T>) -> Option<@T>) {
  */
 #[cfg(not(stage0))]
 pub fn modify<T: 'static>(key: Key<T>, f: &fn(Option<T>) -> Option<T>) {
-    match f(pop(key)) {
-        Some(next) => { set(key, next); }
-        None => {}
+    unsafe {
+        match f(pop(::cast::unsafe_copy(&key))) {
+            Some(next) => { set(key, next); }
+            None => {}
+        }
     }
 }
 
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index 337d804ce73..4661bc20403 100644
--- a/src/libstd/num/strconv.rs
+++ b/src/libstd/num/strconv.rs
@@ -10,6 +10,7 @@
 
 #[allow(missing_doc)];
 
+use clone::Clone;
 use container::Container;
 use core::cmp::{Ord, Eq};
 use ops::{Add, Sub, Mul, Div, Rem, Neg};
@@ -467,7 +468,7 @@ priv static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
  */
 pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
                                     Mul<T,T>+Sub<T,T>+Neg<T>+Add<T,T>+
-                                    NumStrConv>(
+                                    NumStrConv+Clone>(
         buf: &[u8], radix: uint, negative: bool, fractional: bool,
         special: bool, exponent: ExponentFormat, empty_zero: bool,
         ignore_underscores: bool
@@ -528,8 +529,8 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
 
     // Initialize accumulator with signed zero for floating point parsing to
     // work
-    let mut accum      = if accum_positive { copy _0 } else { -_1 * _0};
-    let mut last_accum = copy accum; // Necessary to detect overflow
+    let mut accum      = if accum_positive { _0.clone() } else { -_1 * _0};
+    let mut last_accum = accum.clone(); // Necessary to detect overflow
     let mut i          = start;
     let mut exp_found  = false;
 
@@ -540,7 +541,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
         match char::to_digit(c, radix) {
             Some(digit) => {
                 // shift accum one digit left
-                accum = accum * copy radix_gen;
+                accum = accum * radix_gen.clone();
 
                 // add/subtract current digit depending on sign
                 if accum_positive {
@@ -555,7 +556,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
                     if accum_positive && accum <= last_accum { return None; }
                     if !accum_positive && accum >= last_accum { return None; }
                 }
-                last_accum = copy accum;
+                last_accum = accum.clone();
             }
             None => match c {
                 '_' if ignore_underscores => {}
@@ -577,7 +578,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
     // Parse fractional part of number
     // Skip if already reached start of exponent
     if !exp_found {
-        let mut power = copy _1;
+        let mut power = _1.clone();
 
         while i < len {
             let c = buf[i] as char;
@@ -599,7 +600,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
                     // Detect overflow by comparing to last value
                     if accum_positive && accum < last_accum { return None; }
                     if !accum_positive && accum > last_accum { return None; }
-                    last_accum = copy accum;
+                    last_accum = accum.clone();
                 }
                 None => match c {
                     '_' if ignore_underscores => {}
@@ -625,7 +626,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
         }
     }
 
-    let mut multiplier = copy _1;
+    let mut multiplier = _1.clone();
 
     if exp_found {
         let c = buf[i] as char;
@@ -663,7 +664,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+
  */
 #[inline]
 pub fn from_str_common<T:NumCast+Zero+One+Eq+Ord+Copy+Div<T,T>+Mul<T,T>+
-                              Sub<T,T>+Neg<T>+Add<T,T>+NumStrConv>(
+                              Sub<T,T>+Neg<T>+Add<T,T>+NumStrConv+Clone>(
         buf: &str, radix: uint, negative: bool, fractional: bool,
         special: bool, exponent: ExponentFormat, empty_zero: bool,
         ignore_underscores: bool
diff --git a/src/libstd/option.rs b/src/libstd/option.rs
index b0811674a7b..42d892fee9b 100644
--- a/src/libstd/option.rs
+++ b/src/libstd/option.rs
@@ -41,9 +41,9 @@ let unwrapped_msg = match msg {
 
 */
 
+use clone::Clone;
 use cmp::{Eq,Ord};
 use ops::Add;
-use kinds::Copy;
 use util;
 use num::Zero;
 use iterator::Iterator;
@@ -88,13 +88,13 @@ impl<T:Ord> Ord for Option<T> {
     }
 }
 
-impl<T: Copy+Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
+impl<T:Clone+Add<T,T>> Add<Option<T>, Option<T>> for Option<T> {
     #[inline]
     fn add(&self, other: &Option<T>) -> Option<T> {
         match (&*self, &*other) {
             (&None, &None) => None,
-            (_, &None) => copy *self,
-            (&None, _) => copy *other,
+            (_, &None) => (*self).clone(),
+            (&None, _) => (*other).clone(),
             (&Some(ref lhs), &Some(ref rhs)) => Some(*lhs + *rhs)
         }
     }
@@ -313,9 +313,7 @@ impl<T> Option<T> {
           None => fail!(reason.to_owned()),
         }
     }
-}
 
-impl<T:Copy> Option<T> {
     /**
     Gets the value out of an option
 
@@ -354,7 +352,7 @@ impl<T:Copy> Option<T> {
     }
 }
 
-impl<T:Copy + Zero> Option<T> {
+impl<T:Zero> Option<T> {
     /// Returns the contained value or zero (for this type)
     #[inline]
     pub fn get_or_zero(self) -> T {
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 58175db1241..c54cf3910bd 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -29,6 +29,7 @@
 #[allow(missing_doc)];
 
 use cast;
+use clone::Clone;
 use container::Container;
 use io;
 use iterator::IteratorUtil;
@@ -630,7 +631,7 @@ pub fn path_exists(p: &Path) -> bool {
 // the input paths.
 pub fn make_absolute(p: &Path) -> Path {
     if p.is_absolute {
-        copy *p
+        (*p).clone()
     } else {
         getcwd().push_many(p.components)
     }
@@ -1252,7 +1253,7 @@ static overridden_arg_key: local_data::Key<@OverriddenArgs> = &local_data::Key;
 pub fn args() -> ~[~str] {
     match local_data::get(overridden_arg_key, |k| k.map(|&k| *k)) {
         None => real_args(),
-        Some(args) => copy args.val
+        Some(args) => args.val.clone()
     }
 }
 
@@ -1260,7 +1261,9 @@ pub fn args() -> ~[~str] {
 /// program had when it started. These new arguments are only available to the
 /// current task via the `os::args` method.
 pub fn set_args(new_args: ~[~str]) {
-    let overridden_args = @OverriddenArgs { val: copy new_args };
+    let overridden_args = @OverriddenArgs {
+        val: new_args.clone()
+    };
     local_data::set(overridden_arg_key, overridden_args);
 }
 
@@ -1807,7 +1810,7 @@ mod tests {
         }
         let n = make_rand_name();
         setenv(n, s);
-        debug!(copy s);
+        debug!(s.clone());
         assert_eq!(getenv(n), option::Some(s));
     }
 
@@ -1816,7 +1819,7 @@ mod tests {
         let path = os::self_exe_path();
         assert!(path.is_some());
         let path = path.get();
-        debug!(copy path);
+        debug!(path.clone());
 
         // Hard to test this function
         assert!(path.is_absolute);
@@ -1828,8 +1831,8 @@ mod tests {
         let e = env();
         assert!(e.len() > 0u);
         for e.iter().advance |p| {
-            let (n, v) = copy *p;
-            debug!(copy n);
+            let (n, v) = (*p).clone();
+            debug!(n.clone());
             let v2 = getenv(n);
             // MingW seems to set some funky environment variables like
             // "=C:=C:\MinGW\msys\1.0\bin" and "!::=::\" that are returned
@@ -1844,7 +1847,7 @@ mod tests {
 
         let mut e = env();
         setenv(n, "VALUE");
-        assert!(!e.contains(&(copy n, ~"VALUE")));
+        assert!(!e.contains(&(n.clone(), ~"VALUE")));
 
         e = env();
         assert!(e.contains(&(n, ~"VALUE")));
@@ -1920,7 +1923,7 @@ mod tests {
         assert!(dirs.len() > 0u);
 
         for dirs.iter().advance |dir| {
-            debug!(copy *dir);
+            debug!((*dir).clone());
         }
     }
 
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index a5e82c31d79..fe298931d42 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -16,6 +16,7 @@ Cross-platform file path handling
 
 #[allow(missing_doc)];
 
+use clone::Clone;
 use container::Container;
 use cmp::Eq;
 use iterator::IteratorUtil;
@@ -553,7 +554,7 @@ impl GenericPath for PosixPath {
     fn filename(&self) -> Option<~str> {
         match self.components.len() {
             0 => None,
-            n => Some(copy self.components[n - 1]),
+            n => Some(self.components[n - 1].clone()),
         }
     }
 
@@ -563,7 +564,7 @@ impl GenericPath for PosixPath {
             Some(ref f) => {
                 match f.rfind('.') {
                     Some(p) => Some(f.slice_to(p).to_owned()),
-                    None => Some(copy *f),
+                    None => Some((*f).clone()),
                 }
             }
         }
@@ -603,7 +604,7 @@ impl GenericPath for PosixPath {
 
     fn with_filetype(&self, t: &str) -> PosixPath {
         match (t.len(), self.filestem()) {
-            (0, None)        => copy *self,
+            (0, None)        => (*self).clone(),
             (0, Some(ref s)) => self.with_filename(*s),
             (_, None)        => self.with_filename(fmt!(".%s", t)),
             (_, Some(ref s)) => self.with_filename(fmt!("%s.%s", *s, t)),
@@ -612,7 +613,7 @@ impl GenericPath for PosixPath {
 
     fn dir_path(&self) -> PosixPath {
         match self.components.len() {
-            0 => copy *self,
+            0 => (*self).clone(),
             _ => self.pop(),
         }
     }
@@ -620,7 +621,7 @@ impl GenericPath for PosixPath {
     fn file_path(&self) -> PosixPath {
         let cs = match self.filename() {
           None => ~[],
-          Some(ref f) => ~[copy *f]
+          Some(ref f) => ~[(*f).clone()]
         };
         PosixPath {
             is_absolute: false,
@@ -637,7 +638,7 @@ impl GenericPath for PosixPath {
         if other.is_absolute {
             PosixPath {
                 is_absolute: true,
-                components: copy other.components,
+                components: other.components.clone(),
             }
         } else {
             self.push_rel(other)
@@ -649,7 +650,7 @@ impl GenericPath for PosixPath {
     }
 
     fn push_many<S: Str>(&self, cs: &[S]) -> PosixPath {
-        let mut v = copy self.components;
+        let mut v = self.components.clone();
         for cs.iter().advance |e| {
             for e.as_slice().split_iter(windows::is_sep).advance |s| {
                 if !s.is_empty() {
@@ -664,17 +665,20 @@ impl GenericPath for PosixPath {
     }
 
     fn push(&self, s: &str) -> PosixPath {
-        let mut v = copy self.components;
+        let mut v = self.components.clone();
         for s.split_iter(windows::is_sep).advance |s| {
             if !s.is_empty() {
                 v.push(s.to_owned())
             }
         }
-        PosixPath { components: v, ..copy *self }
+        PosixPath {
+            components: v,
+            ..(*self).clone()
+        }
     }
 
     fn pop(&self) -> PosixPath {
-        let mut cs = copy self.components;
+        let mut cs = self.components.clone();
         if cs.len() != 0 {
             cs.pop();
         }
@@ -734,13 +738,13 @@ impl GenericPath for WindowsPath {
         ) {
             (Some((ref d, ref r)), _) => {
                 host = None;
-                device = Some(copy *d);
-                rest = copy *r;
+                device = Some((*d).clone());
+                rest = (*r).clone();
             }
             (None, Some((ref h, ref r))) => {
-                host = Some(copy *h);
+                host = Some((*h).clone());
                 device = None;
-                rest = copy *r;
+                rest = (*r).clone();
             }
             (None, None) => {
                 host = None;
@@ -773,7 +777,7 @@ impl GenericPath for WindowsPath {
     fn filename(&self) -> Option<~str> {
         match self.components.len() {
             0 => None,
-            n => Some(copy self.components[n - 1]),
+            n => Some(self.components[n - 1].clone()),
         }
     }
 
@@ -783,7 +787,7 @@ impl GenericPath for WindowsPath {
             Some(ref f) => {
                 match f.rfind('.') {
                     Some(p) => Some(f.slice_to(p).to_owned()),
-                    None => Some(copy *f),
+                    None => Some((*f).clone()),
                 }
             }
         }
@@ -823,7 +827,7 @@ impl GenericPath for WindowsPath {
 
     fn with_filetype(&self, t: &str) -> WindowsPath {
         match (t.len(), self.filestem()) {
-            (0, None)        => copy *self,
+            (0, None)        => (*self).clone(),
             (0, Some(ref s)) => self.with_filename(*s),
             (_, None)        => self.with_filename(fmt!(".%s", t)),
             (_, Some(ref s)) => self.with_filename(fmt!("%s.%s", *s, t)),
@@ -832,7 +836,7 @@ impl GenericPath for WindowsPath {
 
     fn dir_path(&self) -> WindowsPath {
         match self.components.len() {
-            0 => copy *self,
+            0 => (*self).clone(),
             _ => self.pop(),
         }
     }
@@ -844,7 +848,7 @@ impl GenericPath for WindowsPath {
             is_absolute: false,
             components: match self.filename() {
                 None => ~[],
-                Some(ref f) => ~[copy *f],
+                Some(ref f) => ~[(*f).clone()],
             }
         }
     }
@@ -864,10 +868,10 @@ impl GenericPath for WindowsPath {
         match other.host {
             Some(ref host) => {
                 return WindowsPath {
-                    host: Some(copy *host),
-                    device: copy other.device,
+                    host: Some((*host).clone()),
+                    device: other.device.clone(),
                     is_absolute: true,
-                    components: copy other.components,
+                    components: other.components.clone(),
                 };
             }
             _ => {}
@@ -878,9 +882,9 @@ impl GenericPath for WindowsPath {
             Some(ref device) => {
                 return WindowsPath {
                     host: None,
-                    device: Some(copy *device),
+                    device: Some((*device).clone()),
                     is_absolute: true,
-                    components: copy other.components,
+                    components: other.components.clone(),
                 };
             }
             _ => {}
@@ -889,10 +893,10 @@ impl GenericPath for WindowsPath {
         /* fallback: host and device of lhs win, but the
            whole path of the right */
         WindowsPath {
-            host: copy self.host,
-            device: copy self.device,
+            host: self.host.clone(),
+            device: self.device.clone(),
             is_absolute: self.is_absolute || other.is_absolute,
-            components: copy other.components,
+            components: other.components.clone(),
         }
     }
 
@@ -912,7 +916,7 @@ impl GenericPath for WindowsPath {
     }
 
     fn push_many<S: Str>(&self, cs: &[S]) -> WindowsPath {
-        let mut v = copy self.components;
+        let mut v = self.components.clone();
         for cs.iter().advance |e| {
             for e.as_slice().split_iter(windows::is_sep).advance |s| {
                 if !s.is_empty() {
@@ -922,31 +926,31 @@ impl GenericPath for WindowsPath {
         }
         // tedious, but as-is, we can't use ..self
         WindowsPath {
-            host: copy self.host,
-            device: copy self.device,
+            host: self.host.clone(),
+            device: self.device.clone(),
             is_absolute: self.is_absolute,
             components: v
         }
     }
 
     fn push(&self, s: &str) -> WindowsPath {
-        let mut v = copy self.components;
+        let mut v = self.components.clone();
         for s.split_iter(windows::is_sep).advance |s| {
             if !s.is_empty() {
                 v.push(s.to_owned())
             }
         }
-        WindowsPath { components: v, ..copy *self }
+        WindowsPath { components: v, ..(*self).clone() }
     }
 
     fn pop(&self) -> WindowsPath {
-        let mut cs = copy self.components;
+        let mut cs = self.components.clone();
         if cs.len() != 0 {
             cs.pop();
         }
         WindowsPath {
-            host: copy self.host,
-            device: copy self.device,
+            host: self.host.clone(),
+            device: self.device.clone(),
             is_absolute: self.is_absolute,
             components: cs,
         }
@@ -954,7 +958,7 @@ impl GenericPath for WindowsPath {
 
     fn normalize(&self) -> WindowsPath {
         WindowsPath {
-            host: copy self.host,
+            host: self.host.clone(),
             device: match self.device {
                 None => None,
 
@@ -982,7 +986,7 @@ pub fn normalize(components: &[~str]) -> ~[~str] {
             cs.pop();
             loop;
         }
-        cs.push(copy *c);
+        cs.push((*c).clone());
     }
     cs
 }
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs
index e1a62b26bbf..caf15120bd7 100644
--- a/src/libstd/ptr.rs
+++ b/src/libstd/ptr.rs
@@ -11,6 +11,7 @@
 //! Unsafe pointer utility functions
 
 use cast;
+use clone::Clone;
 use option::{Option, Some, None};
 use sys;
 use unstable::intrinsics;
@@ -45,6 +46,12 @@ pub unsafe fn buf_len<T>(buf: **T) -> uint {
     position(buf, |i| *i == null())
 }
 
+impl<T> Clone for *T {
+    fn clone(&self) -> *T {
+        *self
+    }
+}
+
 /// Return the first offset `i` such that `f(buf[i]) == true`.
 #[inline]
 pub unsafe fn position<T>(buf: *T, f: &fn(&T) -> bool) -> uint {
@@ -617,7 +624,7 @@ pub mod ptr_tests {
             array_each_with_len(arr_ptr, arr.len(),
                                 |e| {
                                          let actual = str::raw::from_c_str(e);
-                                         let expected = copy expected_arr[ctr];
+                                         let expected = expected_arr[ctr].clone();
                                          debug!(
                                              "test_ptr_array_each e: %s, a: %s",
                                              expected, actual);
@@ -649,7 +656,7 @@ pub mod ptr_tests {
             let mut iteration_count = 0;
             array_each(arr_ptr, |e| {
                 let actual = str::raw::from_c_str(e);
-                let expected = copy expected_arr[ctr];
+                let expected = expected_arr[ctr].clone();
                 debug!(
                     "test_ptr_array_each e: %s, a: %s",
                     expected, actual);
diff --git a/src/libstd/rand.rs b/src/libstd/rand.rs
index 6f89e7ffb07..7d65ba63ff0 100644
--- a/src/libstd/rand.rs
+++ b/src/libstd/rand.rs
@@ -44,6 +44,7 @@ fn main () {
 */
 
 use cast;
+use clone::Clone;
 use cmp;
 use container::Container;
 use int;
@@ -355,9 +356,9 @@ pub trait RngUtil {
      * }
      * ~~~
      */
-    fn choose<T:Copy>(&mut self, values: &[T]) -> T;
+    fn choose<T:Copy + Clone>(&mut self, values: &[T]) -> T;
     /// Choose Some(item) randomly, returning None if values is empty
-    fn choose_option<T:Copy>(&mut self, values: &[T]) -> Option<T>;
+    fn choose_option<T:Clone>(&mut self, values: &[T]) -> Option<T>;
     /**
      * Choose an item respecting the relative weights, failing if the sum of
      * the weights is 0
@@ -378,7 +379,7 @@ pub trait RngUtil {
      * }
      * ~~~
      */
-    fn choose_weighted<T:Copy>(&mut self, v : &[Weighted<T>]) -> T;
+    fn choose_weighted<T:Copy + Clone>(&mut self, v : &[Weighted<T>]) -> T;
     /**
      * Choose Some(item) respecting the relative weights, returning none if
      * the sum of the weights is 0
@@ -399,7 +400,7 @@ pub trait RngUtil {
      * }
      * ~~~
      */
-    fn choose_weighted_option<T:Copy>(&mut self, v: &[Weighted<T>])
+    fn choose_weighted_option<T:Clone>(&mut self, v: &[Weighted<T>])
                                      -> Option<T>;
     /**
      * Return a vec containing copies of the items, in order, where
@@ -421,7 +422,7 @@ pub trait RngUtil {
      * }
      * ~~~
      */
-    fn weighted_vec<T:Copy>(&mut self, v: &[Weighted<T>]) -> ~[T];
+    fn weighted_vec<T:Clone>(&mut self, v: &[Weighted<T>]) -> ~[T];
     /**
      * Shuffle a vec
      *
@@ -438,7 +439,7 @@ pub trait RngUtil {
      * }
      * ~~~
      */
-    fn shuffle<T:Copy>(&mut self, values: &[T]) -> ~[T];
+    fn shuffle<T:Copy + Clone>(&mut self, values: &[T]) -> ~[T];
     /**
      * Shuffle a mutable vec in place
      *
@@ -531,23 +532,23 @@ impl<R: Rng> RngUtil for R {
     }
 
     /// Choose an item randomly, failing if values is empty
-    fn choose<T:Copy>(&mut self, values: &[T]) -> T {
+    fn choose<T:Copy + Clone>(&mut self, values: &[T]) -> T {
         self.choose_option(values).get()
     }
 
     /// Choose Some(item) randomly, returning None if values is empty
-    fn choose_option<T:Copy>(&mut self, values: &[T]) -> Option<T> {
+    fn choose_option<T:Clone>(&mut self, values: &[T]) -> Option<T> {
         if values.is_empty() {
             None
         } else {
-            Some(copy values[self.gen_uint_range(0u, values.len())])
+            Some(values[self.gen_uint_range(0u, values.len())].clone())
         }
     }
     /**
      * Choose an item respecting the relative weights, failing if the sum of
      * the weights is 0
      */
-    fn choose_weighted<T:Copy>(&mut self, v: &[Weighted<T>]) -> T {
+    fn choose_weighted<T:Copy + Clone>(&mut self, v: &[Weighted<T>]) -> T {
         self.choose_weighted_option(v).get()
     }
 
@@ -555,8 +556,8 @@ impl<R: Rng> RngUtil for R {
      * Choose Some(item) respecting the relative weights, returning none if
      * the sum of the weights is 0
      */
-    fn choose_weighted_option<T:Copy>(&mut self, v: &[Weighted<T>])
-                                     -> Option<T> {
+    fn choose_weighted_option<T:Clone>(&mut self, v: &[Weighted<T>])
+                                       -> Option<T> {
         let mut total = 0u;
         for v.iter().advance |item| {
             total += item.weight;
@@ -569,7 +570,7 @@ impl<R: Rng> RngUtil for R {
         for v.iter().advance |item| {
             so_far += item.weight;
             if so_far > chosen {
-                return Some(copy item.item);
+                return Some(item.item.clone());
             }
         }
         util::unreachable();
@@ -579,18 +580,18 @@ impl<R: Rng> RngUtil for R {
      * Return a vec containing copies of the items, in order, where
      * the weight of the item determines how many copies there are
      */
-    fn weighted_vec<T:Copy>(&mut self, v: &[Weighted<T>]) -> ~[T] {
+    fn weighted_vec<T:Clone>(&mut self, v: &[Weighted<T>]) -> ~[T] {
         let mut r = ~[];
         for v.iter().advance |item| {
             for uint::range(0u, item.weight) |_i| {
-                r.push(copy item.item);
+                r.push(item.item.clone());
             }
         }
         r
     }
 
     /// Shuffle a vec
-    fn shuffle<T:Copy>(&mut self, values: &[T]) -> ~[T] {
+    fn shuffle<T:Copy + Clone>(&mut self, values: &[T]) -> ~[T] {
         let mut m = values.to_owned();
         self.shuffle_mut(m);
         m
diff --git a/src/libstd/result.rs b/src/libstd/result.rs
index 0b099b66ecf..4fdcf9bb0b3 100644
--- a/src/libstd/result.rs
+++ b/src/libstd/result.rs
@@ -12,10 +12,10 @@
 
 #[allow(missing_doc)];
 
+use clone::Clone;
 use cmp::Eq;
 use either;
 use either::Either;
-use kinds::Copy;
 use iterator::IteratorUtil;
 use option::{None, Option, Some};
 use vec;
@@ -39,9 +39,9 @@ pub enum Result<T, U> {
  * If the result is an error
  */
 #[inline]
-pub fn get<T:Copy,U>(res: &Result<T, U>) -> T {
+pub fn get<T:Clone,U>(res: &Result<T, U>) -> T {
     match *res {
-      Ok(ref t) => copy *t,
+      Ok(ref t) => (*t).clone(),
       Err(ref the_err) =>
         fail!("get called on error result: %?", *the_err)
     }
@@ -71,9 +71,9 @@ pub fn get_ref<'a, T, U>(res: &'a Result<T, U>) -> &'a T {
  * If the result is not an error
  */
 #[inline]
-pub fn get_err<T, U: Copy>(res: &Result<T, U>) -> U {
+pub fn get_err<T, U: Clone>(res: &Result<T, U>) -> U {
     match *res {
-      Err(ref u) => copy *u,
+      Err(ref u) => (*u).clone(),
       Ok(_) => fail!("get_err called on ok result")
     }
 }
@@ -100,11 +100,11 @@ pub fn is_err<T, U>(res: &Result<T, U>) -> bool {
  * result variants are converted to `either::left`.
  */
 #[inline]
-pub fn to_either<T:Copy,U:Copy>(res: &Result<U, T>)
+pub fn to_either<T:Clone,U:Clone>(res: &Result<U, T>)
     -> Either<T, U> {
     match *res {
-      Ok(ref res) => either::Right(copy *res),
-      Err(ref fail_) => either::Left(copy *fail_)
+      Ok(ref res) => either::Right((*res).clone()),
+      Err(ref fail_) => either::Left((*fail_).clone())
     }
 }
 
@@ -203,11 +203,11 @@ pub fn iter_err<T, E>(res: &Result<T, E>, f: &fn(&E)) {
  *     }
  */
 #[inline]
-pub fn map<T, E: Copy, U: Copy>(res: &Result<T, E>, op: &fn(&T) -> U)
+pub fn map<T, E: Clone, U: Clone>(res: &Result<T, E>, op: &fn(&T) -> U)
   -> Result<U, E> {
     match *res {
       Ok(ref t) => Ok(op(t)),
-      Err(ref e) => Err(copy *e)
+      Err(ref e) => Err((*e).clone())
     }
 }
 
@@ -220,10 +220,10 @@ pub fn map<T, E: Copy, U: Copy>(res: &Result<T, E>, op: &fn(&T) -> U)
  * successful result while handling an error.
  */
 #[inline]
-pub fn map_err<T:Copy,E,F:Copy>(res: &Result<T, E>, op: &fn(&E) -> F)
+pub fn map_err<T:Clone,E,F:Clone>(res: &Result<T, E>, op: &fn(&E) -> F)
   -> Result<T, F> {
     match *res {
-      Ok(ref t) => Ok(copy *t),
+      Ok(ref t) => Ok((*t).clone()),
       Err(ref e) => Err(op(e))
     }
 }
@@ -261,22 +261,22 @@ impl<T, E> Result<T, E> {
     }
 }
 
-impl<T:Copy,E> Result<T, E> {
+impl<T:Clone,E> Result<T, E> {
     #[inline]
     pub fn get(&self) -> T { get(self) }
 
     #[inline]
-    pub fn map_err<F:Copy>(&self, op: &fn(&E) -> F) -> Result<T,F> {
+    pub fn map_err<F:Clone>(&self, op: &fn(&E) -> F) -> Result<T,F> {
         map_err(self, op)
     }
 }
 
-impl<T, E: Copy> Result<T, E> {
+impl<T, E:Clone> Result<T, E> {
     #[inline]
     pub fn get_err(&self) -> E { get_err(self) }
 
     #[inline]
-    pub fn map<U:Copy>(&self, op: &fn(&T) -> U) -> Result<U,E> {
+    pub fn map<U:Clone>(&self, op: &fn(&T) -> U) -> Result<U,E> {
         map(self, op)
     }
 }
@@ -299,9 +299,8 @@ impl<T, E: Copy> Result<T, E> {
  *     }
  */
 #[inline]
-pub fn map_vec<T,U:Copy,V:Copy>(
-    ts: &[T], op: &fn(&T) -> Result<V,U>) -> Result<~[V],U> {
-
+pub fn map_vec<T,U,V>(ts: &[T], op: &fn(&T) -> Result<V,U>)
+                      -> Result<~[V],U> {
     let mut vs: ~[V] = vec::with_capacity(ts.len());
     for ts.iter().advance |t| {
         match op(t) {
@@ -314,15 +313,18 @@ pub fn map_vec<T,U:Copy,V:Copy>(
 
 #[inline]
 #[allow(missing_doc)]
-pub fn map_opt<T,U:Copy,V:Copy>(
-    o_t: &Option<T>, op: &fn(&T) -> Result<V,U>) -> Result<Option<V>,U> {
-
+pub fn map_opt<T,
+               U,
+               V>(
+               o_t: &Option<T>,
+               op: &fn(&T) -> Result<V,U>)
+               -> Result<Option<V>,U> {
     match *o_t {
-      None => Ok(None),
-      Some(ref t) => match op(t) {
-        Ok(v) => Ok(Some(v)),
-        Err(e) => Err(e)
-      }
+        None => Ok(None),
+        Some(ref t) => match op(t) {
+            Ok(v) => Ok(Some(v)),
+            Err(e) => Err(e)
+        }
     }
 }
 
@@ -336,7 +338,7 @@ pub fn map_opt<T,U:Copy,V:Copy>(
  * to accommodate an error like the vectors being of different lengths.
  */
 #[inline]
-pub fn map_vec2<S,T,U:Copy,V:Copy>(ss: &[S], ts: &[T],
+pub fn map_vec2<S,T,U,V>(ss: &[S], ts: &[T],
                 op: &fn(&S,&T) -> Result<V,U>) -> Result<~[V],U> {
 
     assert!(vec::same_length(ss, ts));
@@ -359,7 +361,7 @@ pub fn map_vec2<S,T,U:Copy,V:Copy>(ss: &[S], ts: &[T],
  * on its own as no result vector is built.
  */
 #[inline]
-pub fn iter_vec2<S,T,U:Copy>(ss: &[S], ts: &[T],
+pub fn iter_vec2<S,T,U>(ss: &[S], ts: &[T],
                          op: &fn(&S,&T) -> Result<(),U>) -> Result<(),U> {
 
     assert!(vec::same_length(ss, ts));
diff --git a/src/libstd/rt/join_latch.rs b/src/libstd/rt/join_latch.rs
index 8073c4a75b8..924db1a21b7 100644
--- a/src/libstd/rt/join_latch.rs
+++ b/src/libstd/rt/join_latch.rs
@@ -583,29 +583,31 @@ mod test {
         }
     }
 
+    #[deriving(Clone)]
+    struct Order {
+        immediate: bool,
+        succeed: bool,
+        orders: ~[Order]
+    }
+
     #[test]
     fn whateverman() {
-        struct Order {
-            immediate: bool,
-            succeed: bool,
-            orders: ~[Order]
-        }
         fn next(latch: &mut JoinLatch, orders: ~[Order]) {
             for orders.iter().advance |order| {
-                let suborders = copy order.orders;
+                let suborders = order.orders.clone();
                 let child_latch = Cell::new(latch.new_child());
                 let succeed = order.succeed;
                 if order.immediate {
                     do spawntask_immediately {
                         let mut child_latch = child_latch.take();
-                        next(&mut *child_latch, copy suborders);
+                        next(&mut *child_latch, suborders.clone());
                         rtdebug!("immediate releasing");
                         child_latch.release(succeed);
                     }
                 } else {
                     do spawntask_later {
                         let mut child_latch = child_latch.take();
-                        next(&mut *child_latch, copy suborders);
+                        next(&mut *child_latch, suborders.clone());
                         rtdebug!("later releasing");
                         child_latch.release(succeed);
                     }
diff --git a/src/libstd/run.rs b/src/libstd/run.rs
index 883870db1e6..d2c308c07ea 100644
--- a/src/libstd/run.rs
+++ b/src/libstd/run.rs
@@ -13,6 +13,7 @@
 #[allow(missing_doc)];
 
 use cast;
+use clone::Clone;
 use comm::{stream, SharedChan, GenericChan, GenericPort};
 use io;
 use iterator::IteratorUtil;
@@ -698,7 +699,7 @@ fn with_argv<T>(prog: &str, args: &[~str],
     let mut argptrs = ~[str::as_c_str(prog, |b| b)];
     let mut tmps = ~[];
     for args.iter().advance |arg| {
-        let t = @copy *arg;
+        let t = @(*arg).clone();
         tmps.push(t);
         argptrs.push(str::as_c_str(*t, |b| b));
     }
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index bc3015685bb..0811dab407e 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -2260,6 +2260,13 @@ impl Clone for ~str {
     }
 }
 
+impl Clone for @str {
+    #[inline]
+    fn clone(&self) -> @str {
+        *self
+    }
+}
+
 /// External iterator for a string's characters. Use with the `std::iterator`
 /// module.
 pub struct StrCharIterator<'self> {
@@ -3210,7 +3217,7 @@ mod tests {
                 0x000a_u16 ]) ];
 
         for pairs.iter().advance |p| {
-            let (s, u) = copy *p;
+            let (s, u) = (*p).clone();
             assert!(s.to_utf16() == u);
             assert!(from_utf16(u) == s);
             assert!(from_utf16(s.to_utf16()) == s);
diff --git a/src/libstd/tuple.rs b/src/libstd/tuple.rs
index 45702546278..841be4df6e2 100644
--- a/src/libstd/tuple.rs
+++ b/src/libstd/tuple.rs
@@ -12,6 +12,7 @@
 
 #[allow(missing_doc)];
 
+use clone::Clone;
 use kinds::Copy;
 use vec;
 use vec::ImmutableVector;
@@ -19,7 +20,7 @@ use iterator::IteratorUtil;
 
 pub use self::inner::*;
 
-/// Method extensions to pairs where both types satisfy the `Copy` bound
+/// Method extensions to pairs where both types satisfy the `Clone` bound
 pub trait CopyableTuple<T, U> {
     /// Return the first element of self
     fn first(&self) -> T;
@@ -29,12 +30,12 @@ pub trait CopyableTuple<T, U> {
     fn swap(&self) -> (U, T);
 }
 
-impl<T:Copy,U:Copy> CopyableTuple<T, U> for (T, U) {
+impl<T:Clone,U:Clone> CopyableTuple<T, U> for (T, U) {
     /// Return the first element of self
     #[inline]
     fn first(&self) -> T {
         match *self {
-            (ref t, _) => copy *t,
+            (ref t, _) => (*t).clone(),
         }
     }
 
@@ -42,21 +43,21 @@ impl<T:Copy,U:Copy> CopyableTuple<T, U> for (T, U) {
     #[inline]
     fn second(&self) -> U {
         match *self {
-            (_, ref u) => copy *u,
+            (_, ref u) => (*u).clone(),
         }
     }
 
     /// Return the results of swapping the two elements of self
     #[inline]
     fn swap(&self) -> (U, T) {
-        match copy *self {
+        match (*self).clone() {
             (t, u) => (u, t),
         }
     }
 }
 
 /// Method extensions for pairs where the types don't necessarily satisfy the
-/// `Copy` bound
+/// `Clone` bound
 pub trait ImmutableTuple<T, U> {
     /// Return a reference to the first element of self
     fn first_ref<'a>(&'a self) -> &'a T;
@@ -84,7 +85,11 @@ pub trait ExtendedTupleOps<A,B> {
     fn map<C>(&self, f: &fn(a: &A, b: &B) -> C) -> ~[C];
 }
 
-impl<'self,A:Copy,B:Copy> ExtendedTupleOps<A,B> for (&'self [A], &'self [B]) {
+impl<'self,
+     A:Copy + Clone,
+     B:Copy + Clone>
+     ExtendedTupleOps<A,B> for
+     (&'self [A], &'self [B]) {
     #[inline]
     fn zip(&self) -> ~[(A, B)] {
         match *self {
@@ -104,7 +109,10 @@ impl<'self,A:Copy,B:Copy> ExtendedTupleOps<A,B> for (&'self [A], &'self [B]) {
     }
 }
 
-impl<A:Copy,B:Copy> ExtendedTupleOps<A,B> for (~[A], ~[B]) {
+impl<A:Copy + Clone,
+     B:Copy + Clone>
+     ExtendedTupleOps<A,B> for
+     (~[A], ~[B]) {
     #[inline]
     fn zip(&self) -> ~[(A, B)] {
         match *self {
diff --git a/src/libstd/util.rs b/src/libstd/util.rs
index fd29d7dc14b..8e7efeb532a 100644
--- a/src/libstd/util.rs
+++ b/src/libstd/util.rs
@@ -127,6 +127,8 @@ pub fn unreachable() -> ! {
 #[cfg(test)]
 mod tests {
     use super::*;
+
+    use clone::Clone;
     use option::{None, Some};
     use either::{Either, Left, Right};
     use sys::size_of;
@@ -136,8 +138,8 @@ mod tests {
     fn identity_crisis() {
         // Writing a test for the identity function. How did it come to this?
         let x = ~[(5, false)];
-        //FIXME #3387 assert!(x.eq(id(copy x)));
-        let y = copy x;
+        //FIXME #3387 assert!(x.eq(id(x.clone())));
+        let y = x.clone();
         assert!(x.eq(&id(y)));
     }
 
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index c728d4a60f1..c9c5217ca61 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -14,12 +14,11 @@
 
 use cast::transmute;
 use cast;
+use clone::Clone;
 use container::{Container, Mutable};
-use cmp;
 use cmp::{Eq, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
-use clone::Clone;
+use cmp;
 use iterator::*;
-use kinds::Copy;
 use libc::c_void;
 use num::Zero;
 use option::{None, Option, Some};
@@ -72,7 +71,7 @@ pub fn from_fn<T>(n_elts: uint, op: &fn(uint) -> T) -> ~[T] {
  * Creates an owned vector of size `n_elts` and initializes the elements
  * to the value `t`.
  */
-pub fn from_elem<T:Copy>(n_elts: uint, t: T) -> ~[T] {
+pub fn from_elem<T:Clone>(n_elts: uint, t: T) -> ~[T] {
     // FIXME (#7136): manually inline from_fn for 2x plus speedup (sadly very
     // important, from_elem is a bottleneck in borrowck!). Unfortunately it
     // still is substantially slower than using the unsafe
@@ -82,7 +81,7 @@ pub fn from_elem<T:Copy>(n_elts: uint, t: T) -> ~[T] {
         do v.as_mut_buf |p, _len| {
             let mut i = 0u;
             while i < n_elts {
-                intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), copy t);
+                intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i)), t.clone());
                 i += 1u;
             }
         }
@@ -241,7 +240,7 @@ impl<'self, T> Iterator<&'self [T]> for VecRSplitIterator<'self, T> {
 /// Iterates over the `rhs` vector, copying each element and appending it to the
 /// `lhs`. Afterwards, the `lhs` is then returned for use again.
 #[inline]
-pub fn append<T:Copy>(lhs: ~[T], rhs: &[T]) -> ~[T] {
+pub fn append<T:Clone>(lhs: ~[T], rhs: &[T]) -> ~[T] {
     let mut v = lhs;
     v.push_all(rhs);
     v
@@ -269,16 +268,16 @@ pub fn flat_map<T, U>(v: &[T], f: &fn(t: &T) -> ~[U]) -> ~[U] {
 }
 
 /// Flattens a vector of vectors of T into a single vector of T.
-pub fn concat<T:Copy>(v: &[~[T]]) -> ~[T] { v.concat_vec() }
+pub fn concat<T:Clone>(v: &[~[T]]) -> ~[T] { v.concat_vec() }
 
 /// Concatenate a vector of vectors, placing a given separator between each
-pub fn connect<T:Copy>(v: &[~[T]], sep: &T) -> ~[T] { v.connect_vec(sep) }
+pub fn connect<T:Clone>(v: &[~[T]], sep: &T) -> ~[T] { v.connect_vec(sep) }
 
 /// Flattens a vector of vectors of T into a single vector of T.
-pub fn concat_slices<T:Copy>(v: &[&[T]]) -> ~[T] { v.concat_vec() }
+pub fn concat_slices<T:Clone>(v: &[&[T]]) -> ~[T] { v.concat_vec() }
 
 /// Concatenate a vector of vectors, placing a given separator between each
-pub fn connect_slices<T:Copy>(v: &[&[T]], sep: &T) -> ~[T] { v.connect_vec(sep) }
+pub fn connect_slices<T:Clone>(v: &[&[T]], sep: &T) -> ~[T] { v.connect_vec(sep) }
 
 #[allow(missing_doc)]
 pub trait VectorVector<T> {
@@ -288,10 +287,10 @@ pub trait VectorVector<T> {
     pub fn connect_vec(&self, sep: &T) -> ~[T];
 }
 
-impl<'self, T:Copy> VectorVector<T> for &'self [~[T]] {
+impl<'self, T:Clone> VectorVector<T> for &'self [~[T]] {
     /// Flattens a vector of slices of T into a single vector of T.
     pub fn concat_vec(&self) -> ~[T] {
-        self.flat_map(|inner| copy *inner)
+        self.flat_map(|inner| (*inner).clone())
     }
 
     /// Concatenate a vector of vectors, placing a given separator between each.
@@ -299,14 +298,14 @@ impl<'self, T:Copy> VectorVector<T> for &'self [~[T]] {
         let mut r = ~[];
         let mut first = true;
         for self.iter().advance |inner| {
-            if first { first = false; } else { r.push(copy *sep); }
-            r.push_all(copy *inner);
+            if first { first = false; } else { r.push((*sep).clone()); }
+            r.push_all((*inner).clone());
         }
         r
     }
 }
 
-impl<'self, T:Copy> VectorVector<T> for &'self [&'self [T]] {
+impl<'self,T:Clone> VectorVector<T> for &'self [&'self [T]] {
     /// Flattens a vector of slices of T into a single vector of T.
     pub fn concat_vec(&self) -> ~[T] {
         self.flat_map(|&inner| inner.to_owned())
@@ -317,7 +316,7 @@ impl<'self, T:Copy> VectorVector<T> for &'self [&'self [T]] {
         let mut r = ~[];
         let mut first = true;
         for self.iter().advance |&inner| {
-            if first { first = false; } else { r.push(copy *sep); }
+            if first { first = false; } else { r.push((*sep).clone()); }
             r.push_all(inner);
         }
         r
@@ -331,11 +330,11 @@ impl<'self, T:Copy> VectorVector<T> for &'self [&'self [T]] {
 /**
  * Convert a vector of pairs into a pair of vectors, by reference. As unzip().
  */
-pub fn unzip_slice<T:Copy,U:Copy>(v: &[(T, U)]) -> (~[T], ~[U]) {
+pub fn unzip_slice<T:Clone,U:Clone>(v: &[(T, U)]) -> (~[T], ~[U]) {
     let mut ts = ~[];
     let mut us = ~[];
     for v.iter().advance |p| {
-        let (t, u) = copy *p;
+        let (t, u) = (*p).clone();
         ts.push(t);
         us.push(u);
     }
@@ -364,14 +363,13 @@ pub fn unzip<T,U>(v: ~[(T, U)]) -> (~[T], ~[U]) {
 /**
  * Convert two vectors to a vector of pairs, by reference. As zip().
  */
-pub fn zip_slice<T:Copy,U:Copy>(v: &[T], u: &[U])
-        -> ~[(T, U)] {
+pub fn zip_slice<T:Clone,U:Clone>(v: &[T], u: &[U]) -> ~[(T, U)] {
     let mut zipped = ~[];
     let sz = v.len();
     let mut i = 0u;
     assert_eq!(sz, u.len());
     while i < sz {
-        zipped.push((copy v[i], copy u[i]));
+        zipped.push((v[i].clone(), u[i].clone()));
         i += 1u;
     }
     zipped
@@ -415,9 +413,9 @@ pub fn zip<T, U>(mut v: ~[T], mut u: ~[U]) -> ~[(T, U)] {
  *
  *  * `fun` - The function to iterate over the combinations
  */
-pub fn each_permutation<T:Copy>(values: &[T], fun: &fn(perm : &[T]) -> bool) -> bool {
+pub fn each_permutation<T:Clone>(values: &[T], fun: &fn(perm : &[T]) -> bool) -> bool {
     let length = values.len();
-    let mut permutation = vec::from_fn(length, |i| copy values[i]);
+    let mut permutation = vec::from_fn(length, |i| values[i].clone());
     if length <= 1 {
         fun(permutation);
         return true;
@@ -444,7 +442,7 @@ pub fn each_permutation<T:Copy>(values: &[T], fun: &fn(perm : &[T]) -> bool) ->
         indices.mut_slice(k+1, length).reverse();
         // fixup permutation based on indices
         for uint::range(k, length) |i| {
-            permutation[i] = copy values[indices[i]];
+            permutation[i] = values[indices[i]].clone();
         }
     }
 }
@@ -496,7 +494,8 @@ impl<'self, T> Iterator<&'self [T]> for VecChunkIter<'self, T> {
 #[cfg(not(test))]
 pub mod traits {
     use super::Vector;
-    use kinds::Copy;
+
+    use clone::Clone;
     use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Equal, Equiv};
     use ops::Add;
 
@@ -615,7 +614,7 @@ pub mod traits {
         fn gt(&self, other: &@[T]) -> bool { self.as_slice() > other.as_slice() }
     }
 
-    impl<'self,T:Copy, V: Vector<T>> Add<V, ~[T]> for &'self [T] {
+    impl<'self,T:Clone, V: Vector<T>> Add<V, ~[T]> for &'self [T] {
         #[inline]
         fn add(&self, rhs: &V) -> ~[T] {
             let mut res = self.to_owned();
@@ -623,7 +622,7 @@ pub mod traits {
             res
         }
     }
-    impl<T:Copy, V: Vector<T>> Add<V, ~[T]> for ~[T] {
+    impl<T:Clone, V: Vector<T>> Add<V, ~[T]> for ~[T] {
         #[inline]
         fn add(&self, rhs: &V) -> ~[T] {
             let mut res = self.to_owned();
@@ -688,13 +687,13 @@ pub trait CopyableVector<T> {
 }
 
 /// Extension methods for vectors
-impl<'self,T:Copy> CopyableVector<T> for &'self [T] {
+impl<'self,T:Clone> CopyableVector<T> for &'self [T] {
     /// Returns a copy of `v`.
     #[inline]
     fn to_owned(&self) -> ~[T] {
         let mut result = with_capacity(self.len());
         for self.iter().advance |e| {
-            result.push(copy *e);
+            result.push((*e).clone());
         }
         result
     }
@@ -927,6 +926,7 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
     fn flat_map<U>(&self, f: &fn(t: &T) -> ~[U]) -> ~[U] {
         flat_map(*self, f)
     }
+
     /// Returns a pointer to the element at the given index, without doing
     /// bounds checking.
     #[inline]
@@ -1044,7 +1044,7 @@ pub trait ImmutableCopyableVector<T> {
 }
 
 /// Extension methods for vectors
-impl<'self,T:Copy> ImmutableCopyableVector<T> for &'self [T] {
+impl<'self,T:Clone> ImmutableCopyableVector<T> for &'self [T] {
     /**
      * Partitions the vector into those that satisfies the predicate, and
      * those that do not.
@@ -1056,9 +1056,9 @@ impl<'self,T:Copy> ImmutableCopyableVector<T> for &'self [T] {
 
         for self.iter().advance |elt| {
             if f(elt) {
-                lefts.push(copy *elt);
+                lefts.push((*elt).clone());
             } else {
-                rights.push(copy *elt);
+                rights.push((*elt).clone());
             }
         }
 
@@ -1068,7 +1068,7 @@ impl<'self,T:Copy> ImmutableCopyableVector<T> for &'self [T] {
     /// Returns the element at the given index, without doing bounds checking.
     #[inline]
     unsafe fn unsafe_get(&self, index: uint) -> T {
-        copy *self.unsafe_ref(index)
+        (*self.unsafe_ref(index)).clone()
     }
 }
 
@@ -1555,13 +1555,13 @@ impl<T> Mutable for ~[T] {
 }
 
 #[allow(missing_doc)]
-pub trait OwnedCopyableVector<T:Copy> {
+pub trait OwnedCopyableVector<T:Clone> {
     fn push_all(&mut self, rhs: &[T]);
     fn grow(&mut self, n: uint, initval: &T);
     fn grow_set(&mut self, index: uint, initval: &T, val: T);
 }
 
-impl<T:Copy> OwnedCopyableVector<T> for ~[T] {
+impl<T:Clone> OwnedCopyableVector<T> for ~[T] {
     /// Iterates over the slice `rhs`, copies each element, and then appends it to
     /// the vector provided `v`. The `rhs` vector is traversed in-order.
     ///
@@ -1596,7 +1596,7 @@ impl<T:Copy> OwnedCopyableVector<T> for ~[T] {
         let mut i: uint = 0u;
 
         while i < n {
-            self.push(copy *initval);
+            self.push((*initval).clone());
             i += 1u;
         }
     }
@@ -1894,7 +1894,7 @@ pub struct UnboxedVecRepr {
 /// Unsafe operations
 pub mod raw {
     use cast::transmute;
-    use kinds::Copy;
+    use clone::Clone;
     use managed;
     use option::{None, Some};
     use ptr;
@@ -2009,8 +2009,8 @@ pub mod raw {
      * Unchecked vector indexing.
      */
     #[inline]
-    pub unsafe fn get<T:Copy>(v: &[T], i: uint) -> T {
-        v.as_imm_buf(|p, _len| copy *ptr::offset(p, i))
+    pub unsafe fn get<T:Clone>(v: &[T], i: uint) -> T {
+        v.as_imm_buf(|p, _len| (*ptr::offset(p, i)).clone())
     }
 
     /**