about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2014-12-05 17:01:33 -0800
committerNiko Matsakis <niko@alum.mit.edu>2014-12-08 13:47:44 -0500
commit096a28607fb80c91e6e2ca64d9ef44c4e550e96c (patch)
tree82c4ee8f20df133305959d507ec76adb4db5e324 /src/libcore
parentc7a9b49d1b5d4e520f25355f26a93dfac4ffa146 (diff)
downloadrust-096a28607fb80c91e6e2ca64d9ef44c4e550e96c.tar.gz
rust-096a28607fb80c91e6e2ca64d9ef44c4e550e96c.zip
librustc: Make `Copy` opt-in.
This change makes the compiler no longer infer whether types (structures
and enumerations) implement the `Copy` trait (and thus are implicitly
copyable). Rather, you must implement `Copy` yourself via `impl Copy for
MyType {}`.

A new warning has been added, `missing_copy_implementations`, to warn
you if a non-generic public type has been added that could have
implemented `Copy` but didn't.

For convenience, you may *temporarily* opt out of this behavior by using
`#![feature(opt_out_copy)]`. Note though that this feature gate will never be
accepted and will be removed by the time that 1.0 is released, so you should
transition your code away from using it.

This breaks code like:

    #[deriving(Show)]
    struct Point2D {
        x: int,
        y: int,
    }

    fn main() {
        let mypoint = Point2D {
            x: 1,
            y: 1,
        };
        let otherpoint = mypoint;
        println!("{}{}", mypoint, otherpoint);
    }

Change this code to:

    #[deriving(Show)]
    struct Point2D {
        x: int,
        y: int,
    }

    impl Copy for Point2D {}

    fn main() {
        let mypoint = Point2D {
            x: 1,
            y: 1,
        };
        let otherpoint = mypoint;
        println!("{}{}", mypoint, otherpoint);
    }

This is the backwards-incompatible part of #13231.

Part of RFC #3.

[breaking-change]
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/atomic.rs3
-rw-r--r--src/libcore/char.rs1
-rw-r--r--src/libcore/cmp.rs7
-rw-r--r--src/libcore/fmt/mod.rs4
-rw-r--r--src/libcore/fmt/num.rs5
-rw-r--r--src/libcore/fmt/rt.rs13
-rw-r--r--src/libcore/intrinsics.rs6
-rw-r--r--src/libcore/iter.rs11
-rw-r--r--src/libcore/kinds.rs17
-rw-r--r--src/libcore/lib.rs2
-rw-r--r--src/libcore/num/mod.rs2
-rw-r--r--src/libcore/ops.rs32
-rw-r--r--src/libcore/option.rs7
-rw-r--r--src/libcore/ptr.rs1
-rw-r--r--src/libcore/raw.rs9
-rw-r--r--src/libcore/result.rs5
-rw-r--r--src/libcore/simd.rs23
-rw-r--r--src/libcore/slice.rs6
-rw-r--r--src/libcore/str.rs9
19 files changed, 155 insertions, 8 deletions
diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs
index e930f353b52..748f5d774a4 100644
--- a/src/libcore/atomic.rs
+++ b/src/libcore/atomic.rs
@@ -17,6 +17,7 @@ pub use self::Ordering::*;
 use intrinsics;
 use std::kinds::marker;
 use cell::UnsafeCell;
+use kinds::Copy;
 
 /// A boolean type which can be safely shared between threads.
 #[stable]
@@ -81,6 +82,8 @@ pub enum Ordering {
     SeqCst,
 }
 
+impl Copy for Ordering {}
+
 /// An `AtomicBool` initialized to `false`.
 #[unstable = "may be renamed, pending conventions for static initalizers"]
 pub const INIT_ATOMIC_BOOL: AtomicBool =
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index 2bebe87a14c..8485e40819b 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -519,3 +519,4 @@ impl Iterator<char> for DefaultEscapedChars {
         }
     }
 }
+
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index a5ba2b03b15..87fa44cea66 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -43,9 +43,8 @@
 
 pub use self::Ordering::*;
 
-use kinds::Sized;
-use option::Option;
-use option::Option::{Some, None};
+use kinds::{Copy, Sized};
+use option::{Option, Some, None};
 
 /// Trait for values that can be compared for equality and inequality.
 ///
@@ -106,6 +105,8 @@ pub enum Ordering {
    Greater = 1i,
 }
 
+impl Copy for Ordering {}
+
 impl Ordering {
     /// Reverse the `Ordering`, so that `Less` becomes `Greater` and
     /// vice versa.
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 8b2ffd90ef7..88ea811cfd6 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -46,6 +46,8 @@ pub type Result = result::Result<(), Error>;
 #[experimental = "core and I/O reconciliation may alter this definition"]
 pub struct Error;
 
+impl Copy for Error {}
+
 /// A collection of methods that are required to format a message into a stream.
 ///
 /// This trait is the type which this modules requires when formatting
@@ -135,6 +137,8 @@ impl<'a> Argument<'a> {
     }
 }
 
+impl<'a> Copy for Argument<'a> {}
+
 impl<'a> Arguments<'a> {
     /// When using the format_args!() macro, this function is used to generate the
     /// Arguments structure.
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index a441ced03b2..fa6f48326b5 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -16,6 +16,7 @@
 
 use fmt;
 use iter::DoubleEndedIteratorExt;
+use kinds::Copy;
 use num::{Int, cast};
 use slice::SlicePrelude;
 
@@ -114,6 +115,8 @@ pub struct Radix {
     base: u8,
 }
 
+impl Copy for Radix {}
+
 impl Radix {
     fn new(base: u8) -> Radix {
         assert!(2 <= base && base <= 36, "the base must be in the range of 2..36: {}", base);
@@ -136,6 +139,8 @@ impl GenericRadix for Radix {
 #[unstable = "may be renamed or move to a different module"]
 pub struct RadixFmt<T, R>(T, R);
 
+impl<T,R> Copy for RadixFmt<T,R> where T: Copy, R: Copy {}
+
 /// Constructs a radix formatter in the range of `2..36`.
 ///
 /// # Example
diff --git a/src/libcore/fmt/rt.rs b/src/libcore/fmt/rt.rs
index 145e78dc668..748bd0bc4bd 100644
--- a/src/libcore/fmt/rt.rs
+++ b/src/libcore/fmt/rt.rs
@@ -20,6 +20,7 @@ pub use self::Alignment::*;
 pub use self::Count::*;
 pub use self::Position::*;
 pub use self::Flag::*;
+use kinds::Copy;
 
 #[doc(hidden)]
 pub struct Argument<'a> {
@@ -27,6 +28,8 @@ pub struct Argument<'a> {
     pub format: FormatSpec,
 }
 
+impl<'a> Copy for Argument<'a> {}
+
 #[doc(hidden)]
 pub struct FormatSpec {
     pub fill: char,
@@ -36,6 +39,8 @@ pub struct FormatSpec {
     pub width: Count,
 }
 
+impl Copy for FormatSpec {}
+
 /// Possible alignments that can be requested as part of a formatting directive.
 #[deriving(PartialEq)]
 pub enum Alignment {
@@ -49,16 +54,22 @@ pub enum Alignment {
     AlignUnknown,
 }
 
+impl Copy for Alignment {}
+
 #[doc(hidden)]
 pub enum Count {
     CountIs(uint), CountIsParam(uint), CountIsNextParam, CountImplied,
 }
 
+impl Copy for Count {}
+
 #[doc(hidden)]
 pub enum Position {
     ArgumentNext, ArgumentIs(uint)
 }
 
+impl Copy for Position {}
+
 /// Flags which can be passed to formatting via a directive.
 ///
 /// These flags are discovered through the `flags` field of the `Formatter`
@@ -78,3 +89,5 @@ pub enum Flag {
     /// being aware of the sign to be printed.
     FlagSignAwareZeroPad,
 }
+
+impl Copy for Flag {}
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index ece2ac6975e..2fc4d23e7fd 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -42,6 +42,8 @@
 #![experimental]
 #![allow(missing_docs)]
 
+use kinds::Copy;
+
 pub type GlueFn = extern "Rust" fn(*const i8);
 
 #[lang="ty_desc"]
@@ -59,6 +61,8 @@ pub struct TyDesc {
     pub name: &'static str,
 }
 
+impl Copy for TyDesc {}
+
 extern "rust-intrinsic" {
 
     // NB: These intrinsics take unsafe pointers because they mutate aliased
@@ -539,6 +543,8 @@ pub struct TypeId {
     t: u64,
 }
 
+impl Copy for TypeId {}
+
 impl TypeId {
     /// Returns the `TypeId` of the type this generic function has been instantiated with
     pub fn of<T: 'static>() -> TypeId {
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 49865bd3c7d..ddca9d36bed 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -59,6 +59,7 @@ pub use self::MinMaxResult::*;
 use clone::Clone;
 use cmp;
 use cmp::Ord;
+use kinds::Copy;
 use mem;
 use num::{ToPrimitive, Int};
 use ops::{Add, Deref};
@@ -1166,7 +1167,8 @@ pub struct Cycle<T> {
     iter: T,
 }
 
-#[unstable = "trait is unstable"]
+impl<T:Copy> Copy for Cycle<T> {}
+
 impl<A, T: Clone + Iterator<A>> Iterator<A> for Cycle<T> {
     #[inline]
     fn next(&mut self) -> Option<A> {
@@ -1576,7 +1578,8 @@ pub struct Peekable<A, T> {
     peeked: Option<A>,
 }
 
-#[unstable = "trait is unstable"]
+impl<T:Copy,A:Copy> Copy for Peekable<A,T> {}
+
 impl<A, T: Iterator<A>> Iterator<A> for Peekable<A, T> {
     #[inline]
     fn next(&mut self) -> Option<A> {
@@ -2115,6 +2118,8 @@ pub struct Counter<A> {
     step: A,
 }
 
+impl<A:Copy> Copy for Counter<A> {}
+
 /// Creates a new counter with the specified start/step
 #[inline]
 #[unstable = "may be renamed"]
@@ -2146,6 +2151,8 @@ pub struct Range<A> {
     one: A,
 }
 
+impl<A:Copy> Copy for Range<A> {}
+
 /// Returns an iterator over the given range [start, stop) (that is, starting
 /// at start (inclusive), and ending at stop (exclusive)).
 ///
diff --git a/src/libcore/kinds.rs b/src/libcore/kinds.rs
index 0c2cb9d5910..f932acffd3c 100644
--- a/src/libcore/kinds.rs
+++ b/src/libcore/kinds.rs
@@ -91,6 +91,8 @@ pub trait Sync for Sized? {
 /// implemented using unsafe code. In that case, you may want to embed
 /// some of the marker types below into your type.
 pub mod marker {
+    use super::Copy;
+
     /// A marker type whose type parameter `T` is considered to be
     /// covariant with respect to the type itself. This is (typically)
     /// used to indicate that an instance of the type `T` is being stored
@@ -132,6 +134,8 @@ pub mod marker {
     #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
     pub struct CovariantType<T>;
 
+    impl<T> Copy for CovariantType<T> {}
+
     /// A marker type whose type parameter `T` is considered to be
     /// contravariant with respect to the type itself. This is (typically)
     /// used to indicate that an instance of the type `T` will be consumed
@@ -175,6 +179,8 @@ pub mod marker {
     #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
     pub struct ContravariantType<T>;
 
+    impl<T> Copy for ContravariantType<T> {}
+
     /// A marker type whose type parameter `T` is considered to be
     /// invariant with respect to the type itself. This is (typically)
     /// used to indicate that instances of the type `T` may be read or
@@ -200,6 +206,8 @@ pub mod marker {
     #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
     pub struct InvariantType<T>;
 
+    impl<T> Copy for InvariantType<T> {}
+
     /// As `CovariantType`, but for lifetime parameters. Using
     /// `CovariantLifetime<'a>` indicates that it is ok to substitute
     /// a *longer* lifetime for `'a` than the one you originally
@@ -220,6 +228,8 @@ pub mod marker {
     #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
     pub struct CovariantLifetime<'a>;
 
+    impl<'a> Copy for CovariantLifetime<'a> {}
+
     /// As `ContravariantType`, but for lifetime parameters. Using
     /// `ContravariantLifetime<'a>` indicates that it is ok to
     /// substitute a *shorter* lifetime for `'a` than the one you
@@ -236,6 +246,8 @@ pub mod marker {
     #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
     pub struct ContravariantLifetime<'a>;
 
+    impl<'a> Copy for ContravariantLifetime<'a> {}
+
     /// As `InvariantType`, but for lifetime parameters. Using
     /// `InvariantLifetime<'a>` indicates that it is not ok to
     /// substitute any other lifetime for `'a` besides its original
@@ -253,6 +265,7 @@ pub mod marker {
     /// their instances remain thread-local.
     #[lang="no_send_bound"]
     #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
+    #[allow(missing_copy_implementations)]
     pub struct NoSend;
 
     /// A type which is considered "not POD", meaning that it is not
@@ -260,6 +273,7 @@ pub mod marker {
     /// ensure that they are never copied, even if they lack a destructor.
     #[lang="no_copy_bound"]
     #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
+    #[allow(missing_copy_implementations)]
     pub struct NoCopy;
 
     /// A type which is considered "not sync", meaning that
@@ -267,11 +281,14 @@ pub mod marker {
     /// shared between tasks.
     #[lang="no_sync_bound"]
     #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
+    #[allow(missing_copy_implementations)]
     pub struct NoSync;
 
     /// A type which is considered managed by the GC. This is typically
     /// embedded in other types.
     #[lang="managed_bound"]
     #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
+    #[allow(missing_copy_implementations)]
     pub struct Managed;
 }
+
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 5ad9462daf2..09d5061a02f 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -56,7 +56,7 @@
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![no_std]
-#![allow(unknown_features)]
+#![allow(unknown_features, raw_pointer_deriving)]
 #![feature(globs, intrinsics, lang_items, macro_rules, phase)]
 #![feature(simd, unsafe_destructor, slicing_syntax)]
 #![feature(default_type_params)]
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index e6946c83ceb..3c9b68b350b 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -1240,6 +1240,8 @@ pub enum FPCategory {
     FPNormal,
 }
 
+impl Copy for FPCategory {}
+
 /// A built-in floating point number.
 // FIXME(#5527): In a future version of Rust, many of these functions will
 //               become constants.
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index ce774a66381..e16b24923a8 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -90,6 +90,8 @@ pub trait Drop {
 /// ```rust
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Add<Foo, Foo> for Foo {
 ///     fn add(&self, _rhs: &Foo) -> Foo {
 ///       println!("Adding!");
@@ -128,6 +130,8 @@ add_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
 /// ```rust
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Sub<Foo, Foo> for Foo {
 ///     fn sub(&self, _rhs: &Foo) -> Foo {
 ///         println!("Subtracting!");
@@ -166,6 +170,8 @@ sub_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
 /// ```rust
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Mul<Foo, Foo> for Foo {
 ///     fn mul(&self, _rhs: &Foo) -> Foo {
 ///         println!("Multiplying!");
@@ -204,6 +210,8 @@ mul_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Div<Foo, Foo> for Foo {
 ///     fn div(&self, _rhs: &Foo) -> Foo {
 ///         println!("Dividing!");
@@ -242,6 +250,8 @@ div_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64 f32 f64)
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Rem<Foo, Foo> for Foo {
 ///     fn rem(&self, _rhs: &Foo) -> Foo {
 ///         println!("Remainder-ing!");
@@ -294,6 +304,8 @@ rem_float_impl!(f64, fmod)
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Neg<Foo> for Foo {
 ///     fn neg(&self) -> Foo {
 ///         println!("Negating!");
@@ -348,6 +360,8 @@ neg_uint_impl!(u64, i64)
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Not<Foo> for Foo {
 ///     fn not(&self) -> Foo {
 ///         println!("Not-ing!");
@@ -387,6 +401,8 @@ not_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64)
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl BitAnd<Foo, Foo> for Foo {
 ///     fn bitand(&self, _rhs: &Foo) -> Foo {
 ///         println!("Bitwise And-ing!");
@@ -425,6 +441,8 @@ bitand_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64)
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl BitOr<Foo, Foo> for Foo {
 ///     fn bitor(&self, _rhs: &Foo) -> Foo {
 ///         println!("Bitwise Or-ing!");
@@ -463,6 +481,8 @@ bitor_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64)
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl BitXor<Foo, Foo> for Foo {
 ///     fn bitxor(&self, _rhs: &Foo) -> Foo {
 ///         println!("Bitwise Xor-ing!");
@@ -501,6 +521,8 @@ bitxor_impl!(bool uint u8 u16 u32 u64 int i8 i16 i32 i64)
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Shl<Foo, Foo> for Foo {
 ///     fn shl(&self, _rhs: &Foo) -> Foo {
 ///         println!("Shifting left!");
@@ -541,6 +563,8 @@ shl_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Shr<Foo, Foo> for Foo {
 ///     fn shr(&self, _rhs: &Foo) -> Foo {
 ///         println!("Shifting right!");
@@ -580,6 +604,8 @@ shr_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64)
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Index<Foo, Foo> for Foo {
 ///     fn index<'a>(&'a self, _index: &Foo) -> &'a Foo {
 ///         println!("Indexing!");
@@ -608,6 +634,8 @@ pub trait Index<Sized? Index, Sized? Result> for Sized? {
 /// ```
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl IndexMut<Foo, Foo> for Foo {
 ///     fn index_mut<'a>(&'a mut self, _index: &Foo) -> &'a mut Foo {
 ///         println!("Indexing!");
@@ -636,6 +664,8 @@ pub trait IndexMut<Sized? Index, Sized? Result> for Sized? {
 /// ```ignore
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl Slice<Foo, Foo> for Foo {
 ///     fn as_slice_<'a>(&'a self) -> &'a Foo {
 ///         println!("Slicing!");
@@ -682,6 +712,8 @@ pub trait Slice<Sized? Idx, Sized? Result> for Sized? {
 /// ```ignore
 /// struct Foo;
 ///
+/// impl Copy for Foo {}
+///
 /// impl SliceMut<Foo, Foo> for Foo {
 ///     fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Foo {
 ///         println!("Slicing!");
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 8ba41c3575f..0a8fa28e52c 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -147,7 +147,9 @@ pub use self::Option::*;
 
 use cmp::{Eq, Ord};
 use default::Default;
-use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, ExactSizeIterator};
+use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator};
+use iter::{ExactSizeIterator};
+use kinds::Copy;
 use mem;
 use result::Result;
 use result::Result::{Ok, Err};
@@ -857,3 +859,6 @@ impl<A, V: FromIterator<A>> FromIterator<Option<A>> for Option<V> {
         }
     }
 }
+
+impl<T:Copy> Copy for Option<T> {}
+
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 3f6ac49786d..5c61a1ed103 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -437,3 +437,4 @@ impl<T> PartialOrd for *mut T {
     #[inline]
     fn ge(&self, other: &*mut T) -> bool { *self >= *other }
 }
+
diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs
index d156f71462d..db1be94b2b8 100644
--- a/src/libcore/raw.rs
+++ b/src/libcore/raw.rs
@@ -18,6 +18,7 @@
 //!
 //! Their definition should always match the ABI defined in `rustc::back::abi`.
 
+use kinds::Copy;
 use mem;
 use kinds::Sized;
 
@@ -28,6 +29,8 @@ pub struct Slice<T> {
     pub len: uint,
 }
 
+impl<T> Copy for Slice<T> {}
+
 /// The representation of a Rust closure
 #[repr(C)]
 pub struct Closure {
@@ -35,6 +38,8 @@ pub struct Closure {
     pub env: *mut (),
 }
 
+impl Copy for Closure {}
+
 /// The representation of a Rust procedure (`proc()`)
 #[repr(C)]
 pub struct Procedure {
@@ -42,6 +47,8 @@ pub struct Procedure {
     pub env: *mut (),
 }
 
+impl Copy for Procedure {}
+
 /// The representation of a Rust trait object.
 ///
 /// This struct does not have a `Repr` implementation
@@ -52,6 +59,8 @@ pub struct TraitObject {
     pub vtable: *mut (),
 }
 
+impl Copy for TraitObject {}
+
 /// This trait is meant to map equivalences between raw structs and their
 /// corresponding rust values.
 pub trait Repr<T> for Sized? {
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 0cf8e6affd7..c5d69b16987 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -232,6 +232,7 @@
 
 pub use self::Result::*;
 
+use kinds::Copy;
 use std::fmt::Show;
 use slice;
 use slice::AsSlice;
@@ -916,3 +917,7 @@ pub fn fold<T,
     }
     Ok(init)
 }
+
+#[cfg(not(stage0))]
+impl<T:Copy,U:Copy> Copy for Result<T,U> {}
+
diff --git a/src/libcore/simd.rs b/src/libcore/simd.rs
index 2b6f97cf6a5..369a7106583 100644
--- a/src/libcore/simd.rs
+++ b/src/libcore/simd.rs
@@ -37,6 +37,8 @@
 #![allow(non_camel_case_types)]
 #![allow(missing_docs)]
 
+use kinds::Copy;
+
 #[experimental]
 #[simd]
 #[deriving(Show)]
@@ -46,6 +48,8 @@ pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
                  pub i8, pub i8, pub i8, pub i8,
                  pub i8, pub i8, pub i8, pub i8);
 
+impl Copy for i8x16 {}
+
 #[experimental]
 #[simd]
 #[deriving(Show)]
@@ -53,18 +57,24 @@ pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
 pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
                  pub i16, pub i16, pub i16, pub i16);
 
+impl Copy for i16x8 {}
+
 #[experimental]
 #[simd]
 #[deriving(Show)]
 #[repr(C)]
 pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
 
+impl Copy for i32x4 {}
+
 #[experimental]
 #[simd]
 #[deriving(Show)]
 #[repr(C)]
 pub struct i64x2(pub i64, pub i64);
 
+impl Copy for i64x2 {}
+
 #[experimental]
 #[simd]
 #[deriving(Show)]
@@ -74,6 +84,8 @@ pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
                  pub u8, pub u8, pub u8, pub u8,
                  pub u8, pub u8, pub u8, pub u8);
 
+impl Copy for u8x16 {}
+
 #[experimental]
 #[simd]
 #[deriving(Show)]
@@ -81,26 +93,37 @@ pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
 pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
                  pub u16, pub u16, pub u16, pub u16);
 
+impl Copy for u16x8 {}
+
 #[experimental]
 #[simd]
 #[deriving(Show)]
 #[repr(C)]
 pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
 
+impl Copy for u32x4 {}
+
 #[experimental]
 #[simd]
 #[deriving(Show)]
 #[repr(C)]
 pub struct u64x2(pub u64, pub u64);
 
+impl Copy for u64x2 {}
+
 #[experimental]
 #[simd]
 #[deriving(Show)]
 #[repr(C)]
 pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
 
+impl Copy for f32x4 {}
+
 #[experimental]
 #[simd]
 #[deriving(Show)]
 #[repr(C)]
 pub struct f64x2(pub f64, pub f64);
+
+impl Copy for f64x2 {}
+
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index b8df36c91bc..4e3007b55fe 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -41,6 +41,7 @@ use cmp::Ordering::{Less, Equal, Greater};
 use cmp;
 use default::Default;
 use iter::*;
+use kinds::Copy;
 use num::Int;
 use ops;
 use option::Option;
@@ -1157,6 +1158,8 @@ impl<'a, T> Items<'a, T> {
     }
 }
 
+impl<'a,T> Copy for Items<'a,T> {}
+
 iterator!{struct Items -> *const T, &'a T}
 
 #[experimental = "needs review"]
@@ -1607,6 +1610,8 @@ pub enum BinarySearchResult {
     NotFound(uint)
 }
 
+impl Copy for BinarySearchResult {}
+
 #[experimental = "needs review"]
 impl BinarySearchResult {
     /// Converts a `Found` to `Some`, `NotFound` to `None`.
@@ -1920,3 +1925,4 @@ impl_int_slice!(u16,  i16)
 impl_int_slice!(u32,  i32)
 impl_int_slice!(u64,  i64)
 impl_int_slice!(uint, int)
+
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index 1d59567cbe4..8f9eeaddfb5 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -26,7 +26,7 @@ use default::Default;
 use iter::{Map, Iterator, IteratorExt, DoubleEndedIterator};
 use iter::{DoubleEndedIteratorExt, ExactSizeIterator};
 use iter::range;
-use kinds::Sized;
+use kinds::{Copy, Sized};
 use mem;
 use num::Int;
 use option::Option;
@@ -176,6 +176,8 @@ pub struct Chars<'a> {
     iter: slice::Items<'a, u8>
 }
 
+impl<'a> Copy for Chars<'a> {}
+
 // Return the initial codepoint accumulator for the first byte.
 // The first byte is special, only want bottom 5 bits for width 2, 4 bits
 // for width 3, and 3 bits for width 4
@@ -996,6 +998,8 @@ pub enum Utf16Item {
     LoneSurrogate(u16)
 }
 
+impl Copy for Utf16Item {}
+
 impl Utf16Item {
     /// Convert `self` to a `char`, taking `LoneSurrogate`s to the
     /// replacement character (U+FFFD).
@@ -1139,6 +1143,8 @@ pub struct CharRange {
     pub next: uint,
 }
 
+impl Copy for CharRange {}
+
 /// Mask of the value bits of a continuation byte
 const CONT_MASK: u8 = 0b0011_1111u8;
 /// Value of the tag bits (tag mask is !CONT_MASK) of a continuation byte
@@ -2315,3 +2321,4 @@ impl StrPrelude for str {
 impl<'a> Default for &'a str {
     fn default() -> &'a str { "" }
 }
+