about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/compiletest/common.rs2
-rw-r--r--src/doc/guide-unsafe.md3
-rw-r--r--src/doc/reference.md4
-rw-r--r--src/libarena/lib.rs2
-rw-r--r--src/libcollections/binary_heap.rs2
-rw-r--r--src/libcollections/dlist.rs9
-rw-r--r--src/libcollections/enum_set.rs7
-rw-r--r--src/libcollections/hash/sip.rs3
-rw-r--r--src/libcollections/slice.rs16
-rw-r--r--src/libcollections/str.rs34
-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
-rw-r--r--src/libfmt_macros/lib.rs14
-rw-r--r--src/libgetopts/lib.rs26
-rw-r--r--src/liblibc/lib.rs248
-rw-r--r--src/liblog/lib.rs4
-rw-r--r--src/librand/chacha.rs2
-rw-r--r--src/librand/distributions/exponential.rs5
-rw-r--r--src/librand/distributions/normal.rs7
-rw-r--r--src/librand/isaac.rs5
-rw-r--r--src/librand/lib.rs12
-rw-r--r--src/librand/reseeding.rs2
-rw-r--r--src/librbml/lib.rs6
-rw-r--r--src/libregex/parse.rs2
-rw-r--r--src/libregex/re.rs8
-rw-r--r--src/libregex/vm.rs4
-rw-r--r--src/librustc/lint/builtin.rs102
-rw-r--r--src/librustc/lint/context.rs1
-rw-r--r--src/librustc/lint/mod.rs8
-rw-r--r--src/librustc/metadata/common.rs2
-rw-r--r--src/librustc/metadata/creader.rs6
-rw-r--r--src/librustc/metadata/csearch.rs7
-rw-r--r--src/librustc/metadata/cstore.rs17
-rw-r--r--src/librustc/metadata/decoder.rs6
-rw-r--r--src/librustc/metadata/filesearch.rs7
-rw-r--r--src/librustc/metadata/tydecode.rs2
-rw-r--r--src/librustc/middle/borrowck/check_loans.rs14
-rw-r--r--src/librustc/middle/borrowck/gather_loans/mod.rs12
-rw-r--r--src/librustc/middle/borrowck/graphviz.rs2
-rw-r--r--src/librustc/middle/borrowck/mod.rs37
-rw-r--r--src/librustc/middle/borrowck/move_data.rs16
-rw-r--r--src/librustc/middle/cfg/construct.rs2
-rw-r--r--src/librustc/middle/cfg/mod.rs2
-rw-r--r--src/librustc/middle/check_loop.rs4
-rw-r--r--src/librustc/middle/check_match.rs26
-rw-r--r--src/librustc/middle/check_rvalues.rs6
-rw-r--r--src/librustc/middle/check_static.rs10
-rw-r--r--src/librustc/middle/const_eval.rs2
-rw-r--r--src/librustc/middle/dataflow.rs7
-rw-r--r--src/librustc/middle/def.rs4
-rw-r--r--src/librustc/middle/effect.rs2
-rw-r--r--src/librustc/middle/expr_use_visitor.rs69
-rw-r--r--src/librustc/middle/fast_reject.rs2
-rw-r--r--src/librustc/middle/graph.rs6
-rw-r--r--src/librustc/middle/infer/mod.rs6
-rw-r--r--src/librustc/middle/infer/region_inference/mod.rs16
-rw-r--r--src/librustc/middle/infer/type_variable.rs2
-rw-r--r--src/librustc/middle/infer/unify.rs2
-rw-r--r--src/librustc/middle/lang_items.rs2
-rw-r--r--src/librustc/middle/liveness.rs15
-rw-r--r--src/librustc/middle/mem_categorization.rs22
-rw-r--r--src/librustc/middle/region.rs4
-rw-r--r--src/librustc/middle/resolve.rs40
-rw-r--r--src/librustc/middle/resolve_lifetime.rs2
-rw-r--r--src/librustc/middle/subst.rs2
-rw-r--r--src/librustc/middle/traits/mod.rs8
-rw-r--r--src/librustc/middle/traits/select.rs29
-rw-r--r--src/librustc/middle/ty.rs229
-rw-r--r--src/librustc/session/config.rs12
-rw-r--r--src/librustc/util/common.rs2
-rw-r--r--src/librustc/util/nodemap.rs3
-rw-r--r--src/librustc_driver/pretty.rs4
-rw-r--r--src/librustc_llvm/diagnostic.rs6
-rw-r--r--src/librustc_llvm/lib.rs65
-rw-r--r--src/librustc_trans/back/write.rs11
-rw-r--r--src/librustc_trans/save/mod.rs2
-rw-r--r--src/librustc_trans/save/recorder.rs7
-rw-r--r--src/librustc_trans/save/span_utils.rs1
-rw-r--r--src/librustc_trans/trans/_match.rs27
-rw-r--r--src/librustc_trans/trans/adt.rs5
-rw-r--r--src/librustc_trans/trans/base.rs24
-rw-r--r--src/librustc_trans/trans/basic_block.rs2
-rw-r--r--src/librustc_trans/trans/cabi.rs4
-rw-r--r--src/librustc_trans/trans/cabi_x86_64.rs2
-rw-r--r--src/librustc_trans/trans/callee.rs4
-rw-r--r--src/librustc_trans/trans/cleanup.rs18
-rw-r--r--src/librustc_trans/trans/closure.rs2
-rw-r--r--src/librustc_trans/trans/common.rs9
-rw-r--r--src/librustc_trans/trans/datum.rs24
-rw-r--r--src/librustc_trans/trans/debuginfo.rs6
-rw-r--r--src/librustc_trans/trans/expr.rs4
-rw-r--r--src/librustc_trans/trans/mod.rs2
-rw-r--r--src/librustc_trans/trans/tvec.rs4
-rw-r--r--src/librustc_trans/trans/type_.rs2
-rw-r--r--src/librustc_trans/trans/type_of.rs5
-rw-r--r--src/librustc_trans/trans/value.rs10
-rw-r--r--src/librustc_typeck/check/method/mod.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs8
-rw-r--r--src/librustc_typeck/check/wf.rs5
-rw-r--r--src/librustc_typeck/check/writeback.rs2
-rw-r--r--src/librustc_typeck/coherence/mod.rs80
-rw-r--r--src/librustc_typeck/collect.rs2
-rw-r--r--src/librustc_typeck/rscope.rs3
-rw-r--r--src/librustc_typeck/variance.rs10
-rw-r--r--src/librustdoc/clean/mod.rs6
-rw-r--r--src/librustdoc/doctree.rs2
-rw-r--r--src/librustdoc/html/format.rs5
-rw-r--r--src/librustdoc/html/item_type.rs2
-rw-r--r--src/librustdoc/html/render.rs8
-rw-r--r--src/librustdoc/stability_summary.rs2
-rw-r--r--src/librustrt/bookkeeping.rs1
-rw-r--r--src/librustrt/c_str.rs1
-rw-r--r--src/librustrt/mutex.rs12
-rw-r--r--src/librustrt/unwind.rs1
-rw-r--r--src/librustrt/util.rs3
-rw-r--r--src/libserialize/base64.rs6
-rw-r--r--src/libserialize/hex.rs2
-rw-r--r--src/libserialize/json.rs4
-rw-r--r--src/libstd/ascii.rs3
-rw-r--r--src/libstd/bitflags.rs9
-rw-r--r--src/libstd/collections/hash/table.rs6
-rw-r--r--src/libstd/comm/mod.rs2
-rw-r--r--src/libstd/dynamic_lib.rs8
-rw-r--r--src/libstd/io/mod.rs17
-rw-r--r--src/libstd/io/net/addrinfo.rs11
-rw-r--r--src/libstd/io/net/ip.rs5
-rw-r--r--src/libstd/io/process.rs4
-rw-r--r--src/libstd/io/util.rs6
-rw-r--r--src/libstd/num/strconv.rs51
-rw-r--r--src/libstd/os.rs12
-rw-r--r--src/libstd/path/windows.rs3
-rw-r--r--src/libstd/rand/mod.rs7
-rw-r--r--src/libstd/time/duration.rs3
-rw-r--r--src/libsyntax/abi.rs22
-rw-r--r--src/libsyntax/ast.rs65
-rw-r--r--src/libsyntax/ast_map/blocks.rs4
-rw-r--r--src/libsyntax/ast_map/mod.rs6
-rw-r--r--src/libsyntax/ast_util.rs2
-rw-r--r--src/libsyntax/attr.rs8
-rw-r--r--src/libsyntax/codemap.rs14
-rw-r--r--src/libsyntax/diagnostic.rs10
-rw-r--r--src/libsyntax/ext/base.rs10
-rw-r--r--src/libsyntax/ext/deriving/cmp/ord.rs2
-rw-r--r--src/libsyntax/ext/mtwt.rs2
-rw-r--r--src/libsyntax/feature_gate.rs2
-rw-r--r--src/libsyntax/parse/lexer/comments.rs2
-rw-r--r--src/libsyntax/parse/obsolete.rs2
-rw-r--r--src/libsyntax/parse/parser.rs4
-rw-r--r--src/libsyntax/parse/token.rs12
-rw-r--r--src/libsyntax/print/pp.rs10
-rw-r--r--src/libsyntax/print/pprust.rs4
-rw-r--r--src/libsyntax/visit.rs2
-rw-r--r--src/libterm/lib.rs3
-rw-r--r--src/libterm/terminfo/parm.rs8
-rw-r--r--src/libtest/lib.rs19
-rw-r--r--src/libtime/lib.rs12
-rw-r--r--src/libunicode/tables.rs3
-rw-r--r--src/test/auxiliary/issue-14422.rs2
-rw-r--r--src/test/auxiliary/issue13213aux.rs4
-rw-r--r--src/test/auxiliary/lang-item-public.rs5
-rw-r--r--src/test/auxiliary/method_self_arg1.rs2
-rw-r--r--src/test/auxiliary/method_self_arg2.rs2
-rw-r--r--src/test/auxiliary/xcrate_unit_struct.rs11
-rw-r--r--src/test/bench/noise.rs2
-rw-r--r--src/test/bench/shootout-chameneos-redux.rs11
-rw-r--r--src/test/bench/shootout-fannkuch-redux.rs4
-rw-r--r--src/test/bench/shootout-fasta-redux.rs2
-rw-r--r--src/test/bench/shootout-k-nucleotide.rs2
-rw-r--r--src/test/bench/shootout-nbody.rs2
-rw-r--r--src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs4
-rw-r--r--src/test/compile-fail/borrowck-borrow-from-stack-variable.rs4
-rw-r--r--src/test/compile-fail/borrowck-loan-local-as-both-mut-and-imm.rs35
-rw-r--r--src/test/compile-fail/borrowck-use-mut-borrow.rs3
-rw-r--r--src/test/compile-fail/dst-index.rs7
-rw-r--r--src/test/compile-fail/dst-rvalue.rs2
-rw-r--r--src/test/compile-fail/issue-17651.rs3
-rw-r--r--src/test/compile-fail/kindck-copy.rs3
-rw-r--r--src/test/compile-fail/lint-dead-code-1.rs1
-rw-r--r--src/test/compile-fail/lint-missing-doc.rs1
-rw-r--r--src/test/compile-fail/opt-in-copy.rs33
-rw-r--r--src/test/compile-fail/stage0-clone-contravariant-lifetime.rs43
-rw-r--r--src/test/compile-fail/stage0-cmp.rs39
-rw-r--r--src/test/debuginfo/c-style-enum.rs3
-rw-r--r--src/test/debuginfo/generic-method-on-generic-struct.rs3
-rw-r--r--src/test/debuginfo/method-on-enum.rs3
-rw-r--r--src/test/debuginfo/method-on-generic-struct.rs3
-rw-r--r--src/test/debuginfo/method-on-struct.rs3
-rw-r--r--src/test/debuginfo/method-on-trait.rs3
-rw-r--r--src/test/debuginfo/method-on-tuple-struct.rs3
-rw-r--r--src/test/debuginfo/self-in-default-method.rs3
-rw-r--r--src/test/debuginfo/self-in-generic-default-method.rs3
-rw-r--r--src/test/pretty/block-disambig.rs2
-rw-r--r--src/test/run-make/extern-fn-with-packed-struct/test.rs2
-rw-r--r--src/test/run-make/target-specs/foo.rs3
-rw-r--r--src/test/run-pass/borrowck-univariant-enum.rs2
-rw-r--r--src/test/run-pass/builtin-superkinds-in-metadata.rs8
-rw-r--r--src/test/run-pass/cell-does-not-clone.rs2
-rw-r--r--src/test/run-pass/class-impl-very-parameterized-trait.rs2
-rw-r--r--src/test/run-pass/coherence-impl-in-fn.rs1
-rw-r--r--src/test/run-pass/coherence-where-clause.rs2
-rw-r--r--src/test/run-pass/const-nullary-univariant-enum.rs2
-rw-r--r--src/test/run-pass/dst-struct-sole.rs2
-rw-r--r--src/test/run-pass/dst-struct.rs2
-rw-r--r--src/test/run-pass/dst-trait.rs4
-rw-r--r--src/test/run-pass/empty-tag.rs2
-rw-r--r--src/test/run-pass/enum-discrim-width-stuff.rs1
-rw-r--r--src/test/run-pass/explicit-self-generic.rs4
-rw-r--r--src/test/run-pass/export-unexported-dep.rs2
-rw-r--r--src/test/run-pass/expr-copy.rs2
-rw-r--r--src/test/run-pass/expr-if-struct.rs4
-rw-r--r--src/test/run-pass/expr-match-struct.rs4
-rw-r--r--src/test/run-pass/exterior.rs2
-rw-r--r--src/test/run-pass/extern-pass-TwoU16s.rs2
-rw-r--r--src/test/run-pass/extern-pass-TwoU32s.rs2
-rw-r--r--src/test/run-pass/extern-pass-TwoU64s.rs2
-rw-r--r--src/test/run-pass/extern-pass-TwoU8s.rs2
-rw-r--r--src/test/run-pass/foreign-fn-with-byval.rs2
-rw-r--r--src/test/run-pass/generic-fn.rs2
-rw-r--r--src/test/run-pass/guards-not-exhaustive.rs2
-rw-r--r--src/test/run-pass/guards.rs2
-rw-r--r--src/test/run-pass/issue-12860.rs2
-rw-r--r--src/test/run-pass/issue-19100.rs2
-rw-r--r--src/test/run-pass/issue-2288.rs3
-rw-r--r--src/test/run-pass/issue-2633.rs4
-rw-r--r--src/test/run-pass/issue-3121.rs4
-rw-r--r--src/test/run-pass/issue-3563-3.rs6
-rw-r--r--src/test/run-pass/issue-3743.rs2
-rw-r--r--src/test/run-pass/issue-3753.rs4
-rw-r--r--src/test/run-pass/issue-5688.rs4
-rw-r--r--src/test/run-pass/lang-item-public.rs1
-rw-r--r--src/test/run-pass/match-arm-statics.rs2
-rw-r--r--src/test/run-pass/method-self-arg-trait.rs2
-rw-r--r--src/test/run-pass/method-self-arg.rs2
-rw-r--r--src/test/run-pass/monomorphize-abi-alignment.rs15
-rw-r--r--src/test/run-pass/multidispatch1.rs2
-rw-r--r--src/test/run-pass/multidispatch2.rs2
-rw-r--r--src/test/run-pass/newtype.rs9
-rw-r--r--src/test/run-pass/out-pointer-aliasing.rs2
-rw-r--r--src/test/run-pass/overloaded-autoderef-order.rs4
-rw-r--r--src/test/run-pass/packed-struct-vec.rs2
-rw-r--r--src/test/run-pass/rec-tup.rs2
-rw-r--r--src/test/run-pass/rec.rs2
-rw-r--r--src/test/run-pass/regions-dependent-addr-of.rs2
-rw-r--r--src/test/run-pass/regions-early-bound-used-in-bound-method.rs2
-rw-r--r--src/test/run-pass/regions-early-bound-used-in-bound.rs2
-rw-r--r--src/test/run-pass/regions-early-bound-used-in-type-param.rs2
-rw-r--r--src/test/run-pass/regions-mock-tcx.rs9
-rw-r--r--src/test/run-pass/self-in-mut-slot-immediate-value.rs2
-rw-r--r--src/test/run-pass/shape_intrinsic_tag_then_rec.rs67
-rw-r--r--src/test/run-pass/simd-generics.rs2
-rw-r--r--src/test/run-pass/small-enum-range-edge.rs6
-rw-r--r--src/test/run-pass/struct-return.rs5
-rw-r--r--src/test/run-pass/structured-compare.rs2
-rw-r--r--src/test/run-pass/tag-variant-disr-val.rs2
-rw-r--r--src/test/run-pass/trait-coercion-generic.rs2
-rw-r--r--src/test/run-pass/trait-coercion.rs2
-rw-r--r--src/test/run-pass/typeclasses-eq-example-static.rs11
-rw-r--r--src/test/run-pass/typeclasses-eq-example.rs8
-rw-r--r--src/test/run-pass/ufcs-explicit-self.rs4
-rw-r--r--src/test/run-pass/unboxed-closures-monomorphization.rs3
277 files changed, 2182 insertions, 513 deletions
diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs
index 0a902d970ef..62b757529dc 100644
--- a/src/compiletest/common.rs
+++ b/src/compiletest/common.rs
@@ -25,6 +25,8 @@ pub enum Mode {
     Codegen
 }
 
+impl Copy for Mode {}
+
 impl FromStr for Mode {
     fn from_str(s: &str) -> Option<Mode> {
         match s {
diff --git a/src/doc/guide-unsafe.md b/src/doc/guide-unsafe.md
index 5b248126c80..bda1b345632 100644
--- a/src/doc/guide-unsafe.md
+++ b/src/doc/guide-unsafe.md
@@ -661,6 +661,9 @@ extern {
     fn abort() -> !;
 }
 
+#[lang = "owned_box"]
+pub struct Box<T>(*mut T);
+
 #[lang="exchange_malloc"]
 unsafe fn allocate(size: uint, _align: uint) -> *mut u8 {
     let p = libc::malloc(size as libc::size_t) as *mut u8;
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 9ac4469d549..f6ee5cadbc6 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -1660,6 +1660,7 @@ Implementations are defined with the keyword `impl`.
 
 ```
 # struct Point {x: f64, y: f64};
+# impl Copy for Point {}
 # type Surface = int;
 # struct BoundingBox {x: f64, y: f64, width: f64, height: f64};
 # trait Shape { fn draw(&self, Surface); fn bounding_box(&self) -> BoundingBox; }
@@ -1669,6 +1670,8 @@ struct Circle {
     center: Point,
 }
 
+impl Copy for Circle {}
+
 impl Shape for Circle {
     fn draw(&self, s: Surface) { do_draw_circle(s, *self); }
     fn bounding_box(&self) -> BoundingBox {
@@ -1791,6 +1794,7 @@ default visibility with the `priv` keyword. When an item is declared as `pub`,
 it can be thought of as being accessible to the outside world. For example:
 
 ```
+# #![allow(missing_copy_implementations)]
 # fn main() {}
 // Declare a private struct
 struct Foo;
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index 8b84ecb6904..95c4dff323e 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -466,7 +466,7 @@ impl<T> TypedArena<T> {
         }
 
         let ptr: &mut T = unsafe {
-            let ptr: &mut T = mem::transmute(self.ptr);
+            let ptr: &mut T = mem::transmute(self.ptr.clone());
             ptr::write(ptr, object);
             self.ptr.set(self.ptr.get().offset(1));
             ptr
diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs
index e321ef16f66..a4722c340dd 100644
--- a/src/libcollections/binary_heap.rs
+++ b/src/libcollections/binary_heap.rs
@@ -35,6 +35,8 @@
 //!     position: uint
 //! }
 //!
+//! impl Copy for State {}
+//!
 //! // The priority queue depends on `Ord`.
 //! // Explicitly implement the trait so the queue becomes a min-heap
 //! // instead of a max-heap.
diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs
index a30bb9e978b..4309e96bec4 100644
--- a/src/libcollections/dlist.rs
+++ b/src/libcollections/dlist.rs
@@ -39,7 +39,12 @@ pub struct DList<T> {
 }
 
 type Link<T> = Option<Box<Node<T>>>;
-struct Rawlink<T> { p: *mut T }
+
+struct Rawlink<T> {
+    p: *mut T,
+}
+
+impl<T> Copy for Rawlink<T> {}
 
 struct Node<T> {
     next: Link<T>,
@@ -59,6 +64,8 @@ impl<'a, T> Clone for Items<'a, T> {
     fn clone(&self) -> Items<'a, T> { *self }
 }
 
+impl<'a,T> Copy for Items<'a,T> {}
+
 /// An iterator over mutable references to the items of a `DList`.
 pub struct MutItems<'a, T:'a> {
     list: &'a mut DList<T>,
diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs
index 5e77cf66726..28514b99192 100644
--- a/src/libcollections/enum_set.rs
+++ b/src/libcollections/enum_set.rs
@@ -27,6 +27,8 @@ pub struct EnumSet<E> {
     bits: uint
 }
 
+impl<E> Copy for EnumSet<E> {}
+
 impl<E:CLike+fmt::Show> fmt::Show for EnumSet<E> {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(fmt, "{{"));
@@ -269,6 +271,8 @@ mod test {
         A, B, C
     }
 
+    impl Copy for Foo {}
+
     impl CLike for Foo {
         fn to_uint(&self) -> uint {
             *self as uint
@@ -477,6 +481,9 @@ mod test {
             V50, V51, V52, V53, V54, V55, V56, V57, V58, V59,
             V60, V61, V62, V63, V64, V65, V66, V67, V68, V69,
         }
+
+        impl Copy for Bar {}
+
         impl CLike for Bar {
             fn to_uint(&self) -> uint {
                 *self as uint
diff --git a/src/libcollections/hash/sip.rs b/src/libcollections/hash/sip.rs
index ab69a3ad8b8..9a7aa8c20d3 100644
--- a/src/libcollections/hash/sip.rs
+++ b/src/libcollections/hash/sip.rs
@@ -43,6 +43,8 @@ pub struct SipState {
     ntail: uint,  // how many bytes in tail are valid
 }
 
+impl Copy for SipState {}
+
 // sadly, these macro definitions can't appear later,
 // because they're needed in the following defs;
 // this design could be improved.
@@ -211,6 +213,7 @@ impl Default for SipState {
 
 /// `SipHasher` computes the SipHash algorithm from a stream of bytes.
 #[deriving(Clone)]
+#[allow(missing_copy_implementations)]
 pub struct SipHasher {
     k0: u64,
     k1: u64,
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 03b8ea8f20f..c230c48d222 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -91,7 +91,7 @@ use self::Direction::*;
 use alloc::boxed::Box;
 use core::borrow::{BorrowFrom, BorrowFromMut, ToOwned};
 use core::cmp;
-use core::kinds::Sized;
+use core::kinds::{Copy, Sized};
 use core::mem::size_of;
 use core::mem;
 use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option};
@@ -177,12 +177,16 @@ impl ElementSwaps {
 
 enum Direction { Pos, Neg }
 
+impl Copy for Direction {}
+
 /// An `Index` and `Direction` together.
 struct SizeDirection {
     size: uint,
     dir: Direction,
 }
 
+impl Copy for SizeDirection {}
+
 impl Iterator<(uint, uint)> for ElementSwaps {
     #[inline]
     fn next(&mut self) -> Option<(uint, uint)> {
@@ -1482,11 +1486,17 @@ mod tests {
             fn clone(&self) -> S {
                 self.f.set(self.f.get() + 1);
                 if self.f.get() == 10 { panic!() }
-                S { f: self.f, boxes: self.boxes.clone() }
+                S {
+                    f: self.f.clone(),
+                    boxes: self.boxes.clone(),
+                }
             }
         }
 
-        let s = S { f: Cell::new(0), boxes: (box 0, Rc::new(0)) };
+        let s = S {
+            f: Cell::new(0),
+            boxes: (box 0, Rc::new(0)),
+        };
         let _ = Vec::from_elem(100, s);
     }
 
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index 28027198143..419d7f270ad 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -228,24 +228,32 @@ impl<'a> Iterator<char> for Decompositions<'a> {
             _ => self.sorted = false
         }
 
-        let decomposer = match self.kind {
-            Canonical => unicode::char::decompose_canonical,
-            Compatible => unicode::char::decompose_compatible
-        };
-
         if !self.sorted {
             for ch in self.iter {
                 let buffer = &mut self.buffer;
                 let sorted = &mut self.sorted;
-                decomposer(ch, |d| {
-                    let class = unicode::char::canonical_combining_class(d);
-                    if class == 0 && !*sorted {
-                        canonical_sort(buffer.as_mut_slice());
-                        *sorted = true;
+                {
+                    let callback = |d| {
+                        let class =
+                            unicode::char::canonical_combining_class(d);
+                        if class == 0 && !*sorted {
+                            canonical_sort(buffer.as_mut_slice());
+                            *sorted = true;
+                        }
+                        buffer.push((d, class));
+                    };
+                    match self.kind {
+                        Canonical => {
+                            unicode::char::decompose_canonical(ch, callback)
+                        }
+                        Compatible => {
+                            unicode::char::decompose_compatible(ch, callback)
+                        }
                     }
-                    buffer.push((d, class));
-                });
-                if *sorted { break }
+                }
+                if *sorted {
+                    break
+                }
             }
         }
 
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 { "" }
 }
+
diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs
index d88551eb855..db389457a1e 100644
--- a/src/libfmt_macros/lib.rs
+++ b/src/libfmt_macros/lib.rs
@@ -44,6 +44,8 @@ pub enum Piece<'a> {
     NextArgument(Argument<'a>),
 }
 
+impl<'a> Copy for Piece<'a> {}
+
 /// Representation of an argument specification.
 #[deriving(PartialEq)]
 pub struct Argument<'a> {
@@ -53,6 +55,8 @@ pub struct Argument<'a> {
     pub format: FormatSpec<'a>,
 }
 
+impl<'a> Copy for Argument<'a> {}
+
 /// Specification for the formatting of an argument in the format string.
 #[deriving(PartialEq)]
 pub struct FormatSpec<'a> {
@@ -72,6 +76,8 @@ pub struct FormatSpec<'a> {
     pub ty: &'a str
 }
 
+impl<'a> Copy for FormatSpec<'a> {}
+
 /// Enum describing where an argument for a format can be located.
 #[deriving(PartialEq)]
 pub enum Position<'a> {
@@ -83,6 +89,8 @@ pub enum Position<'a> {
     ArgumentNamed(&'a str),
 }
 
+impl<'a> Copy for Position<'a> {}
+
 /// Enum of alignments which are supported.
 #[deriving(PartialEq)]
 pub enum Alignment {
@@ -96,6 +104,8 @@ pub enum Alignment {
     AlignUnknown,
 }
 
+impl Copy for Alignment {}
+
 /// Various flags which can be applied to format strings. The meaning of these
 /// flags is defined by the formatters themselves.
 #[deriving(PartialEq)]
@@ -112,6 +122,8 @@ pub enum Flag {
     FlagSignAwareZeroPad,
 }
 
+impl Copy for Flag {}
+
 /// A count is used for the precision and width parameters of an integer, and
 /// can reference either an argument or a literal integer.
 #[deriving(PartialEq)]
@@ -128,6 +140,8 @@ pub enum Count<'a> {
     CountImplied,
 }
 
+impl<'a> Copy for Count<'a> {}
+
 /// The parser structure for interpreting the input format string. This is
 /// modelled as an iterator over `Piece` structures to form a stream of tokens
 /// being output.
diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs
index ffcc0eb22f6..9174f8e8456 100644
--- a/src/libgetopts/lib.rs
+++ b/src/libgetopts/lib.rs
@@ -97,6 +97,9 @@ use self::HasArg::*;
 use self::Occur::*;
 use self::Fail::*;
 use self::Optval::*;
+use self::SplitWithinState::*;
+use self::Whitespace::*;
+use self::LengthLimit::*;
 
 use std::fmt;
 use std::result::Result::{Err, Ok};
@@ -125,6 +128,8 @@ pub enum HasArg {
     Maybe,
 }
 
+impl Copy for HasArg {}
+
 /// Describes how often an option may occur.
 #[deriving(Clone, PartialEq, Eq)]
 pub enum Occur {
@@ -136,6 +141,8 @@ pub enum Occur {
     Multi,
 }
 
+impl Copy for Occur {}
+
 /// A description of a possible option.
 #[deriving(Clone, PartialEq, Eq)]
 pub struct Opt {
@@ -203,6 +210,19 @@ pub enum Fail {
     UnexpectedArgument(String),
 }
 
+/// The type of failure that occurred.
+#[deriving(PartialEq, Eq)]
+#[allow(missing_docs)]
+pub enum FailType {
+    ArgumentMissing_,
+    UnrecognizedOption_,
+    OptionMissing_,
+    OptionDuplicated_,
+    UnexpectedArgument_,
+}
+
+impl Copy for FailType {}
+
 /// The result of parsing a command line with a set of options.
 pub type Result = result::Result<Matches, Fail>;
 
@@ -824,14 +844,17 @@ enum SplitWithinState {
     B,  // words
     C,  // internal and trailing whitespace
 }
+impl Copy for SplitWithinState {}
 enum Whitespace {
     Ws, // current char is whitespace
     Cr  // current char is not whitespace
 }
+impl Copy for Whitespace {}
 enum LengthLimit {
     UnderLim, // current char makes current substring still fit in limit
     OverLim   // current char makes current substring no longer fit in limit
 }
+impl Copy for LengthLimit {}
 
 
 /// Splits a string into substrings with possibly internal whitespace,
@@ -847,9 +870,6 @@ enum LengthLimit {
 /// sequence longer than the limit.
 fn each_split_within<'a>(ss: &'a str, lim: uint, it: |&'a str| -> bool)
                      -> bool {
-    use self::SplitWithinState::*;
-    use self::Whitespace::*;
-    use self::LengthLimit::*;
     // Just for fun, let's write this as a state machine:
 
     let mut slice_start = 0;
diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs
index 18e9d832c00..8825099e36c 100644
--- a/src/liblibc/lib.rs
+++ b/src/liblibc/lib.rs
@@ -76,6 +76,7 @@
 #![allow(non_upper_case_globals)]
 #![allow(missing_docs)]
 #![allow(non_snake_case)]
+#![allow(raw_pointer_deriving)]
 
 extern crate core;
 
@@ -340,12 +341,15 @@ pub mod types {
             /// variants, because the compiler complains about the repr attribute
             /// otherwise.
             #[repr(u8)]
+            #[allow(missing_copy_implementations)]
             pub enum c_void {
                 __variant1,
                 __variant2,
             }
 
+            #[allow(missing_copy_implementations)]
             pub enum FILE {}
+            #[allow(missing_copy_implementations)]
             pub enum fpos_t {}
         }
         pub mod c99 {
@@ -359,7 +363,9 @@ pub mod types {
             pub type uint64_t = u64;
         }
         pub mod posix88 {
+            #[allow(missing_copy_implementations)]
             pub enum DIR {}
+            #[allow(missing_copy_implementations)]
             pub enum dirent_t {}
         }
         pub mod posix01 {}
@@ -380,7 +386,7 @@ pub mod types {
                 pub type pthread_t = c_ulong;
 
                 #[repr(C)]
-                pub struct glob_t {
+                #[deriving(Copy)] pub struct glob_t {
                     pub gl_pathc: size_t,
                     pub gl_pathv: *mut *mut c_char,
                     pub gl_offs:  size_t,
@@ -393,18 +399,18 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                pub struct timeval {
+                #[deriving(Copy)] pub struct timeval {
                     pub tv_sec: time_t,
                     pub tv_usec: suseconds_t,
                 }
 
                 #[repr(C)]
-                pub struct timespec {
+                #[deriving(Copy)] pub struct timespec {
                     pub tv_sec: time_t,
                     pub tv_nsec: c_long,
                 }
 
-                pub enum timezone {}
+                #[deriving(Copy)] pub enum timezone {}
 
                 pub type sighandler_t = size_t;
             }
@@ -417,29 +423,29 @@ pub mod types {
                 pub type in_port_t = u16;
                 pub type in_addr_t = u32;
                 #[repr(C)]
-                pub struct sockaddr {
+                #[deriving(Copy)] pub struct sockaddr {
                     pub sa_family: sa_family_t,
                     pub sa_data: [u8, ..14],
                 }
                 #[repr(C)]
-                pub struct sockaddr_storage {
+                #[deriving(Copy)] pub struct sockaddr_storage {
                     pub ss_family: sa_family_t,
                     pub __ss_align: i64,
                     pub __ss_pad2: [u8, ..112],
                 }
                 #[repr(C)]
-                pub struct sockaddr_in {
+                #[deriving(Copy)] pub struct sockaddr_in {
                     pub sin_family: sa_family_t,
                     pub sin_port: in_port_t,
                     pub sin_addr: in_addr,
                     pub sin_zero: [u8, ..8],
                 }
                 #[repr(C)]
-                pub struct in_addr {
+                #[deriving(Copy)] pub struct in_addr {
                     pub s_addr: in_addr_t,
                 }
                 #[repr(C)]
-                pub struct sockaddr_in6 {
+                #[deriving(Copy)] pub struct sockaddr_in6 {
                     pub sin6_family: sa_family_t,
                     pub sin6_port: in_port_t,
                     pub sin6_flowinfo: u32,
@@ -447,21 +453,21 @@ pub mod types {
                     pub sin6_scope_id: u32,
                 }
                 #[repr(C)]
-                pub struct in6_addr {
+                #[deriving(Copy)] pub struct in6_addr {
                     pub s6_addr: [u16, ..8]
                 }
                 #[repr(C)]
-                pub struct ip_mreq {
+                #[deriving(Copy)] pub struct ip_mreq {
                     pub imr_multiaddr: in_addr,
                     pub imr_interface: in_addr,
                 }
                 #[repr(C)]
-                pub struct ip6_mreq {
+                #[deriving(Copy)] pub struct ip6_mreq {
                     pub ipv6mr_multiaddr: in6_addr,
                     pub ipv6mr_interface: c_uint,
                 }
                 #[repr(C)]
-                pub struct addrinfo {
+                #[deriving(Copy)] pub struct addrinfo {
                     pub ai_flags: c_int,
                     pub ai_family: c_int,
                     pub ai_socktype: c_int,
@@ -483,13 +489,13 @@ pub mod types {
                     pub ai_next: *mut addrinfo,
                 }
                 #[repr(C)]
-                pub struct sockaddr_un {
+                #[deriving(Copy)] pub struct sockaddr_un {
                     pub sun_family: sa_family_t,
                     pub sun_path: [c_char, ..108]
                 }
 
                 #[repr(C)]
-                pub struct ifaddrs {
+                #[deriving(Copy)] pub struct ifaddrs {
                     pub ifa_next: *mut ifaddrs,
                     pub ifa_name: *mut c_char,
                     pub ifa_flags: c_uint,
@@ -572,7 +578,7 @@ pub mod types {
                 pub type blkcnt_t = i32;
 
                 #[repr(C)]
-                pub struct stat {
+                #[deriving(Copy)] pub struct stat {
                     pub st_dev: dev_t,
                     pub __pad1: c_short,
                     pub st_ino: ino_t,
@@ -596,13 +602,13 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                pub struct utimbuf {
+                #[deriving(Copy)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
 
                 #[repr(C)]
-                pub struct pthread_attr_t {
+                #[deriving(Copy)] pub struct pthread_attr_t {
                     pub __size: [u32, ..9]
                 }
             }
@@ -617,7 +623,7 @@ pub mod types {
                 pub type blkcnt_t = u32;
 
                 #[repr(C)]
-                pub struct stat {
+                #[deriving(Copy)] pub struct stat {
                     pub st_dev: c_ulonglong,
                     pub __pad0: [c_uchar, ..4],
                     pub __st_ino: ino_t,
@@ -640,13 +646,13 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                pub struct utimbuf {
+                #[deriving(Copy)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
 
                 #[repr(C)]
-                pub struct pthread_attr_t {
+                #[deriving(Copy)] pub struct pthread_attr_t {
                     pub __size: [u32, ..9]
                 }
             }
@@ -662,7 +668,7 @@ pub mod types {
                 pub type blkcnt_t = i32;
 
                 #[repr(C)]
-                pub struct stat {
+                #[deriving(Copy)] pub struct stat {
                     pub st_dev: c_ulong,
                     pub st_pad1: [c_long, ..3],
                     pub st_ino: ino_t,
@@ -686,13 +692,13 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                pub struct utimbuf {
+                #[deriving(Copy)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
 
                 #[repr(C)]
-                pub struct pthread_attr_t {
+                #[deriving(Copy)] pub struct pthread_attr_t {
                     pub __size: [u32, ..9]
                 }
             }
@@ -701,7 +707,7 @@ pub mod types {
             pub mod extra {
                 use types::os::arch::c95::{c_ushort, c_int, c_uchar};
                 #[repr(C)]
-                pub struct sockaddr_ll {
+                #[deriving(Copy)] pub struct sockaddr_ll {
                     pub sll_family: c_ushort,
                     pub sll_protocol: c_ushort,
                     pub sll_ifindex: c_int,
@@ -764,7 +770,7 @@ pub mod types {
                 pub type blksize_t = i64;
                 pub type blkcnt_t = i64;
                 #[repr(C)]
-                pub struct stat {
+                #[deriving(Copy)] pub struct stat {
                     pub st_dev: dev_t,
                     pub st_ino: ino_t,
                     pub st_nlink: nlink_t,
@@ -786,13 +792,13 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                pub struct utimbuf {
+                #[deriving(Copy)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
 
                 #[repr(C)]
-                pub struct pthread_attr_t {
+                #[deriving(Copy)] pub struct pthread_attr_t {
                     pub __size: [u64, ..7]
                 }
             }
@@ -802,7 +808,7 @@ pub mod types {
             }
             pub mod extra {
                 use types::os::arch::c95::{c_ushort, c_int, c_uchar};
-                pub struct sockaddr_ll {
+                #[deriving(Copy)] pub struct sockaddr_ll {
                     pub sll_family: c_ushort,
                     pub sll_protocol: c_ushort,
                     pub sll_ifindex: c_int,
@@ -828,7 +834,7 @@ pub mod types {
                 pub type pthread_t = uintptr_t;
 
                 #[repr(C)]
-                pub struct glob_t {
+                #[deriving(Copy)] pub struct glob_t {
                     pub gl_pathc:  size_t,
                     pub __unused1: size_t,
                     pub gl_offs:   size_t,
@@ -845,18 +851,18 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                pub struct timeval {
+                #[deriving(Copy)] pub struct timeval {
                     pub tv_sec: time_t,
                     pub tv_usec: suseconds_t,
                 }
 
                 #[repr(C)]
-                pub struct timespec {
+                #[deriving(Copy)] pub struct timespec {
                     pub tv_sec: time_t,
                     pub tv_nsec: c_long,
                 }
 
-                pub enum timezone {}
+                #[deriving(Copy)] pub enum timezone {}
 
                 pub type sighandler_t = size_t;
             }
@@ -869,13 +875,13 @@ pub mod types {
                 pub type in_port_t = u16;
                 pub type in_addr_t = u32;
                 #[repr(C)]
-                pub struct sockaddr {
+                #[deriving(Copy)] pub struct sockaddr {
                     pub sa_len: u8,
                     pub sa_family: sa_family_t,
                     pub sa_data: [u8, ..14],
                 }
                 #[repr(C)]
-                pub struct sockaddr_storage {
+                #[deriving(Copy)] pub struct sockaddr_storage {
                     pub ss_len: u8,
                     pub ss_family: sa_family_t,
                     pub __ss_pad1: [u8, ..6],
@@ -883,7 +889,7 @@ pub mod types {
                     pub __ss_pad2: [u8, ..112],
                 }
                 #[repr(C)]
-                pub struct sockaddr_in {
+                #[deriving(Copy)] pub struct sockaddr_in {
                     pub sin_len: u8,
                     pub sin_family: sa_family_t,
                     pub sin_port: in_port_t,
@@ -891,11 +897,11 @@ pub mod types {
                     pub sin_zero: [u8, ..8],
                 }
                 #[repr(C)]
-                pub struct in_addr {
+                #[deriving(Copy)] pub struct in_addr {
                     pub s_addr: in_addr_t,
                 }
                 #[repr(C)]
-                pub struct sockaddr_in6 {
+                #[deriving(Copy)] pub struct sockaddr_in6 {
                     pub sin6_len: u8,
                     pub sin6_family: sa_family_t,
                     pub sin6_port: in_port_t,
@@ -904,21 +910,21 @@ pub mod types {
                     pub sin6_scope_id: u32,
                 }
                 #[repr(C)]
-                pub struct in6_addr {
+                #[deriving(Copy)] pub struct in6_addr {
                     pub s6_addr: [u16, ..8]
                 }
                 #[repr(C)]
-                pub struct ip_mreq {
+                #[deriving(Copy)] pub struct ip_mreq {
                     pub imr_multiaddr: in_addr,
                     pub imr_interface: in_addr,
                 }
                 #[repr(C)]
-                pub struct ip6_mreq {
+                #[deriving(Copy)] pub struct ip6_mreq {
                     pub ipv6mr_multiaddr: in6_addr,
                     pub ipv6mr_interface: c_uint,
                 }
                 #[repr(C)]
-                pub struct addrinfo {
+                #[deriving(Copy)] pub struct addrinfo {
                     pub ai_flags: c_int,
                     pub ai_family: c_int,
                     pub ai_socktype: c_int,
@@ -929,13 +935,13 @@ pub mod types {
                     pub ai_next: *mut addrinfo,
                 }
                 #[repr(C)]
-                pub struct sockaddr_un {
+                #[deriving(Copy)] pub struct sockaddr_un {
                     pub sun_len: u8,
                     pub sun_family: sa_family_t,
                     pub sun_path: [c_char, ..104]
                 }
                 #[repr(C)]
-                pub struct ifaddrs {
+                #[deriving(Copy)] pub struct ifaddrs {
                     pub ifa_next: *mut ifaddrs,
                     pub ifa_name: *mut c_char,
                     pub ifa_flags: c_uint,
@@ -1002,7 +1008,7 @@ pub mod types {
                 pub type blkcnt_t = i64;
                 pub type fflags_t = u32;
                 #[repr(C)]
-                pub struct stat {
+                #[deriving(Copy)] pub struct stat {
                     pub st_dev: dev_t,
                     pub st_ino: ino_t,
                     pub st_mode: mode_t,
@@ -1028,7 +1034,7 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                pub struct utimbuf {
+                #[deriving(Copy)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
@@ -1056,7 +1062,7 @@ pub mod types {
                 pub type pthread_t = uintptr_t;
 
                 #[repr(C)]
-                pub struct glob_t {
+                #[deriving(Copy)] pub struct glob_t {
                     pub gl_pathc:  size_t,
                     pub __unused1: size_t,
                     pub gl_offs:   size_t,
@@ -1073,18 +1079,18 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                pub struct timeval {
+                #[deriving(Copy)] pub struct timeval {
                     pub tv_sec: time_t,
                     pub tv_usec: suseconds_t,
                 }
 
                 #[repr(C)]
-                pub struct timespec {
+                #[deriving(Copy)] pub struct timespec {
                     pub tv_sec: time_t,
                     pub tv_nsec: c_long,
                 }
 
-                pub enum timezone {}
+                #[deriving(Copy)] pub enum timezone {}
 
                 pub type sighandler_t = size_t;
             }
@@ -1096,13 +1102,13 @@ pub mod types {
                 pub type in_port_t = u16;
                 pub type in_addr_t = u32;
                 #[repr(C)]
-                pub struct sockaddr {
+                #[deriving(Copy)] pub struct sockaddr {
                     pub sa_len: u8,
                     pub sa_family: sa_family_t,
                     pub sa_data: [u8, ..14],
                 }
                 #[repr(C)]
-                pub struct sockaddr_storage {
+                #[deriving(Copy)] pub struct sockaddr_storage {
                     pub ss_len: u8,
                     pub ss_family: sa_family_t,
                     pub __ss_pad1: [u8, ..6],
@@ -1110,7 +1116,7 @@ pub mod types {
                     pub __ss_pad2: [u8, ..112],
                 }
                 #[repr(C)]
-                pub struct sockaddr_in {
+                #[deriving(Copy)] pub struct sockaddr_in {
                     pub sin_len: u8,
                     pub sin_family: sa_family_t,
                     pub sin_port: in_port_t,
@@ -1118,11 +1124,11 @@ pub mod types {
                     pub sin_zero: [u8, ..8],
                 }
                 #[repr(C)]
-                pub struct in_addr {
+                #[deriving(Copy)] pub struct in_addr {
                     pub s_addr: in_addr_t,
                 }
                 #[repr(C)]
-                pub struct sockaddr_in6 {
+                #[deriving(Copy)] pub struct sockaddr_in6 {
                     pub sin6_len: u8,
                     pub sin6_family: sa_family_t,
                     pub sin6_port: in_port_t,
@@ -1131,21 +1137,21 @@ pub mod types {
                     pub sin6_scope_id: u32,
                 }
                 #[repr(C)]
-                pub struct in6_addr {
+                #[deriving(Copy)] pub struct in6_addr {
                     pub s6_addr: [u16, ..8]
                 }
                 #[repr(C)]
-                pub struct ip_mreq {
+                #[deriving(Copy)] pub struct ip_mreq {
                     pub imr_multiaddr: in_addr,
                     pub imr_interface: in_addr,
                 }
                 #[repr(C)]
-                pub struct ip6_mreq {
+                #[deriving(Copy)] pub struct ip6_mreq {
                     pub ipv6mr_multiaddr: in6_addr,
                     pub ipv6mr_interface: c_uint,
                 }
                 #[repr(C)]
-                pub struct addrinfo {
+                #[deriving(Copy)] pub struct addrinfo {
                     pub ai_flags: c_int,
                     pub ai_family: c_int,
                     pub ai_socktype: c_int,
@@ -1156,7 +1162,7 @@ pub mod types {
                     pub ai_next: *mut addrinfo,
                 }
                 #[repr(C)]
-                pub struct sockaddr_un {
+                #[deriving(Copy)] pub struct sockaddr_un {
                     pub sun_len: u8,
                     pub sun_family: sa_family_t,
                     pub sun_path: [c_char, ..104]
@@ -1219,7 +1225,7 @@ pub mod types {
                 pub type fflags_t = u32;
 
                 #[repr(C)]
-                pub struct stat {
+                #[deriving(Copy)] pub struct stat {
                     pub st_ino: ino_t,
                     pub st_nlink: nlink_t,
                     pub st_dev: dev_t,
@@ -1244,7 +1250,7 @@ pub mod types {
                     pub st_qspare2: int64_t,
                 }
                 #[repr(C)]
-                pub struct utimbuf {
+                #[deriving(Copy)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
@@ -1271,7 +1277,7 @@ pub mod types {
                 // pub Note: this is the struct called stat64 in Windows. Not stat,
                 // nor stati64.
                 #[repr(C)]
-                pub struct stat {
+                #[deriving(Copy)] pub struct stat {
                     pub st_dev: dev_t,
                     pub st_ino: ino_t,
                     pub st_mode: u16,
@@ -1287,24 +1293,24 @@ pub mod types {
 
                 // note that this is called utimbuf64 in Windows
                 #[repr(C)]
-                pub struct utimbuf {
+                #[deriving(Copy)] pub struct utimbuf {
                     pub actime: time64_t,
                     pub modtime: time64_t,
                 }
 
                 #[repr(C)]
-                pub struct timeval {
+                #[deriving(Copy)] pub struct timeval {
                     pub tv_sec: c_long,
                     pub tv_usec: c_long,
                 }
 
                 #[repr(C)]
-                pub struct timespec {
+                #[deriving(Copy)] pub struct timespec {
                     pub tv_sec: time_t,
                     pub tv_nsec: c_long,
                 }
 
-                pub enum timezone {}
+                #[deriving(Copy)] pub enum timezone {}
             }
 
             pub mod bsd44 {
@@ -1317,30 +1323,30 @@ pub mod types {
                 pub type in_port_t = u16;
                 pub type in_addr_t = u32;
                 #[repr(C)]
-                pub struct sockaddr {
+                #[deriving(Copy)] pub struct sockaddr {
                     pub sa_family: sa_family_t,
                     pub sa_data: [u8, ..14],
                 }
                 #[repr(C)]
-                pub struct sockaddr_storage {
+                #[deriving(Copy)] pub struct sockaddr_storage {
                     pub ss_family: sa_family_t,
                     pub __ss_pad1: [u8, ..6],
                     pub __ss_align: i64,
                     pub __ss_pad2: [u8, ..112],
                 }
                 #[repr(C)]
-                pub struct sockaddr_in {
+                #[deriving(Copy)] pub struct sockaddr_in {
                     pub sin_family: sa_family_t,
                     pub sin_port: in_port_t,
                     pub sin_addr: in_addr,
                     pub sin_zero: [u8, ..8],
                 }
                 #[repr(C)]
-                pub struct in_addr {
+                #[deriving(Copy)] pub struct in_addr {
                     pub s_addr: in_addr_t,
                 }
                 #[repr(C)]
-                pub struct sockaddr_in6 {
+                #[deriving(Copy)] pub struct sockaddr_in6 {
                     pub sin6_family: sa_family_t,
                     pub sin6_port: in_port_t,
                     pub sin6_flowinfo: u32,
@@ -1348,21 +1354,21 @@ pub mod types {
                     pub sin6_scope_id: u32,
                 }
                 #[repr(C)]
-                pub struct in6_addr {
+                #[deriving(Copy)] pub struct in6_addr {
                     pub s6_addr: [u16, ..8]
                 }
                 #[repr(C)]
-                pub struct ip_mreq {
+                #[deriving(Copy)] pub struct ip_mreq {
                     pub imr_multiaddr: in_addr,
                     pub imr_interface: in_addr,
                 }
                 #[repr(C)]
-                pub struct ip6_mreq {
+                #[deriving(Copy)] pub struct ip6_mreq {
                     pub ipv6mr_multiaddr: in6_addr,
                     pub ipv6mr_interface: c_uint,
                 }
                 #[repr(C)]
-                pub struct addrinfo {
+                #[deriving(Copy)] pub struct addrinfo {
                     pub ai_flags: c_int,
                     pub ai_family: c_int,
                     pub ai_socktype: c_int,
@@ -1373,7 +1379,7 @@ pub mod types {
                     pub ai_next: *mut addrinfo,
                 }
                 #[repr(C)]
-                pub struct sockaddr_un {
+                #[deriving(Copy)] pub struct sockaddr_un {
                     pub sun_family: sa_family_t,
                     pub sun_path: [c_char, ..108]
                 }
@@ -1501,7 +1507,7 @@ pub mod types {
                 pub type LPCH = *mut CHAR;
 
                 #[repr(C)]
-                pub struct SECURITY_ATTRIBUTES {
+                #[deriving(Copy)] pub struct SECURITY_ATTRIBUTES {
                     pub nLength: DWORD,
                     pub lpSecurityDescriptor: LPVOID,
                     pub bInheritHandle: BOOL,
@@ -1525,7 +1531,7 @@ pub mod types {
                 pub type int64 = i64;
 
                 #[repr(C)]
-                pub struct STARTUPINFO {
+                #[deriving(Copy)] pub struct STARTUPINFO {
                     pub cb: DWORD,
                     pub lpReserved: LPWSTR,
                     pub lpDesktop: LPWSTR,
@@ -1548,7 +1554,7 @@ pub mod types {
                 pub type LPSTARTUPINFO = *mut STARTUPINFO;
 
                 #[repr(C)]
-                pub struct PROCESS_INFORMATION {
+                #[deriving(Copy)] pub struct PROCESS_INFORMATION {
                     pub hProcess: HANDLE,
                     pub hThread: HANDLE,
                     pub dwProcessId: DWORD,
@@ -1557,7 +1563,7 @@ pub mod types {
                 pub type LPPROCESS_INFORMATION = *mut PROCESS_INFORMATION;
 
                 #[repr(C)]
-                pub struct SYSTEM_INFO {
+                #[deriving(Copy)] pub struct SYSTEM_INFO {
                     pub wProcessorArchitecture: WORD,
                     pub wReserved: WORD,
                     pub dwPageSize: DWORD,
@@ -1573,7 +1579,7 @@ pub mod types {
                 pub type LPSYSTEM_INFO = *mut SYSTEM_INFO;
 
                 #[repr(C)]
-                pub struct MEMORY_BASIC_INFORMATION {
+                #[deriving(Copy)] pub struct MEMORY_BASIC_INFORMATION {
                     pub BaseAddress: LPVOID,
                     pub AllocationBase: LPVOID,
                     pub AllocationProtect: DWORD,
@@ -1585,7 +1591,7 @@ pub mod types {
                 pub type LPMEMORY_BASIC_INFORMATION = *mut MEMORY_BASIC_INFORMATION;
 
                 #[repr(C)]
-                pub struct OVERLAPPED {
+                #[deriving(Copy)] pub struct OVERLAPPED {
                     pub Internal: *mut c_ulong,
                     pub InternalHigh: *mut c_ulong,
                     pub Offset: DWORD,
@@ -1596,7 +1602,7 @@ pub mod types {
                 pub type LPOVERLAPPED = *mut OVERLAPPED;
 
                 #[repr(C)]
-                pub struct FILETIME {
+                #[deriving(Copy)] pub struct FILETIME {
                     pub dwLowDateTime: DWORD,
                     pub dwHighDateTime: DWORD,
                 }
@@ -1604,7 +1610,7 @@ pub mod types {
                 pub type LPFILETIME = *mut FILETIME;
 
                 #[repr(C)]
-                pub struct GUID {
+                #[deriving(Copy)] pub struct GUID {
                     pub Data1: DWORD,
                     pub Data2: WORD,
                     pub Data3: WORD,
@@ -1612,7 +1618,7 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                pub struct WSAPROTOCOLCHAIN {
+                #[deriving(Copy)] pub struct WSAPROTOCOLCHAIN {
                     pub ChainLen: c_int,
                     pub ChainEntries: [DWORD, ..MAX_PROTOCOL_CHAIN as uint],
                 }
@@ -1620,7 +1626,7 @@ pub mod types {
                 pub type LPWSAPROTOCOLCHAIN = *mut WSAPROTOCOLCHAIN;
 
                 #[repr(C)]
-                pub struct WSAPROTOCOL_INFO {
+                #[deriving(Copy)] pub struct WSAPROTOCOL_INFO {
                     pub dwServiceFlags1: DWORD,
                     pub dwServiceFlags2: DWORD,
                     pub dwServiceFlags3: DWORD,
@@ -1648,7 +1654,7 @@ pub mod types {
                 pub type GROUP = c_uint;
 
                 #[repr(C)]
-                pub struct WIN32_FIND_DATAW {
+                #[deriving(Copy)] pub struct WIN32_FIND_DATAW {
                     pub dwFileAttributes: DWORD,
                     pub ftCreationTime: FILETIME,
                     pub ftLastAccessTime: FILETIME,
@@ -1671,14 +1677,14 @@ pub mod types {
         pub mod common {
             pub mod posix01 {
                 use types::common::c95::c_void;
-                use types::os::arch::c95::{c_char, c_int, size_t,
-                                                 time_t, suseconds_t, c_long};
+                use types::os::arch::c95::{c_char, c_int, size_t, time_t};
+                use types::os::arch::c95::{suseconds_t, c_long};
                 use types::os::arch::c99::{uintptr_t};
 
                 pub type pthread_t = uintptr_t;
 
                 #[repr(C)]
-                pub struct glob_t {
+                #[deriving(Copy)] pub struct glob_t {
                     pub gl_pathc:  size_t,
                     pub __unused1: c_int,
                     pub gl_offs:   size_t,
@@ -1695,18 +1701,18 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                pub struct timeval {
+                #[deriving(Copy)] pub struct timeval {
                     pub tv_sec: time_t,
                     pub tv_usec: suseconds_t,
                 }
 
                 #[repr(C)]
-                pub struct timespec {
+                #[deriving(Copy)] pub struct timespec {
                     pub tv_sec: time_t,
                     pub tv_nsec: c_long,
                 }
 
-                pub enum timezone {}
+                #[deriving(Copy)] pub enum timezone {}
 
                 pub type sighandler_t = size_t;
             }
@@ -1720,33 +1726,37 @@ pub mod types {
                 pub type in_port_t = u16;
                 pub type in_addr_t = u32;
                 #[repr(C)]
-                pub struct sockaddr {
+                #[deriving(Copy)] pub struct sockaddr {
                     pub sa_len: u8,
                     pub sa_family: sa_family_t,
                     pub sa_data: [u8, ..14],
                 }
+
                 #[repr(C)]
-                pub struct sockaddr_storage {
+                #[deriving(Copy)] pub struct sockaddr_storage {
                     pub ss_len: u8,
                     pub ss_family: sa_family_t,
                     pub __ss_pad1: [u8, ..6],
                     pub __ss_align: i64,
                     pub __ss_pad2: [u8, ..112],
                 }
+
                 #[repr(C)]
-                pub struct sockaddr_in {
+                #[deriving(Copy)] pub struct sockaddr_in {
                     pub sin_len: u8,
                     pub sin_family: sa_family_t,
                     pub sin_port: in_port_t,
                     pub sin_addr: in_addr,
                     pub sin_zero: [u8, ..8],
                 }
+
                 #[repr(C)]
-                pub struct in_addr {
+                #[deriving(Copy)] pub struct in_addr {
                     pub s_addr: in_addr_t,
                 }
+
                 #[repr(C)]
-                pub struct sockaddr_in6 {
+                #[deriving(Copy)] pub struct sockaddr_in6 {
                     pub sin6_len: u8,
                     pub sin6_family: sa_family_t,
                     pub sin6_port: in_port_t,
@@ -1754,22 +1764,26 @@ pub mod types {
                     pub sin6_addr: in6_addr,
                     pub sin6_scope_id: u32,
                 }
+
                 #[repr(C)]
-                pub struct in6_addr {
+                #[deriving(Copy)] pub struct in6_addr {
                     pub s6_addr: [u16, ..8]
                 }
+
                 #[repr(C)]
-                pub struct ip_mreq {
+                #[deriving(Copy)] pub struct ip_mreq {
                     pub imr_multiaddr: in_addr,
                     pub imr_interface: in_addr,
                 }
+
                 #[repr(C)]
-                pub struct ip6_mreq {
+                #[deriving(Copy)] pub struct ip6_mreq {
                     pub ipv6mr_multiaddr: in6_addr,
                     pub ipv6mr_interface: c_uint,
                 }
+
                 #[repr(C)]
-                pub struct addrinfo {
+                #[deriving(Copy)] pub struct addrinfo {
                     pub ai_flags: c_int,
                     pub ai_family: c_int,
                     pub ai_socktype: c_int,
@@ -1779,14 +1793,16 @@ pub mod types {
                     pub ai_addr: *mut sockaddr,
                     pub ai_next: *mut addrinfo,
                 }
+
                 #[repr(C)]
-                pub struct sockaddr_un {
+                #[deriving(Copy)] pub struct sockaddr_un {
                     pub sun_len: u8,
                     pub sun_family: sa_family_t,
                     pub sun_path: [c_char, ..104]
                 }
+
                 #[repr(C)]
-                pub struct ifaddrs {
+                #[deriving(Copy)] pub struct ifaddrs {
                     pub ifa_next: *mut ifaddrs,
                     pub ifa_name: *mut c_char,
                     pub ifa_flags: c_uint,
@@ -1849,7 +1865,7 @@ pub mod types {
                 pub type blkcnt_t = i32;
 
                 #[repr(C)]
-                pub struct stat {
+                #[deriving(Copy)] pub struct stat {
                     pub st_dev: dev_t,
                     pub st_mode: mode_t,
                     pub st_nlink: nlink_t,
@@ -1875,13 +1891,13 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                pub struct utimbuf {
+                #[deriving(Copy)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
 
                 #[repr(C)]
-                pub struct pthread_attr_t {
+                #[deriving(Copy)] pub struct pthread_attr_t {
                     pub __sig: c_long,
                     pub __opaque: [c_char, ..36]
                 }
@@ -1892,7 +1908,7 @@ pub mod types {
             }
             pub mod extra {
                 #[repr(C)]
-                pub struct mach_timebase_info {
+                #[deriving(Copy)] pub struct mach_timebase_info {
                     pub numer: u32,
                     pub denom: u32,
                 }
@@ -1953,7 +1969,7 @@ pub mod types {
                 pub type blkcnt_t = i32;
 
                 #[repr(C)]
-                pub struct stat {
+                #[deriving(Copy)] pub struct stat {
                     pub st_dev: dev_t,
                     pub st_mode: mode_t,
                     pub st_nlink: nlink_t,
@@ -1979,13 +1995,13 @@ pub mod types {
                 }
 
                 #[repr(C)]
-                pub struct utimbuf {
+                #[deriving(Copy)] pub struct utimbuf {
                     pub actime: time_t,
                     pub modtime: time_t,
                 }
 
                 #[repr(C)]
-                pub struct pthread_attr_t {
+                #[deriving(Copy)] pub struct pthread_attr_t {
                     pub __sig: c_long,
                     pub __opaque: [c_char, ..56]
                 }
@@ -1996,7 +2012,7 @@ pub mod types {
             }
             pub mod extra {
                 #[repr(C)]
-                pub struct mach_timebase_info {
+                #[deriving(Copy)] pub struct mach_timebase_info {
                     pub numer: u32,
                     pub denom: u32,
                 }
@@ -4990,3 +5006,9 @@ pub mod funcs {
 pub fn issue_14344_workaround() {} // FIXME #14344 force linkage to happen correctly
 
 #[test] fn work_on_windows() { } // FIXME #10872 needed for a happy windows
+
+#[doc(hidden)]
+#[cfg(not(test))]
+mod std {
+    pub use core::kinds;
+}
diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs
index 5642ec91ba3..8b79078eac6 100644
--- a/src/liblog/lib.rs
+++ b/src/liblog/lib.rs
@@ -234,6 +234,8 @@ struct DefaultLogger {
 #[deriving(PartialEq, PartialOrd)]
 pub struct LogLevel(pub u32);
 
+impl Copy for LogLevel {}
+
 impl fmt::Show for LogLevel {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         let LogLevel(level) = *self;
@@ -344,6 +346,8 @@ pub struct LogLocation {
     pub line: uint,
 }
 
+impl Copy for LogLocation {}
+
 /// Tests whether a given module's name is enabled for a particular level of
 /// logging. This is the second layer of defense about determining whether a
 /// module's log statement should be emitted or not.
diff --git a/src/librand/chacha.rs b/src/librand/chacha.rs
index 2693f183644..83a410674ee 100644
--- a/src/librand/chacha.rs
+++ b/src/librand/chacha.rs
@@ -35,6 +35,8 @@ pub struct ChaChaRng {
     index:   uint,                 // Index into state
 }
 
+impl Copy for ChaChaRng {}
+
 static EMPTY: ChaChaRng = ChaChaRng {
     buffer:  [0, ..STATE_WORDS],
     state:   [0, ..STATE_WORDS],
diff --git a/src/librand/distributions/exponential.rs b/src/librand/distributions/exponential.rs
index d874f1deed3..9a9f31e9339 100644
--- a/src/librand/distributions/exponential.rs
+++ b/src/librand/distributions/exponential.rs
@@ -10,6 +10,7 @@
 
 //! The exponential distribution.
 
+use core::kinds::Copy;
 use core::num::Float;
 
 use {Rng, Rand};
@@ -31,6 +32,8 @@ use distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample};
 /// College, Oxford
 pub struct Exp1(pub f64);
 
+impl Copy for Exp1 {}
+
 // This could be done via `-rng.gen::<f64>().ln()` but that is slower.
 impl Rand for Exp1 {
     #[inline]
@@ -71,6 +74,8 @@ pub struct Exp {
     lambda_inverse: f64
 }
 
+impl Copy for Exp {}
+
 impl Exp {
     /// Construct a new `Exp` with the given shape parameter
     /// `lambda`. Panics if `lambda <= 0`.
diff --git a/src/librand/distributions/normal.rs b/src/librand/distributions/normal.rs
index b3dc20819bc..f5261f1db82 100644
--- a/src/librand/distributions/normal.rs
+++ b/src/librand/distributions/normal.rs
@@ -10,6 +10,7 @@
 
 //! The normal and derived distributions.
 
+use core::kinds::Copy;
 use core::num::Float;
 
 use {Rng, Rand, Open01};
@@ -30,6 +31,8 @@ use distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample};
 /// College, Oxford
 pub struct StandardNormal(pub f64);
 
+impl Copy for StandardNormal {}
+
 impl Rand for StandardNormal {
     fn rand<R:Rng>(rng: &mut R) -> StandardNormal {
         #[inline]
@@ -88,6 +91,8 @@ pub struct Normal {
     std_dev: f64,
 }
 
+impl Copy for Normal {}
+
 impl Normal {
     /// Construct a new `Normal` distribution with the given mean and
     /// standard deviation.
@@ -134,6 +139,8 @@ pub struct LogNormal {
     norm: Normal
 }
 
+impl Copy for LogNormal {}
+
 impl LogNormal {
     /// Construct a new `LogNormal` distribution with the given mean
     /// and standard deviation.
diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs
index 517b50c49c7..2c1853b1951 100644
--- a/src/librand/isaac.rs
+++ b/src/librand/isaac.rs
@@ -37,6 +37,9 @@ pub struct IsaacRng {
     b: u32,
     c: u32
 }
+
+impl Copy for IsaacRng {}
+
 static EMPTY: IsaacRng = IsaacRng {
     cnt: 0,
     rsl: [0, ..RAND_SIZE_UINT],
@@ -271,6 +274,8 @@ pub struct Isaac64Rng {
     c: u64,
 }
 
+impl Copy for Isaac64Rng {}
+
 static EMPTY_64: Isaac64Rng = Isaac64Rng {
     cnt: 0,
     rsl: [0, .. RAND_SIZE_64],
diff --git a/src/librand/lib.rs b/src/librand/lib.rs
index de40ee4893d..d357f247f1b 100644
--- a/src/librand/lib.rs
+++ b/src/librand/lib.rs
@@ -377,6 +377,7 @@ pub trait SeedableRng<Seed>: Rng {
 /// [1]: Marsaglia, George (July 2003). ["Xorshift
 /// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
 /// Statistical Software*. Vol. 8 (Issue 14).
+#[allow(missing_copy_implementations)]
 pub struct XorShiftRng {
     x: u32,
     y: u32,
@@ -384,6 +385,17 @@ pub struct XorShiftRng {
     w: u32,
 }
 
+impl Clone for XorShiftRng {
+    fn clone(&self) -> XorShiftRng {
+        XorShiftRng {
+            x: self.x,
+            y: self.y,
+            z: self.z,
+            w: self.w,
+        }
+    }
+}
+
 impl XorShiftRng {
     /// Creates a new XorShiftRng instance which is not seeded.
     ///
diff --git a/src/librand/reseeding.rs b/src/librand/reseeding.rs
index 64c6b1739eb..88c870579e6 100644
--- a/src/librand/reseeding.rs
+++ b/src/librand/reseeding.rs
@@ -135,6 +135,8 @@ pub trait Reseeder<R> {
 /// replacing the RNG with the result of a `Default::default` call.
 pub struct ReseedWithDefault;
 
+impl Copy for ReseedWithDefault {}
+
 impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {
     fn reseed(&mut self, rng: &mut R) {
         *rng = Default::default();
diff --git a/src/librbml/lib.rs b/src/librbml/lib.rs
index f65c4f4e3ed..426a987d25d 100644
--- a/src/librbml/lib.rs
+++ b/src/librbml/lib.rs
@@ -47,6 +47,8 @@ pub struct Doc<'a> {
     pub end: uint,
 }
 
+impl<'doc> Copy for Doc<'doc> {}
+
 impl<'doc> Doc<'doc> {
     pub fn new(data: &'doc [u8]) -> Doc<'doc> {
         Doc { data: data, start: 0u, end: data.len() }
@@ -104,6 +106,8 @@ pub enum EbmlEncoderTag {
     EsLabel, // Used only when debugging
 }
 
+impl Copy for EbmlEncoderTag {}
+
 #[deriving(Show)]
 pub enum Error {
     IntTooBig(uint),
@@ -151,6 +155,8 @@ pub mod reader {
         pub next: uint
     }
 
+    impl Copy for Res {}
+
     #[inline(never)]
     fn vuint_at_slow(data: &[u8], start: uint) -> DecodeResult<Res> {
         let a = data[start];
diff --git a/src/libregex/parse.rs b/src/libregex/parse.rs
index 5cd833e2797..55e533aadee 100644
--- a/src/libregex/parse.rs
+++ b/src/libregex/parse.rs
@@ -83,6 +83,8 @@ pub enum Greed {
     Ungreedy,
 }
 
+impl Copy for Greed {}
+
 impl Greed {
     pub fn is_greedy(&self) -> bool {
         match *self {
diff --git a/src/libregex/re.rs b/src/libregex/re.rs
index 58ce72a3173..2a1fda06431 100644
--- a/src/libregex/re.rs
+++ b/src/libregex/re.rs
@@ -135,8 +135,12 @@ pub struct ExNative {
     pub prog: fn(MatchKind, &str, uint, uint) -> Vec<Option<uint>>
 }
 
+impl Copy for ExNative {}
+
 impl Clone for ExNative {
-    fn clone(&self) -> ExNative { *self }
+    fn clone(&self) -> ExNative {
+        *self
+    }
 }
 
 impl fmt::Show for Regex {
@@ -917,7 +921,7 @@ fn exec_slice(re: &Regex, which: MatchKind,
               input: &str, s: uint, e: uint) -> CaptureLocs {
     match *re {
         Dynamic(ExDynamic { ref prog, .. }) => vm::run(which, prog, input, s, e),
-        Native(ExNative { prog, .. }) => prog(which, input, s, e),
+        Native(ExNative { ref prog, .. }) => (*prog)(which, input, s, e),
     }
 }
 
diff --git a/src/libregex/vm.rs b/src/libregex/vm.rs
index 4315c0f7b40..44cf2249b8e 100644
--- a/src/libregex/vm.rs
+++ b/src/libregex/vm.rs
@@ -60,6 +60,8 @@ pub enum MatchKind {
     Submatches,
 }
 
+impl Copy for MatchKind {}
+
 /// Runs an NFA simulation on the compiled expression given on the search text
 /// `input`. The search begins at byte index `start` and ends at byte index
 /// `end`. (The range is specified here so that zero-width assertions will work
@@ -107,6 +109,8 @@ pub enum StepState {
     StepContinue,
 }
 
+impl Copy for StepState {}
+
 impl<'r, 't> Nfa<'r, 't> {
     fn run(&mut self) -> CaptureLocs {
         let ncaps = match self.which {
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index c474820c3c9..e19fa01b2e4 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -28,6 +28,7 @@ use self::MethodContext::*;
 
 use metadata::csearch;
 use middle::def::*;
+use middle::subst::Substs;
 use middle::ty::{mod, Ty};
 use middle::{def, pat_util, stability};
 use middle::const_eval::{eval_const_expr_partial, const_int, const_uint};
@@ -40,11 +41,12 @@ use std::collections::hash_map::{Occupied, Vacant};
 use std::num::SignedInt;
 use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
 use syntax::{abi, ast, ast_map};
-use syntax::ast_util::{mod, is_shift_binop};
+use syntax::ast_util::is_shift_binop;
 use syntax::attr::{mod, AttrMetaMethods};
 use syntax::codemap::{Span, DUMMY_SP};
 use syntax::parse::token;
 use syntax::ast::{TyI, TyU, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64};
+use syntax::ast_util;
 use syntax::ptr::P;
 use syntax::visit::{mod, Visitor};
 
@@ -53,6 +55,8 @@ declare_lint!(WHILE_TRUE, Warn,
 
 pub struct WhileTrue;
 
+impl Copy for WhileTrue {}
+
 impl LintPass for WhileTrue {
     fn get_lints(&self) -> LintArray {
         lint_array!(WHILE_TRUE)
@@ -75,6 +79,8 @@ declare_lint!(UNUSED_TYPECASTS, Allow,
 
 pub struct UnusedCasts;
 
+impl Copy for UnusedCasts {}
+
 impl LintPass for UnusedCasts {
     fn get_lints(&self) -> LintArray {
         lint_array!(UNUSED_TYPECASTS)
@@ -107,6 +113,8 @@ pub struct TypeLimits {
     negated_expr_id: ast::NodeId,
 }
 
+impl Copy for TypeLimits {}
+
 impl TypeLimits {
     pub fn new() -> TypeLimits {
         TypeLimits {
@@ -415,6 +423,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ImproperCTypesVisitor<'a, 'tcx> {
 
 pub struct ImproperCTypes;
 
+impl Copy for ImproperCTypes {}
+
 impl LintPass for ImproperCTypes {
     fn get_lints(&self) -> LintArray {
         lint_array!(IMPROPER_CTYPES)
@@ -454,6 +464,8 @@ declare_lint!(BOX_POINTERS, Allow,
 
 pub struct BoxPointers;
 
+impl Copy for BoxPointers {}
+
 impl BoxPointers {
     fn check_heap_type<'a, 'tcx>(&self, cx: &Context<'a, 'tcx>,
                                  span: Span, ty: Ty<'tcx>) {
@@ -587,6 +599,8 @@ declare_lint!(UNUSED_ATTRIBUTES, Warn,
 
 pub struct UnusedAttributes;
 
+impl Copy for UnusedAttributes {}
+
 impl LintPass for UnusedAttributes {
     fn get_lints(&self) -> LintArray {
         lint_array!(UNUSED_ATTRIBUTES)
@@ -666,6 +680,8 @@ declare_lint!(pub PATH_STATEMENTS, Warn,
 
 pub struct PathStatements;
 
+impl Copy for PathStatements {}
+
 impl LintPass for PathStatements {
     fn get_lints(&self) -> LintArray {
         lint_array!(PATH_STATEMENTS)
@@ -693,6 +709,8 @@ declare_lint!(pub UNUSED_RESULTS, Allow,
 
 pub struct UnusedResults;
 
+impl Copy for UnusedResults {}
+
 impl LintPass for UnusedResults {
     fn get_lints(&self) -> LintArray {
         lint_array!(UNUSED_MUST_USE, UNUSED_RESULTS)
@@ -757,6 +775,8 @@ declare_lint!(pub NON_CAMEL_CASE_TYPES, Warn,
 
 pub struct NonCamelCaseTypes;
 
+impl Copy for NonCamelCaseTypes {}
+
 impl NonCamelCaseTypes {
     fn check_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
         fn is_camel_case(ident: ast::Ident) -> bool {
@@ -876,6 +896,8 @@ declare_lint!(pub NON_SNAKE_CASE, Warn,
 
 pub struct NonSnakeCase;
 
+impl Copy for NonSnakeCase {}
+
 impl NonSnakeCase {
     fn check_snake_case(&self, cx: &Context, sort: &str, ident: ast::Ident, span: Span) {
         fn is_snake_case(ident: ast::Ident) -> bool {
@@ -985,6 +1007,8 @@ declare_lint!(pub NON_UPPER_CASE_GLOBALS, Warn,
 
 pub struct NonUpperCaseGlobals;
 
+impl Copy for NonUpperCaseGlobals {}
+
 impl LintPass for NonUpperCaseGlobals {
     fn get_lints(&self) -> LintArray {
         lint_array!(NON_UPPER_CASE_GLOBALS)
@@ -1034,6 +1058,8 @@ declare_lint!(UNUSED_PARENS, Warn,
 
 pub struct UnusedParens;
 
+impl Copy for UnusedParens {}
+
 impl UnusedParens {
     fn check_unused_parens_core(&self, cx: &Context, value: &ast::Expr, msg: &str,
                                      struct_lit_needs_parens: bool) {
@@ -1124,6 +1150,8 @@ declare_lint!(UNUSED_IMPORT_BRACES, Allow,
 
 pub struct UnusedImportBraces;
 
+impl Copy for UnusedImportBraces {}
+
 impl LintPass for UnusedImportBraces {
     fn get_lints(&self) -> LintArray {
         lint_array!(UNUSED_IMPORT_BRACES)
@@ -1159,6 +1187,8 @@ declare_lint!(NON_SHORTHAND_FIELD_PATTERNS, Warn,
 
 pub struct NonShorthandFieldPatterns;
 
+impl Copy for NonShorthandFieldPatterns {}
+
 impl LintPass for NonShorthandFieldPatterns {
     fn get_lints(&self) -> LintArray {
         lint_array!(NON_SHORTHAND_FIELD_PATTERNS)
@@ -1188,6 +1218,8 @@ declare_lint!(pub UNUSED_UNSAFE, Warn,
 
 pub struct UnusedUnsafe;
 
+impl Copy for UnusedUnsafe {}
+
 impl LintPass for UnusedUnsafe {
     fn get_lints(&self) -> LintArray {
         lint_array!(UNUSED_UNSAFE)
@@ -1209,6 +1241,8 @@ declare_lint!(UNSAFE_BLOCKS, Allow,
 
 pub struct UnsafeBlocks;
 
+impl Copy for UnsafeBlocks {}
+
 impl LintPass for UnsafeBlocks {
     fn get_lints(&self) -> LintArray {
         lint_array!(UNSAFE_BLOCKS)
@@ -1229,6 +1263,8 @@ declare_lint!(pub UNUSED_MUT, Warn,
 
 pub struct UnusedMut;
 
+impl Copy for UnusedMut {}
+
 impl UnusedMut {
     fn check_unused_mut_pat(&self, cx: &Context, pats: &[P<ast::Pat>]) {
         // collect all mutable pattern and group their NodeIDs by their Identifier to
@@ -1294,6 +1330,8 @@ declare_lint!(UNUSED_ALLOCATION, Warn,
 
 pub struct UnusedAllocation;
 
+impl Copy for UnusedAllocation {}
+
 impl LintPass for UnusedAllocation {
     fn get_lints(&self) -> LintArray {
         lint_array!(UNUSED_ALLOCATION)
@@ -1479,6 +1517,61 @@ impl LintPass for MissingDoc {
     }
 }
 
+pub struct MissingCopyImplementations;
+
+impl Copy for MissingCopyImplementations {}
+
+impl LintPass for MissingCopyImplementations {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(MISSING_COPY_IMPLEMENTATIONS)
+    }
+
+    fn check_item(&mut self, cx: &Context, item: &ast::Item) {
+        if !cx.exported_items.contains(&item.id) {
+            return
+        }
+        if cx.tcx
+             .destructor_for_type
+             .borrow()
+             .contains_key(&ast_util::local_def(item.id)) {
+            return
+        }
+        let ty = match item.node {
+            ast::ItemStruct(_, ref ast_generics) => {
+                if ast_generics.is_parameterized() {
+                    return
+                }
+                ty::mk_struct(cx.tcx,
+                              ast_util::local_def(item.id),
+                              Substs::empty())
+            }
+            ast::ItemEnum(_, ref ast_generics) => {
+                if ast_generics.is_parameterized() {
+                    return
+                }
+                ty::mk_enum(cx.tcx,
+                            ast_util::local_def(item.id),
+                            Substs::empty())
+            }
+            _ => return,
+        };
+        let parameter_environment = ty::empty_parameter_environment();
+        if !ty::type_moves_by_default(cx.tcx,
+                                      ty,
+                                      &parameter_environment) {
+            return
+        }
+        if ty::can_type_implement_copy(cx.tcx,
+                                       ty,
+                                       &parameter_environment).is_ok() {
+            cx.span_lint(MISSING_COPY_IMPLEMENTATIONS,
+                         item.span,
+                         "type could implement `Copy`; consider adding `impl \
+                          Copy`")
+        }
+    }
+}
+
 declare_lint!(DEPRECATED, Warn,
               "detects use of #[deprecated] items")
 
@@ -1493,6 +1586,8 @@ declare_lint!(UNSTABLE, Allow,
 /// `#[unstable]` attributes, or no stability attribute.
 pub struct Stability;
 
+impl Copy for Stability {}
+
 impl Stability {
     fn lint(&self, cx: &Context, id: ast::DefId, span: Span) {
         let stability = stability::lookup(cx.tcx, id);
@@ -1682,10 +1777,15 @@ declare_lint!(pub VARIANT_SIZE_DIFFERENCES, Allow,
 declare_lint!(pub FAT_PTR_TRANSMUTES, Allow,
               "detects transmutes of fat pointers")
 
+declare_lint!(pub MISSING_COPY_IMPLEMENTATIONS, Warn,
+              "detects potentially-forgotten implementations of `Copy`")
+
 /// Does nothing as a lint pass, but registers some `Lint`s
 /// which are used by other parts of the compiler.
 pub struct HardwiredLints;
 
+impl Copy for HardwiredLints {}
+
 impl LintPass for HardwiredLints {
     fn get_lints(&self) -> LintArray {
         lint_array!(
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 442d3aab92d..153a00e5617 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -204,6 +204,7 @@ impl LintStore {
                      UnusedMut,
                      UnusedAllocation,
                      Stability,
+                     MissingCopyImplementations,
         )
 
         add_builtin_with_new!(sess,
diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs
index d6b83752cc5..4b4ba2ab94c 100644
--- a/src/librustc/lint/mod.rs
+++ b/src/librustc/lint/mod.rs
@@ -64,6 +64,8 @@ pub struct Lint {
     pub desc: &'static str,
 }
 
+impl Copy for Lint {}
+
 impl Lint {
     /// Get the lint's name, with ASCII letters converted to lowercase.
     pub fn name_lower(&self) -> String {
@@ -179,6 +181,8 @@ pub struct LintId {
     lint: &'static Lint,
 }
 
+impl Copy for LintId {}
+
 impl PartialEq for LintId {
     fn eq(&self, other: &LintId) -> bool {
         (self.lint as *const Lint) == (other.lint as *const Lint)
@@ -214,6 +218,8 @@ pub enum Level {
     Allow, Warn, Deny, Forbid
 }
 
+impl Copy for Level {}
+
 impl Level {
     /// Convert a level to a lower-case string.
     pub fn as_str(self) -> &'static str {
@@ -251,6 +257,8 @@ pub enum LintSource {
     CommandLine,
 }
 
+impl Copy for LintSource {}
+
 pub type LevelSource = (Level, LintSource);
 
 pub mod builtin;
diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs
index 0da3b1b7a4e..315e0eea9b7 100644
--- a/src/librustc/metadata/common.rs
+++ b/src/librustc/metadata/common.rs
@@ -144,6 +144,8 @@ pub enum astencode_tag { // Reserves 0x40 -- 0x5f
     tag_table_capture_modes = 0x56,
     tag_table_object_cast_map = 0x57,
 }
+
+impl Copy for astencode_tag {}
 static first_astencode_tag: uint = tag_ast as uint;
 static last_astencode_tag: uint = tag_table_object_cast_map as uint;
 impl astencode_tag {
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index deeab18de7c..9e87153e64a 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc/metadata/creader.rs
@@ -275,8 +275,10 @@ fn visit_item(e: &Env, i: &ast::Item) {
     }
 }
 
-fn register_native_lib(sess: &Session, span: Option<Span>, name: String,
-                       kind: cstore::NativeLibaryKind) {
+fn register_native_lib(sess: &Session,
+                       span: Option<Span>,
+                       name: String,
+                       kind: cstore::NativeLibraryKind) {
     if name.is_empty() {
         match span {
             Some(span) => {
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index ebf5cca6a31..b864dc39603 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -40,6 +40,8 @@ pub struct MethodInfo {
     pub vis: ast::Visibility,
 }
 
+impl Copy for MethodInfo {}
+
 pub fn get_symbol(cstore: &cstore::CStore, def: ast::DefId) -> String {
     let cdata = cstore.get_crate_data(def.krate);
     decoder::get_symbol(cdata.data(), def.node)
@@ -273,9 +275,8 @@ pub fn get_impl_vtables<'tcx>(tcx: &ty::ctxt<'tcx>,
     decoder::get_impl_vtables(&*cdata, def.node, tcx)
 }
 
-pub fn get_native_libraries(cstore: &cstore::CStore,
-                            crate_num: ast::CrateNum)
-                                -> Vec<(cstore::NativeLibaryKind, String)> {
+pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum)
+                            -> Vec<(cstore::NativeLibraryKind, String)> {
     let cdata = cstore.get_crate_data(crate_num);
     decoder::get_native_libraries(&*cdata)
 }
diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs
index f93a1699e18..91f360a7a38 100644
--- a/src/librustc/metadata/cstore.rs
+++ b/src/librustc/metadata/cstore.rs
@@ -15,7 +15,7 @@
 
 pub use self::MetadataBlob::*;
 pub use self::LinkagePreference::*;
-pub use self::NativeLibaryKind::*;
+pub use self::NativeLibraryKind::*;
 
 use back::svh::Svh;
 use metadata::decoder;
@@ -54,13 +54,17 @@ pub enum LinkagePreference {
     RequireStatic,
 }
 
-#[deriving(PartialEq, FromPrimitive, Clone)]
-pub enum NativeLibaryKind {
+impl Copy for LinkagePreference {}
+
+#[deriving(Clone, PartialEq, FromPrimitive)]
+pub enum NativeLibraryKind {
     NativeStatic,    // native static library (.a archive)
     NativeFramework, // OSX-specific
     NativeUnknown,   // default way to specify a dynamic library
 }
 
+impl Copy for NativeLibraryKind {}
+
 // Where a crate came from on the local filesystem. One of these two options
 // must be non-None.
 #[deriving(PartialEq, Clone)]
@@ -75,7 +79,7 @@ pub struct CStore {
     /// Map from NodeId's of local extern crate statements to crate numbers
     extern_mod_crate_map: RefCell<NodeMap<ast::CrateNum>>,
     used_crate_sources: RefCell<Vec<CrateSource>>,
-    used_libraries: RefCell<Vec<(String, NativeLibaryKind)>>,
+    used_libraries: RefCell<Vec<(String, NativeLibraryKind)>>,
     used_link_args: RefCell<Vec<String>>,
     pub intr: Rc<IdentInterner>,
 }
@@ -186,13 +190,14 @@ impl CStore {
         libs
     }
 
-    pub fn add_used_library(&self, lib: String, kind: NativeLibaryKind) {
+    pub fn add_used_library(&self, lib: String, kind: NativeLibraryKind) {
         assert!(!lib.is_empty());
         self.used_libraries.borrow_mut().push((lib, kind));
     }
 
     pub fn get_used_libraries<'a>(&'a self)
-                              -> &'a RefCell<Vec<(String, NativeLibaryKind)> > {
+                              -> &'a RefCell<Vec<(String,
+                                                  NativeLibraryKind)>> {
         &self.used_libraries
     }
 
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index f352a28df69..0d51e044de9 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -442,6 +442,8 @@ pub enum DefLike {
     DlField
 }
 
+impl Copy for DefLike {}
+
 /// Iterates over the language items in the given crate.
 pub fn each_lang_item(cdata: Cmd, f: |ast::NodeId, uint| -> bool) -> bool {
     let root = rbml::Doc::new(cdata.data());
@@ -1267,14 +1269,14 @@ pub fn get_trait_of_item(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
 
 
 pub fn get_native_libraries(cdata: Cmd)
-                            -> Vec<(cstore::NativeLibaryKind, String)> {
+                            -> Vec<(cstore::NativeLibraryKind, String)> {
     let libraries = reader::get_doc(rbml::Doc::new(cdata.data()),
                                     tag_native_libraries);
     let mut result = Vec::new();
     reader::tagged_docs(libraries, tag_native_libraries_lib, |lib_doc| {
         let kind_doc = reader::get_doc(lib_doc, tag_native_libraries_kind);
         let name_doc = reader::get_doc(lib_doc, tag_native_libraries_name);
-        let kind: cstore::NativeLibaryKind =
+        let kind: cstore::NativeLibraryKind =
             FromPrimitive::from_u32(reader::doc_as_u32(kind_doc)).unwrap();
         let name = name_doc.as_str().to_string();
         result.push((kind, name));
diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs
index 63fc2af492c..2d23a61813a 100644
--- a/src/librustc/metadata/filesearch.rs
+++ b/src/librustc/metadata/filesearch.rs
@@ -20,7 +20,12 @@ use std::os;
 
 use util::fs as myfs;
 
-pub enum FileMatch { FileMatches, FileDoesntMatch }
+pub enum FileMatch {
+    FileMatches,
+    FileDoesntMatch,
+}
+
+impl Copy for FileMatch {}
 
 // A module for searching for libraries
 // FIXME (#2658): I'm not happy how this module turned out. Should
diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs
index 00d12ad6a38..e29741fb4a1 100644
--- a/src/librustc/metadata/tydecode.rs
+++ b/src/librustc/metadata/tydecode.rs
@@ -61,6 +61,8 @@ pub enum DefIdSource {
     // Identifies an unboxed closure
     UnboxedClosureSource
 }
+
+impl Copy for DefIdSource {}
 pub type conv_did<'a> =
     |source: DefIdSource, ast::DefId|: 'a -> ast::DefId;
 
diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs
index 72c6256dcb5..5f030324d42 100644
--- a/src/librustc/middle/borrowck/check_loans.rs
+++ b/src/librustc/middle/borrowck/check_loans.rs
@@ -24,7 +24,9 @@ use middle::borrowck::LoanPathKind::*;
 use middle::expr_use_visitor as euv;
 use middle::mem_categorization as mc;
 use middle::region;
+use middle::ty::ParameterEnvironment;
 use middle::ty;
+use syntax::ast::NodeId;
 use syntax::ast;
 use syntax::codemap::Span;
 use util::ppaux::Repr;
@@ -89,6 +91,7 @@ struct CheckLoanCtxt<'a, 'tcx: 'a> {
     dfcx_loans: &'a LoanDataFlow<'a, 'tcx>,
     move_data: move_data::FlowedMoveData<'a, 'tcx>,
     all_loans: &'a [Loan<'tcx>],
+    param_env: &'a ParameterEnvironment<'tcx>,
 }
 
 impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> {
@@ -193,19 +196,25 @@ pub fn check_loans<'a, 'b, 'c, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
                                      dfcx_loans: &LoanDataFlow<'b, 'tcx>,
                                      move_data: move_data::FlowedMoveData<'c, 'tcx>,
                                      all_loans: &[Loan<'tcx>],
+                                     fn_id: NodeId,
                                      decl: &ast::FnDecl,
                                      body: &ast::Block) {
     debug!("check_loans(body id={})", body.id);
 
+    let param_env = ParameterEnvironment::for_item(bccx.tcx, fn_id);
+
     let mut clcx = CheckLoanCtxt {
         bccx: bccx,
         dfcx_loans: dfcx_loans,
         move_data: move_data,
         all_loans: all_loans,
+        param_env: &param_env,
     };
 
     {
-        let mut euv = euv::ExprUseVisitor::new(&mut clcx, bccx.tcx);
+        let mut euv = euv::ExprUseVisitor::new(&mut clcx,
+                                               bccx.tcx,
+                                               param_env.clone());
         euv.walk_fn(decl, body);
     }
 }
@@ -700,7 +709,8 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                 use_kind,
                 &**lp,
                 the_move,
-                moved_lp);
+                moved_lp,
+                self.param_env);
             false
         });
     }
diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs
index edffe59fff5..ca9d4b512b3 100644
--- a/src/librustc/middle/borrowck/gather_loans/mod.rs
+++ b/src/librustc/middle/borrowck/gather_loans/mod.rs
@@ -22,6 +22,7 @@ use middle::borrowck::move_data::MoveData;
 use middle::expr_use_visitor as euv;
 use middle::mem_categorization as mc;
 use middle::region;
+use middle::ty::ParameterEnvironment;
 use middle::ty;
 use util::ppaux::{Repr};
 
@@ -37,10 +38,11 @@ mod gather_moves;
 mod move_error;
 
 pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
+                                    fn_id: NodeId,
                                     decl: &ast::FnDecl,
                                     body: &ast::Block)
-                                    -> (Vec<Loan<'tcx>>, move_data::MoveData<'tcx>)
-{
+                                    -> (Vec<Loan<'tcx>>,
+                                        move_data::MoveData<'tcx>) {
     let mut glcx = GatherLoanCtxt {
         bccx: bccx,
         all_loans: Vec::new(),
@@ -49,8 +51,12 @@ pub fn gather_loans_in_fn<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>,
         move_error_collector: move_error::MoveErrorCollector::new(),
     };
 
+    let param_env = ParameterEnvironment::for_item(bccx.tcx, fn_id);
+
     {
-        let mut euv = euv::ExprUseVisitor::new(&mut glcx, bccx.tcx);
+        let mut euv = euv::ExprUseVisitor::new(&mut glcx,
+                                               bccx.tcx,
+                                               param_env);
         euv.walk_fn(decl, body);
     }
 
diff --git a/src/librustc/middle/borrowck/graphviz.rs b/src/librustc/middle/borrowck/graphviz.rs
index a209b1a28f2..32fa5f8c3a9 100644
--- a/src/librustc/middle/borrowck/graphviz.rs
+++ b/src/librustc/middle/borrowck/graphviz.rs
@@ -34,6 +34,8 @@ pub enum Variant {
     Assigns,
 }
 
+impl Copy for Variant {}
+
 impl Variant {
     pub fn short_name(&self) -> &'static str {
         match *self {
diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs
index 0bbcdfe61bb..e90de1b6912 100644
--- a/src/librustc/middle/borrowck/mod.rs
+++ b/src/librustc/middle/borrowck/mod.rs
@@ -25,7 +25,7 @@ use middle::dataflow::DataFlowOperator;
 use middle::expr_use_visitor as euv;
 use middle::mem_categorization as mc;
 use middle::region;
-use middle::ty::{mod, Ty};
+use middle::ty::{mod, ParameterEnvironment, Ty};
 use util::ppaux::{note_and_explain_region, Repr, UserString};
 
 use std::rc::Rc;
@@ -62,6 +62,8 @@ pub mod move_data;
 #[deriving(Clone)]
 pub struct LoanDataFlowOperator;
 
+impl Copy for LoanDataFlowOperator {}
+
 pub type LoanDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, LoanDataFlowOperator>;
 
 impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> {
@@ -146,8 +148,13 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
     move_data::fragments::instrument_move_fragments(&flowed_moves.move_data,
                                                     this.tcx, sp, id);
 
-    check_loans::check_loans(this, &loan_dfcx, flowed_moves,
-                             all_loans.as_slice(), decl, body);
+    check_loans::check_loans(this,
+                             &loan_dfcx,
+                             flowed_moves,
+                             all_loans.as_slice(),
+                             id,
+                             decl,
+                             body);
 
     visit::walk_fn(this, fk, decl, body, sp);
 }
@@ -162,7 +169,7 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
     // Check the body of fn items.
     let id_range = ast_util::compute_id_range_for_fn_body(fk, decl, body, sp, id);
     let (all_loans, move_data) =
-        gather_loans::gather_loans_in_fn(this, decl, body);
+        gather_loans::gather_loans_in_fn(this, id, decl, body);
 
     let mut loan_dfcx =
         DataFlowContext::new(this.tcx,
@@ -339,6 +346,8 @@ pub enum LoanPathElem {
     LpInterior(mc::InteriorKind) // `LV.f` in doc.rs
 }
 
+impl Copy for LoanPathElem {}
+
 pub fn closure_to_block(closure_id: ast::NodeId,
                         tcx: &ty::ctxt) -> ast::NodeId {
     match tcx.map.get(closure_id) {
@@ -484,6 +493,7 @@ pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option<Rc<LoanPath<'tcx>>> {
 
 // Errors that can occur
 #[deriving(PartialEq)]
+#[allow(missing_copy_implementations)]
 pub enum bckerr_code {
     err_mutbl,
     err_out_of_scope(ty::Region, ty::Region), // superscope, subscope
@@ -505,12 +515,16 @@ pub enum AliasableViolationKind {
     BorrowViolation(euv::LoanCause)
 }
 
+impl Copy for AliasableViolationKind {}
+
 #[deriving(Show)]
 pub enum MovedValueUseKind {
     MovedInUse,
     MovedInCapture,
 }
 
+impl Copy for MovedValueUseKind {}
+
 ///////////////////////////////////////////////////////////////////////////
 // Misc
 
@@ -545,7 +559,8 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                                      use_kind: MovedValueUseKind,
                                      lp: &LoanPath<'tcx>,
                                      the_move: &move_data::Move,
-                                     moved_lp: &LoanPath<'tcx>) {
+                                     moved_lp: &LoanPath<'tcx>,
+                                     param_env: &ParameterEnvironment<'tcx>) {
         let verb = match use_kind {
             MovedInUse => "use",
             MovedInCapture => "capture",
@@ -621,7 +636,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                                                   r).as_slice())
                     }
                 };
-                let (suggestion, _) = move_suggestion(self.tcx, expr_ty,
+                let (suggestion, _) = move_suggestion(self.tcx, param_env, expr_ty,
                         ("moved by default", ""));
                 self.tcx.sess.span_note(
                     expr_span,
@@ -659,7 +674,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                                                   r).as_slice())
                     }
                 };
-                let (suggestion, help) = move_suggestion(self.tcx, expr_ty,
+                let (suggestion, help) = move_suggestion(self.tcx,
+                                                         param_env,
+                                                         expr_ty,
                         ("moved by default", "make a copy and \
                          capture that instead to override"));
                 self.tcx.sess.span_note(
@@ -674,7 +691,9 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
             }
         }
 
-        fn move_suggestion<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>,
+        fn move_suggestion<'tcx>(tcx: &ty::ctxt<'tcx>,
+                                 param_env: &ty::ParameterEnvironment<'tcx>,
+                                 ty: Ty<'tcx>,
                                  default_msgs: (&'static str, &'static str))
                                  -> (&'static str, &'static str) {
             match ty.sty {
@@ -684,7 +703,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                     }) =>
                     ("a non-copyable stack closure",
                      "capture it in a new closure, e.g. `|x| f(x)`, to override"),
-                _ if ty::type_moves_by_default(tcx, ty) =>
+                _ if ty::type_moves_by_default(tcx, ty, param_env) =>
                     ("non-copyable",
                      "perhaps you meant to use `clone()`?"),
                 _ => default_msgs,
diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs
index 7bf3458f0ae..3bb6145c5ca 100644
--- a/src/librustc/middle/borrowck/move_data.rs
+++ b/src/librustc/middle/borrowck/move_data.rs
@@ -81,6 +81,8 @@ pub struct FlowedMoveData<'a, 'tcx: 'a> {
 #[deriving(PartialEq, Eq, PartialOrd, Ord, Show)]
 pub struct MovePathIndex(uint);
 
+impl Copy for MovePathIndex {}
+
 impl MovePathIndex {
     fn get(&self) -> uint {
         let MovePathIndex(v) = *self; v
@@ -101,6 +103,8 @@ static InvalidMovePathIndex: MovePathIndex =
 #[deriving(PartialEq)]
 pub struct MoveIndex(uint);
 
+impl Copy for MoveIndex {}
+
 impl MoveIndex {
     fn get(&self) -> uint {
         let MoveIndex(v) = *self; v
@@ -138,6 +142,8 @@ pub enum MoveKind {
     Captured    // Closure creation that moves a value
 }
 
+impl Copy for MoveKind {}
+
 pub struct Move {
     /// Path being moved.
     pub path: MovePathIndex,
@@ -152,6 +158,8 @@ pub struct Move {
     pub next_move: MoveIndex
 }
 
+impl Copy for Move {}
+
 pub struct Assignment {
     /// Path being assigned.
     pub path: MovePathIndex,
@@ -163,6 +171,8 @@ pub struct Assignment {
     pub span: Span,
 }
 
+impl Copy for Assignment {}
+
 pub struct VariantMatch {
     /// downcast to the variant.
     pub path: MovePathIndex,
@@ -177,14 +187,20 @@ pub struct VariantMatch {
     pub mode: euv::MatchMode
 }
 
+impl Copy for VariantMatch {}
+
 #[deriving(Clone)]
 pub struct MoveDataFlowOperator;
 
+impl Copy for MoveDataFlowOperator {}
+
 pub type MoveDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, MoveDataFlowOperator>;
 
 #[deriving(Clone)]
 pub struct AssignDataFlowOperator;
 
+impl Copy for AssignDataFlowOperator {}
+
 pub type AssignDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, AssignDataFlowOperator>;
 
 fn loan_path_is_precise(loan_path: &LoanPath) -> bool {
diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs
index 90919609e2e..0dcb78f6bb0 100644
--- a/src/librustc/middle/cfg/construct.rs
+++ b/src/librustc/middle/cfg/construct.rs
@@ -32,6 +32,8 @@ struct LoopScope {
     break_index: CFGIndex,    // where to go on a `break
 }
 
+impl Copy for LoopScope {}
+
 pub fn construct(tcx: &ty::ctxt,
                  blk: &ast::Block) -> CFG {
     let mut graph = graph::Graph::new();
diff --git a/src/librustc/middle/cfg/mod.rs b/src/librustc/middle/cfg/mod.rs
index a2e8ba8d65c..bc512a73a4b 100644
--- a/src/librustc/middle/cfg/mod.rs
+++ b/src/librustc/middle/cfg/mod.rs
@@ -30,6 +30,8 @@ pub struct CFGNodeData {
     pub id: ast::NodeId
 }
 
+impl Copy for CFGNodeData {}
+
 pub struct CFGEdgeData {
     pub exiting_scopes: Vec<ast::NodeId>
 }
diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs
index 36742df9850..eb073e07b02 100644
--- a/src/librustc/middle/check_loop.rs
+++ b/src/librustc/middle/check_loop.rs
@@ -21,11 +21,15 @@ enum Context {
     Normal, Loop, Closure
 }
 
+impl Copy for Context {}
+
 struct CheckLoopVisitor<'a> {
     sess: &'a Session,
     cx: Context
 }
 
+impl<'a> Copy for CheckLoopVisitor<'a> {}
+
 pub fn check_crate(sess: &Session, krate: &ast::Crate) {
     visit::walk_crate(&mut CheckLoopVisitor { sess: sess, cx: Normal }, krate)
 }
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index ed119081f78..2c437ae046b 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -99,7 +99,8 @@ impl<'a> FromIterator<Vec<&'a Pat>> for Matrix<'a> {
 }
 
 pub struct MatchCheckCtxt<'a, 'tcx: 'a> {
-    pub tcx: &'a ty::ctxt<'tcx>
+    pub tcx: &'a ty::ctxt<'tcx>,
+    pub param_env: ParameterEnvironment<'tcx>,
 }
 
 #[deriving(Clone, PartialEq)]
@@ -131,6 +132,8 @@ enum WitnessPreference {
     LeaveOutWitness
 }
 
+impl Copy for WitnessPreference {}
+
 impl<'a, 'tcx, 'v> Visitor<'v> for MatchCheckCtxt<'a, 'tcx> {
     fn visit_expr(&mut self, ex: &ast::Expr) {
         check_expr(self, ex);
@@ -145,7 +148,10 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MatchCheckCtxt<'a, 'tcx> {
 }
 
 pub fn check_crate(tcx: &ty::ctxt) {
-    visit::walk_crate(&mut MatchCheckCtxt { tcx: tcx }, tcx.map.krate());
+    visit::walk_crate(&mut MatchCheckCtxt {
+        tcx: tcx,
+        param_env: ty::empty_parameter_environment(),
+    }, tcx.map.krate());
     tcx.sess.abort_if_errors();
 }
 
@@ -954,8 +960,14 @@ fn check_fn(cx: &mut MatchCheckCtxt,
             decl: &ast::FnDecl,
             body: &ast::Block,
             sp: Span,
-            _: NodeId) {
+            fn_id: NodeId) {
+    match kind {
+        visit::FkFnBlock => {}
+        _ => cx.param_env = ParameterEnvironment::for_item(cx.tcx, fn_id),
+    }
+
     visit::walk_fn(cx, kind, decl, body, sp);
+
     for input in decl.inputs.iter() {
         is_refutable(cx, &*input.pat, |pat| {
             span_err!(cx.tcx.sess, input.pat.span, E0006,
@@ -1020,7 +1032,9 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
                 match p.node {
                     ast::PatIdent(ast::BindByValue(_), _, ref sub) => {
                         let pat_ty = ty::node_id_to_type(tcx, p.id);
-                        if ty::type_moves_by_default(tcx, pat_ty) {
+                        if ty::type_moves_by_default(tcx,
+                                                      pat_ty,
+                                                      &cx.param_env) {
                             check_move(p, sub.as_ref().map(|p| &**p));
                         }
                     }
@@ -1048,7 +1062,9 @@ fn check_for_mutation_in_guard<'a, 'tcx>(cx: &'a MatchCheckCtxt<'a, 'tcx>,
     let mut checker = MutationChecker {
         cx: cx,
     };
-    let mut visitor = ExprUseVisitor::new(&mut checker, checker.cx.tcx);
+    let mut visitor = ExprUseVisitor::new(&mut checker,
+                                          checker.cx.tcx,
+                                          cx.param_env.clone());
     visitor.walk_expr(guard);
 }
 
diff --git a/src/librustc/middle/check_rvalues.rs b/src/librustc/middle/check_rvalues.rs
index dae76ba125e..a14307b90ee 100644
--- a/src/librustc/middle/check_rvalues.rs
+++ b/src/librustc/middle/check_rvalues.rs
@@ -13,6 +13,7 @@
 
 use middle::expr_use_visitor as euv;
 use middle::mem_categorization as mc;
+use middle::ty::ParameterEnvironment;
 use middle::ty;
 use util::ppaux::ty_to_string;
 
@@ -36,9 +37,10 @@ impl<'a, 'tcx, 'v> visit::Visitor<'v> for RvalueContext<'a, 'tcx> {
                 fd: &'v ast::FnDecl,
                 b: &'v ast::Block,
                 s: Span,
-                _: ast::NodeId) {
+                fn_id: ast::NodeId) {
         {
-            let mut euv = euv::ExprUseVisitor::new(self, self.tcx);
+            let param_env = ParameterEnvironment::for_item(self.tcx, fn_id);
+            let mut euv = euv::ExprUseVisitor::new(self, self.tcx, param_env);
             euv.walk_fn(fd, b);
         }
         visit::walk_fn(self, fk, fd, b, s)
diff --git a/src/librustc/middle/check_static.rs b/src/librustc/middle/check_static.rs
index 2fc85afd393..a495d1e049d 100644
--- a/src/librustc/middle/check_static.rs
+++ b/src/librustc/middle/check_static.rs
@@ -47,13 +47,16 @@ enum Mode {
     InNothing,
 }
 
+impl Copy for Mode {}
+
 struct CheckStaticVisitor<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
     mode: Mode,
     checker: &'a mut GlobalChecker,
 }
 
-struct GlobalVisitor<'a, 'b, 'tcx: 'b>(euv::ExprUseVisitor<'a, 'b, 'tcx, ty::ctxt<'tcx>>);
+struct GlobalVisitor<'a,'b,'tcx:'a+'b>(
+    euv::ExprUseVisitor<'a,'b,'tcx,ty::ctxt<'tcx>>);
 struct GlobalChecker {
     static_consumptions: NodeSet,
     const_borrows: NodeSet,
@@ -69,7 +72,8 @@ pub fn check_crate(tcx: &ty::ctxt) {
         static_local_borrows: NodeSet::new(),
     };
     {
-        let visitor = euv::ExprUseVisitor::new(&mut checker, tcx);
+        let param_env = ty::empty_parameter_environment();
+        let visitor = euv::ExprUseVisitor::new(&mut checker, tcx, param_env);
         visit::walk_crate(&mut GlobalVisitor(visitor), tcx.map.krate());
     }
     visit::walk_crate(&mut CheckStaticVisitor {
@@ -242,7 +246,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for CheckStaticVisitor<'a, 'tcx> {
     }
 }
 
-impl<'a, 'b, 't, 'v> Visitor<'v> for GlobalVisitor<'a, 'b, 't> {
+impl<'a,'b,'t,'v> Visitor<'v> for GlobalVisitor<'a,'b,'t> {
     fn visit_item(&mut self, item: &ast::Item) {
         match item.node {
             ast::ItemConst(_, ref e) |
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index 43726f55bb9..150bcbdd688 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -68,6 +68,8 @@ pub enum constness {
     non_const
 }
 
+impl Copy for constness {}
+
 type constness_cache = DefIdMap<constness>;
 
 pub fn join(a: constness, b: constness) -> constness {
diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs
index 53fea8ffc86..db8fd999f38 100644
--- a/src/librustc/middle/dataflow.rs
+++ b/src/librustc/middle/dataflow.rs
@@ -28,7 +28,12 @@ use syntax::print::{pp, pprust};
 use util::nodemap::NodeMap;
 
 #[deriving(Show)]
-pub enum EntryOrExit { Entry, Exit }
+pub enum EntryOrExit {
+    Entry,
+    Exit,
+}
+
+impl Copy for EntryOrExit {}
 
 #[deriving(Clone)]
 pub struct DataFlowContext<'a, 'tcx: 'a, O> {
diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs
index 4a4298f62f2..b3e4dd25adc 100644
--- a/src/librustc/middle/def.rs
+++ b/src/librustc/middle/def.rs
@@ -52,6 +52,8 @@ pub enum Def {
     DefMethod(ast::DefId /* method */, Option<ast::DefId> /* trait */, MethodProvenance),
 }
 
+impl Copy for Def {}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum MethodProvenance {
     FromTrait(ast::DefId),
@@ -67,6 +69,8 @@ impl MethodProvenance {
     }
 }
 
+impl Copy for MethodProvenance {}
+
 impl Def {
     pub fn def_id(&self) -> ast::DefId {
         match *self {
diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs
index dbec69f4205..8bf43c70c26 100644
--- a/src/librustc/middle/effect.rs
+++ b/src/librustc/middle/effect.rs
@@ -30,6 +30,8 @@ enum UnsafeContext {
     UnsafeBlock(ast::NodeId),
 }
 
+impl Copy for UnsafeContext {}
+
 fn type_is_unsafe_function(ty: Ty) -> bool {
     match ty.sty {
         ty::ty_bare_fn(ref f) => f.fn_style == ast::UnsafeFn,
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 7d2bb7458ac..8e00c96535b 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -23,12 +23,13 @@ use self::OverloadedCallType::*;
 use middle::{def, region, pat_util};
 use middle::mem_categorization as mc;
 use middle::mem_categorization::Typer;
-use middle::ty::{mod, Ty};
+use middle::ty::{mod, ParameterEnvironment, Ty};
 use middle::ty::{MethodCall, MethodObject, MethodTraitObject};
 use middle::ty::{MethodOrigin, MethodParam, MethodTypeParam};
 use middle::ty::{MethodStatic, MethodStaticUnboxedClosure};
 use util::ppaux::Repr;
 
+use std::kinds;
 use syntax::ast;
 use syntax::ptr::P;
 use syntax::codemap::Span;
@@ -106,12 +107,16 @@ pub enum LoanCause {
     MatchDiscriminant
 }
 
+impl kinds::Copy for LoanCause {}
+
 #[deriving(PartialEq, Show)]
 pub enum ConsumeMode {
     Copy,                // reference to x where x has a type that copies
     Move(MoveReason),    // reference to x where x has a type that moves
 }
 
+impl kinds::Copy for ConsumeMode {}
+
 #[deriving(PartialEq,Show)]
 pub enum MoveReason {
     DirectRefMove,
@@ -119,6 +124,8 @@ pub enum MoveReason {
     CaptureMove,
 }
 
+impl kinds::Copy for MoveReason {}
+
 #[deriving(PartialEq,Show)]
 pub enum MatchMode {
     NonBindingMatch,
@@ -127,11 +134,17 @@ pub enum MatchMode {
     MovingMatch,
 }
 
+impl kinds::Copy for MatchMode {}
+
 #[deriving(PartialEq,Show)]
 enum TrackMatchMode<T> {
-    Unknown, Definite(MatchMode), Conflicting,
+    Unknown,
+    Definite(MatchMode),
+    Conflicting,
 }
 
+impl<T> kinds::Copy for TrackMatchMode<T> {}
+
 impl<T> TrackMatchMode<T> {
     // Builds up the whole match mode for a pattern from its constituent
     // parts.  The lattice looks like this:
@@ -199,12 +212,16 @@ pub enum MutateMode {
     WriteAndRead, // x += y
 }
 
+impl kinds::Copy for MutateMode {}
+
 enum OverloadedCallType {
     FnOverloadedCall,
     FnMutOverloadedCall,
     FnOnceOverloadedCall,
 }
 
+impl kinds::Copy for OverloadedCallType {}
+
 impl OverloadedCallType {
     fn from_trait_id(tcx: &ty::ctxt, trait_id: ast::DefId)
                      -> OverloadedCallType {
@@ -293,6 +310,7 @@ pub struct ExprUseVisitor<'d,'t,'tcx,TYPER:'t> {
     typer: &'t TYPER,
     mc: mc::MemCategorizationContext<'t,TYPER>,
     delegate: &'d mut (Delegate<'tcx>+'d),
+    param_env: ParameterEnvironment<'tcx>,
 }
 
 // If the TYPER results in an error, it's because the type check
@@ -313,11 +331,15 @@ macro_rules! return_if_err(
 
 impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
     pub fn new(delegate: &'d mut Delegate<'tcx>,
-               typer: &'t TYPER)
+               typer: &'t TYPER,
+               param_env: ParameterEnvironment<'tcx>)
                -> ExprUseVisitor<'d,'t,'tcx,TYPER> {
-        ExprUseVisitor { typer: typer,
-                         mc: mc::MemCategorizationContext::new(typer),
-                         delegate: delegate }
+        ExprUseVisitor {
+            typer: typer,
+            mc: mc::MemCategorizationContext::new(typer),
+            delegate: delegate,
+            param_env: param_env,
+        }
     }
 
     pub fn walk_fn(&mut self,
@@ -352,7 +374,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                         consume_id: ast::NodeId,
                         consume_span: Span,
                         cmt: mc::cmt<'tcx>) {
-        let mode = copy_or_move(self.tcx(), cmt.ty, DirectRefMove);
+        let mode = copy_or_move(self.tcx(),
+                                cmt.ty,
+                                &self.param_env,
+                                DirectRefMove);
         self.delegate.consume(consume_id, consume_span, cmt, mode);
     }
 
@@ -954,7 +979,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                     ast::PatIdent(ast::BindByRef(_), _, _) =>
                         mode.lub(BorrowingMatch),
                     ast::PatIdent(ast::BindByValue(_), _, _) => {
-                        match copy_or_move(tcx, cmt_pat.ty, PatBindingMove) {
+                        match copy_or_move(tcx,
+                                           cmt_pat.ty,
+                                           &self.param_env,
+                                           PatBindingMove) {
                             Copy => mode.lub(CopyingMatch),
                             Move(_) => mode.lub(MovingMatch),
                         }
@@ -984,7 +1012,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
         let tcx = typer.tcx();
         let def_map = &self.typer.tcx().def_map;
         let delegate = &mut self.delegate;
-
+        let param_env = &mut self.param_env;
         return_if_err!(mc.cat_pattern(cmt_discr.clone(), pat, |mc, cmt_pat, pat| {
             if pat_util::pat_is_binding(def_map, pat) {
                 let tcx = typer.tcx();
@@ -1018,7 +1046,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
                                              r, bk, RefBinding);
                     }
                     ast::PatIdent(ast::BindByValue(_), _, _) => {
-                        let mode = copy_or_move(typer.tcx(), cmt_pat.ty, PatBindingMove);
+                        let mode = copy_or_move(typer.tcx(),
+                                                cmt_pat.ty,
+                                                param_env,
+                                                PatBindingMove);
                         debug!("walk_pat binding consuming pat");
                         delegate.consume_pat(pat, cmt_pat, mode);
                     }
@@ -1211,7 +1242,10 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
             let cmt_var = return_if_err!(self.cat_captured_var(closure_expr.id,
                                                                closure_expr.span,
                                                                freevar.def));
-            let mode = copy_or_move(self.tcx(), cmt_var.ty, CaptureMove);
+            let mode = copy_or_move(self.tcx(),
+                                    cmt_var.ty,
+                                    &self.param_env,
+                                    CaptureMove);
             self.delegate.consume(closure_expr.id, freevar.span, cmt_var, mode);
         }
     }
@@ -1229,8 +1263,15 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
     }
 }
 
-fn copy_or_move<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>,
-                      move_reason: MoveReason) -> ConsumeMode {
-    if ty::type_moves_by_default(tcx, ty) { Move(move_reason) } else { Copy }
+fn copy_or_move<'tcx>(tcx: &ty::ctxt<'tcx>,
+                      ty: Ty<'tcx>,
+                      param_env: &ParameterEnvironment<'tcx>,
+                      move_reason: MoveReason)
+                      -> ConsumeMode {
+    if ty::type_moves_by_default(tcx, ty, param_env) {
+        Move(move_reason)
+    } else {
+        Copy
+    }
 }
 
diff --git a/src/librustc/middle/fast_reject.rs b/src/librustc/middle/fast_reject.rs
index 888f01f9118..6780177933f 100644
--- a/src/librustc/middle/fast_reject.rs
+++ b/src/librustc/middle/fast_reject.rs
@@ -33,6 +33,8 @@ pub enum SimplifiedType {
     ParameterSimplifiedType,
 }
 
+impl Copy for SimplifiedType {}
+
 /// Tries to simplify a type by dropping type parameters, deref'ing away any reference types, etc.
 /// The idea is to get something simple that we can use to quickly decide if two types could unify
 /// during method lookup.
diff --git a/src/librustc/middle/graph.rs b/src/librustc/middle/graph.rs
index 2f50a964023..e45232a3c30 100644
--- a/src/librustc/middle/graph.rs
+++ b/src/librustc/middle/graph.rs
@@ -65,11 +65,15 @@ pub struct NodeIndex(pub uint);
 #[allow(non_upper_case_globals)]
 pub const InvalidNodeIndex: NodeIndex = NodeIndex(uint::MAX);
 
+impl Copy for NodeIndex {}
+
 #[deriving(PartialEq, Show)]
 pub struct EdgeIndex(pub uint);
 #[allow(non_upper_case_globals)]
 pub const InvalidEdgeIndex: EdgeIndex = EdgeIndex(uint::MAX);
 
+impl Copy for EdgeIndex {}
+
 // Use a private field here to guarantee no more instances are created:
 #[deriving(Show)]
 pub struct Direction { repr: uint }
@@ -78,6 +82,8 @@ pub const Outgoing: Direction = Direction { repr: 0 };
 #[allow(non_upper_case_globals)]
 pub const Incoming: Direction = Direction { repr: 1 };
 
+impl Copy for Direction {}
+
 impl NodeIndex {
     fn get(&self) -> uint { let NodeIndex(v) = *self; v }
     /// Returns unique id (unique with respect to the graph holding associated node).
diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs
index c5845b143af..81cd8dd20d2 100644
--- a/src/librustc/middle/infer/mod.rs
+++ b/src/librustc/middle/infer/mod.rs
@@ -132,6 +132,8 @@ pub enum TypeOrigin {
     IfExpressionWithNoElse(Span)
 }
 
+impl Copy for TypeOrigin {}
+
 /// See `error_reporting.rs` for more details
 #[deriving(Clone, Show)]
 pub enum ValuePairs<'tcx> {
@@ -237,6 +239,8 @@ pub enum LateBoundRegionConversionTime {
     HigherRankedType,
 }
 
+impl Copy for LateBoundRegionConversionTime {}
+
 /// Reasons to create a region inference variable
 ///
 /// See `error_reporting.rs` for more details
@@ -280,6 +284,8 @@ pub enum fixup_err {
     unresolved_ty(TyVid)
 }
 
+impl Copy for fixup_err {}
+
 pub fn fixup_err_to_string(f: fixup_err) -> String {
     match f {
       unresolved_int_ty(_) => {
diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs
index 9155c18cb3b..391e37e8b9c 100644
--- a/src/librustc/middle/infer/region_inference/mod.rs
+++ b/src/librustc/middle/infer/region_inference/mod.rs
@@ -51,6 +51,8 @@ pub enum Constraint {
     ConstrainVarSubReg(RegionVid, Region),
 }
 
+impl Copy for Constraint {}
+
 // Something we have to verify after region inference is done, but
 // which does not directly influence the inference process
 pub enum Verify<'tcx> {
@@ -72,6 +74,8 @@ pub struct TwoRegions {
     b: Region,
 }
 
+impl Copy for TwoRegions {}
+
 #[deriving(PartialEq)]
 pub enum UndoLogEntry {
     OpenSnapshot,
@@ -84,11 +88,15 @@ pub enum UndoLogEntry {
     AddCombination(CombineMapType, TwoRegions)
 }
 
+impl Copy for UndoLogEntry {}
+
 #[deriving(PartialEq)]
 pub enum CombineMapType {
     Lub, Glb
 }
 
+impl Copy for CombineMapType {}
+
 #[deriving(Clone, Show)]
 pub enum RegionResolutionError<'tcx> {
     /// `ConcreteFailure(o, a, b)`:
@@ -220,11 +228,15 @@ pub struct RegionSnapshot {
     length: uint
 }
 
+impl Copy for RegionSnapshot {}
+
 #[deriving(Show)]
 pub struct RegionMark {
     length: uint
 }
 
+impl Copy for RegionMark {}
+
 impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
     pub fn new(tcx: &'a ty::ctxt<'tcx>) -> RegionVarBindings<'a, 'tcx> {
         RegionVarBindings {
@@ -926,8 +938,12 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
 #[deriving(PartialEq, Show)]
 enum Classification { Expanding, Contracting }
 
+impl Copy for Classification {}
+
 pub enum VarValue { NoValue, Value(Region), ErrorValue }
 
+impl Copy for VarValue {}
+
 struct VarData {
     classification: Classification,
     value: VarValue,
diff --git a/src/librustc/middle/infer/type_variable.rs b/src/librustc/middle/infer/type_variable.rs
index 3058f09a83a..766e930486c 100644
--- a/src/librustc/middle/infer/type_variable.rs
+++ b/src/librustc/middle/infer/type_variable.rs
@@ -49,6 +49,8 @@ pub enum RelationDir {
     SubtypeOf, SupertypeOf, EqTo
 }
 
+impl Copy for RelationDir {}
+
 impl RelationDir {
     fn opposite(self) -> RelationDir {
         match self {
diff --git a/src/librustc/middle/infer/unify.rs b/src/librustc/middle/infer/unify.rs
index 6f6adb84a75..a2dd4d62913 100644
--- a/src/librustc/middle/infer/unify.rs
+++ b/src/librustc/middle/infer/unify.rs
@@ -92,6 +92,8 @@ pub struct Node<K,V> {
 
 pub struct Delegate;
 
+impl Copy for Delegate {}
+
 // We can't use V:LatticeValue, much as I would like to,
 // because frequently the pattern is that V=Option<U> for some
 // other type parameter U, and we have no way to say
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index da1c0bd649a..4a20c92d8e2 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -50,6 +50,8 @@ pub enum LangItem {
     $($variant),*
 }
 
+impl Copy for LangItem {}
+
 pub struct LanguageItems {
     pub items: Vec<Option<ast::DefId>>,
     pub missing: Vec<LangItem>,
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index a6d3c15df8a..5edbafc4e0b 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -137,9 +137,14 @@ enum LoopKind<'a> {
 
 #[deriving(PartialEq)]
 struct Variable(uint);
+
+impl Copy for Variable {}
+
 #[deriving(PartialEq)]
 struct LiveNode(uint);
 
+impl Copy for LiveNode {}
+
 impl Variable {
     fn get(&self) -> uint { let Variable(v) = *self; v }
 }
@@ -162,6 +167,8 @@ enum LiveNodeKind {
     ExitNode
 }
 
+impl Copy for LiveNodeKind {}
+
 fn live_node_kind_to_string(lnk: LiveNodeKind, cx: &ty::ctxt) -> String {
     let cm = cx.sess.codemap();
     match lnk {
@@ -246,6 +253,8 @@ struct LocalInfo {
     ident: ast::Ident
 }
 
+impl Copy for LocalInfo {}
+
 #[deriving(Show)]
 enum VarKind {
     Arg(NodeId, ast::Ident),
@@ -254,6 +263,8 @@ enum VarKind {
     CleanExit
 }
 
+impl Copy for VarKind {}
+
 struct IrMaps<'a, 'tcx: 'a> {
     tcx: &'a ty::ctxt<'tcx>,
 
@@ -532,6 +543,8 @@ struct Users {
     used: bool
 }
 
+impl Copy for Users {}
+
 fn invalid_users() -> Users {
     Users {
         reader: invalid_node(),
@@ -547,6 +560,8 @@ struct Specials {
     clean_exit_var: Variable
 }
 
+impl Copy for Specials {}
+
 static ACC_READ: uint = 1u;
 static ACC_WRITE: uint = 2u;
 static ACC_USE: uint = 4u;
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index cd70d8e2b48..302fbd53dd5 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -110,6 +110,8 @@ pub struct Upvar {
     pub is_unboxed: bool
 }
 
+impl Copy for Upvar {}
+
 // different kinds of pointers:
 #[deriving(Clone, PartialEq, Eq, Hash, Show)]
 pub enum PointerKind {
@@ -119,6 +121,8 @@ pub enum PointerKind {
     UnsafePtr(ast::Mutability)
 }
 
+impl Copy for PointerKind {}
+
 // We use the term "interior" to mean "something reachable from the
 // base without a pointer dereference", e.g. a field
 #[deriving(Clone, PartialEq, Eq, Hash, Show)]
@@ -127,18 +131,24 @@ pub enum InteriorKind {
     InteriorElement(ElementKind),
 }
 
+impl Copy for InteriorKind {}
+
 #[deriving(Clone, PartialEq, Eq, Hash, Show)]
 pub enum FieldName {
     NamedField(ast::Name),
     PositionalField(uint)
 }
 
+impl Copy for FieldName {}
+
 #[deriving(Clone, PartialEq, Eq, Hash, Show)]
 pub enum ElementKind {
     VecElement,
     OtherElement,
 }
 
+impl Copy for ElementKind {}
+
 #[deriving(Clone, PartialEq, Eq, Hash, Show)]
 pub enum MutabilityCategory {
     McImmutable, // Immutable.
@@ -146,6 +156,8 @@ pub enum MutabilityCategory {
     McInherited, // Inherited from the fact that owner is mutable.
 }
 
+impl Copy for MutabilityCategory {}
+
 // A note about the provenance of a `cmt`.  This is used for
 // special-case handling of upvars such as mutability inference.
 // Upvar categorization can generate a variable number of nested
@@ -158,6 +170,8 @@ pub enum Note {
     NoteNone                     // Nothing special
 }
 
+impl Copy for Note {}
+
 // `cmt`: "Category, Mutability, and Type".
 //
 // a complete categorization of a value indicating where it originated
@@ -191,6 +205,8 @@ pub enum deref_kind {
     deref_interior(InteriorKind),
 }
 
+impl Copy for deref_kind {}
+
 // Categorizes a derefable type.  Note that we include vectors and strings as
 // derefable (we model an index as the combination of a deref and then a
 // pointer adjustment).
@@ -261,6 +277,8 @@ pub struct MemCategorizationContext<'t,TYPER:'t> {
     typer: &'t TYPER
 }
 
+impl<'t,TYPER:'t> Copy for MemCategorizationContext<'t,TYPER> {}
+
 pub type McResult<T> = Result<T, ()>;
 
 /// The `Typer` trait provides the interface for the mem-categorization
@@ -1384,6 +1402,8 @@ pub enum InteriorSafety {
     InteriorSafe
 }
 
+impl Copy for InteriorSafety {}
+
 pub enum AliasableReason {
     AliasableBorrowed,
     AliasableClosure(ast::NodeId), // Aliasable due to capture Fn closure env
@@ -1392,6 +1412,8 @@ pub enum AliasableReason {
     AliasableStaticMut(InteriorSafety),
 }
 
+impl Copy for AliasableReason {}
+
 impl<'tcx> cmt_<'tcx> {
     pub fn guarantor(&self) -> cmt<'tcx> {
         //! Returns `self` after stripping away any owned pointer derefs or
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index 2b8dd8df249..370097004e9 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -41,6 +41,8 @@ pub enum CodeExtent {
     Misc(ast::NodeId)
 }
 
+impl Copy for CodeExtent {}
+
 impl CodeExtent {
     /// Creates a scope that represents the dynamic extent associated
     /// with `node_id`.
@@ -120,6 +122,8 @@ pub struct Context {
     parent: Option<ast::NodeId>,
 }
 
+impl Copy for Context {}
+
 struct RegionResolutionVisitor<'a> {
     sess: &'a Session,
 
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 8c3aa22c5fc..36b87bbd423 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -94,6 +94,8 @@ struct binding_info {
     binding_mode: BindingMode,
 }
 
+impl Copy for binding_info {}
+
 // Map from the name in a pattern to its binding mode.
 type BindingMap = HashMap<Name,binding_info>;
 
@@ -130,12 +132,16 @@ pub enum LastPrivate {
                type_used: ImportUse},
 }
 
+impl Copy for LastPrivate {}
+
 #[deriving(Show)]
 pub enum PrivateDep {
     AllPublic,
     DependsOn(DefId),
 }
 
+impl Copy for PrivateDep {}
+
 // How an import is used.
 #[deriving(PartialEq, Show)]
 pub enum ImportUse {
@@ -143,6 +149,8 @@ pub enum ImportUse {
     Used,         // The import is used.
 }
 
+impl Copy for ImportUse {}
+
 impl LastPrivate {
     fn or(self, other: LastPrivate) -> LastPrivate {
         match (self, other) {
@@ -159,12 +167,16 @@ enum PatternBindingMode {
     ArgumentIrrefutableMode,
 }
 
+impl Copy for PatternBindingMode {}
+
 #[deriving(PartialEq, Eq, Hash, Show)]
 enum Namespace {
     TypeNS,
     ValueNS
 }
 
+impl Copy for Namespace {}
+
 #[deriving(PartialEq)]
 enum NamespaceError {
     NoError,
@@ -173,6 +185,8 @@ enum NamespaceError {
     ValueError
 }
 
+impl Copy for NamespaceError {}
+
 /// A NamespaceResult represents the result of resolving an import in
 /// a particular namespace. The result is either definitely-resolved,
 /// definitely- unresolved, or unknown.
@@ -238,6 +252,8 @@ enum ImportDirectiveSubclass {
     GlobImport
 }
 
+impl Copy for ImportDirectiveSubclass {}
+
 /// The context that we thread through while building the reduced graph.
 #[deriving(Clone)]
 enum ReducedGraphParent {
@@ -294,6 +310,8 @@ enum TypeParameters<'a> {
         RibKind)
 }
 
+impl<'a> Copy for TypeParameters<'a> {}
+
 // The rib kind controls the translation of local
 // definitions (`DefLocal`) to upvars (`DefUpvar`).
 
@@ -319,17 +337,23 @@ enum RibKind {
     ConstantItemRibKind
 }
 
+impl Copy for RibKind {}
+
 // Methods can be required or provided. RequiredMethod methods only occur in traits.
 enum MethodSort {
     RequiredMethod,
     ProvidedMethod(NodeId)
 }
 
+impl Copy for MethodSort {}
+
 enum UseLexicalScopeFlag {
     DontUseLexicalScope,
     UseLexicalScope
 }
 
+impl Copy for UseLexicalScopeFlag {}
+
 enum ModulePrefixResult {
     NoPrefixFound,
     PrefixFound(Rc<Module>, uint)
@@ -342,6 +366,8 @@ pub enum TraitItemKind {
     TypeTraitItemKind,
 }
 
+impl Copy for TraitItemKind {}
+
 impl TraitItemKind {
     pub fn from_explicit_self_category(explicit_self_category:
                                        ExplicitSelfCategory)
@@ -364,12 +390,16 @@ enum NameSearchType {
     PathSearch,
 }
 
+impl Copy for NameSearchType {}
+
 enum BareIdentifierPatternResolution {
     FoundStructOrEnumVariant(Def, LastPrivate),
     FoundConst(Def, LastPrivate),
     BareIdentifierPatternUnresolved
 }
 
+impl Copy for BareIdentifierPatternResolution {}
+
 // Specifies how duplicates should be handled when adding a child item if
 // another item exists with the same name in some namespace.
 #[deriving(PartialEq)]
@@ -381,6 +411,8 @@ enum DuplicateCheckingMode {
     OverwriteDuplicates
 }
 
+impl Copy for DuplicateCheckingMode {}
+
 /// One local scope.
 struct Rib {
     bindings: HashMap<Name, DefLike>,
@@ -518,6 +550,8 @@ enum ModuleKind {
     AnonymousModuleKind,
 }
 
+impl Copy for ModuleKind {}
+
 /// One node in the tree of modules.
 struct Module {
     parent_link: ParentLink,
@@ -599,6 +633,8 @@ bitflags! {
     }
 }
 
+impl Copy for DefModifiers {}
+
 // Records a possibly-private type definition.
 #[deriving(Clone)]
 struct TypeNsDef {
@@ -616,6 +652,8 @@ struct ValueNsDef {
     value_span: Option<Span>,
 }
 
+impl Copy for ValueNsDef {}
+
 // Records the definitions (at most one for each namespace) that a name is
 // bound to.
 struct NameBindings {
@@ -632,6 +670,8 @@ enum TraitReferenceType {
     TraitQPath,                      // <T as SomeTrait>::
 }
 
+impl Copy for TraitReferenceType {}
+
 impl NameBindings {
     fn new() -> NameBindings {
         NameBindings {
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index bd8db1d51df..2ba9ba5631d 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -46,6 +46,8 @@ pub enum DefRegion {
                   /* lifetime decl */ ast::NodeId),
 }
 
+impl Copy for DefRegion {}
+
 // maps the id of each lifetime reference to the lifetime decl
 // that it corresponds to
 pub type NamedRegionMap = NodeMap<DefRegion>;
diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs
index 21f57a9d573..bcc762a9640 100644
--- a/src/librustc/middle/subst.rs
+++ b/src/librustc/middle/subst.rs
@@ -190,6 +190,8 @@ pub enum ParamSpace {
     FnSpace,    // Type parameters attached to a method or fn
 }
 
+impl Copy for ParamSpace {}
+
 impl ParamSpace {
     pub fn all() -> [ParamSpace, ..4] {
         [TypeSpace, SelfSpace, AssocSpace, FnSpace]
diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs
index e12ec44ad87..d410a456dc9 100644
--- a/src/librustc/middle/traits/mod.rs
+++ b/src/librustc/middle/traits/mod.rs
@@ -60,6 +60,8 @@ pub struct ObligationCause<'tcx> {
     pub code: ObligationCauseCode<'tcx>
 }
 
+impl<'tcx> Copy for ObligationCause<'tcx> {}
+
 #[deriving(Clone)]
 pub enum ObligationCauseCode<'tcx> {
     /// Not well classified or should be obvious from span.
@@ -95,6 +97,8 @@ pub enum ObligationCauseCode<'tcx> {
 
 pub type Obligations<'tcx> = subst::VecPerParamSpace<Obligation<'tcx>>;
 
+impl<'tcx> Copy for ObligationCauseCode<'tcx> {}
+
 pub type Selection<'tcx> = Vtable<'tcx, Obligation<'tcx>>;
 
 #[deriving(Clone,Show)]
@@ -338,7 +342,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
             VtableFnPointer(ref sig) => VtableFnPointer((*sig).clone()),
             VtableUnboxedClosure(d, ref s) => VtableUnboxedClosure(d, s.clone()),
             VtableParam(ref p) => VtableParam((*p).clone()),
-            VtableBuiltin(ref i) => VtableBuiltin(i.map_nested(op)),
+            VtableBuiltin(ref b) => VtableBuiltin(b.map_nested(op)),
         }
     }
 
@@ -348,7 +352,7 @@ impl<'tcx, N> Vtable<'tcx, N> {
             VtableFnPointer(sig) => VtableFnPointer(sig),
             VtableUnboxedClosure(d, s) => VtableUnboxedClosure(d, s),
             VtableParam(p) => VtableParam(p),
-            VtableBuiltin(i) => VtableBuiltin(i.map_move_nested(op)),
+            VtableBuiltin(no) => VtableBuiltin(no.map_move_nested(op)),
         }
     }
 }
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index 0e6a0c19f70..5ad0d17ad13 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -80,6 +80,7 @@ struct ObligationStack<'prev, 'tcx: 'prev> {
     previous: Option<&'prev ObligationStack<'prev, 'tcx>>
 }
 
+#[deriving(Clone)]
 pub struct SelectionCache<'tcx> {
     hashmap: RefCell<HashMap<Rc<ty::TraitRef<'tcx>>,
                              SelectionResult<'tcx, Candidate<'tcx>>>>,
@@ -102,6 +103,8 @@ pub enum MethodMatchedData {
     CoerciveMethodMatch(/* impl we matched */ ast::DefId)
 }
 
+impl Copy for MethodMatchedData {}
+
 /// The selection process begins by considering all impls, where
 /// clauses, and so forth that might resolve an obligation.  Sometimes
 /// we'll be able to say definitively that (e.g.) an impl does not
@@ -918,20 +921,31 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // and applicable impls. There is a certain set of precedence rules here.
 
         match self.tcx().lang_items.to_builtin_kind(obligation.trait_ref.def_id) {
-            Some(bound) => {
-                try!(self.assemble_builtin_bound_candidates(bound, stack, &mut candidates));
+            Some(ty::BoundCopy) => {
+                debug!("obligation self ty is {}",
+                       obligation.self_ty().repr(self.tcx()));
+                try!(self.assemble_candidates_from_impls(obligation, &mut candidates));
+                try!(self.assemble_builtin_bound_candidates(ty::BoundCopy,
+                                                            stack,
+                                                            &mut candidates));
             }
 
             None => {
-                // For the time being, we ignore user-defined impls for builtin-bounds.
+                // For the time being, we ignore user-defined impls for builtin-bounds, other than
+                // `Copy`.
                 // (And unboxed candidates only apply to the Fn/FnMut/etc traits.)
                 try!(self.assemble_unboxed_closure_candidates(obligation, &mut candidates));
                 try!(self.assemble_fn_pointer_candidates(obligation, &mut candidates));
                 try!(self.assemble_candidates_from_impls(obligation, &mut candidates));
             }
+
+            Some(bound) => {
+                try!(self.assemble_builtin_bound_candidates(bound, stack, &mut candidates));
+            }
         }
 
         try!(self.assemble_candidates_from_caller_bounds(obligation, &mut candidates));
+        debug!("candidate list size: {}", candidates.vec.len());
         Ok(candidates)
     }
 
@@ -1519,13 +1533,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 }
 
                 ty::BoundCopy => {
-                    if
-                        Some(def_id) == tcx.lang_items.no_copy_bound() ||
-                        Some(def_id) == tcx.lang_items.managed_bound() ||
-                        ty::has_dtor(tcx, def_id)
-                    {
-                        return Err(Unimplemented);
-                    }
+                    // This is an Opt-In Built-In Trait.
+                    return Ok(ParameterBuiltin)
                 }
 
                 ty::BoundSync => {
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index 8a2529701bb..4c4b5d07f50 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -38,6 +38,7 @@ pub use self::IntVarValue::*;
 pub use self::ExprAdjustment::*;
 pub use self::vtable_origin::*;
 pub use self::MethodOrigin::*;
+pub use self::CopyImplementationError::*;
 
 use back::svh::Svh;
 use session::Session;
@@ -52,8 +53,10 @@ use middle::mem_categorization as mc;
 use middle::region;
 use middle::resolve;
 use middle::resolve_lifetime;
+use middle::infer;
 use middle::stability;
 use middle::subst::{mod, Subst, Substs, VecPerParamSpace};
+use middle::traits::ObligationCause;
 use middle::traits;
 use middle::ty;
 use middle::ty_fold::{mod, TypeFoldable, TypeFolder, HigherRankedFoldable};
@@ -72,7 +75,7 @@ use std::hash::{Hash, sip, Writer};
 use std::mem;
 use std::ops;
 use std::rc::Rc;
-use std::collections::hash_map::{Occupied, Vacant};
+use std::collections::hash_map::{HashMap, Occupied, Vacant};
 use arena::TypedArena;
 use syntax::abi;
 use syntax::ast::{CrateNum, DefId, FnStyle, Ident, ItemTrait, LOCAL_CRATE};
@@ -81,7 +84,7 @@ use syntax::ast::{Onceness, StmtExpr, StmtSemi, StructField, UnnamedField};
 use syntax::ast::{Visibility};
 use syntax::ast_util::{mod, is_local, lit_is_str, local_def, PostExpansionMethod};
 use syntax::attr::{mod, AttrMetaMethods};
-use syntax::codemap::Span;
+use syntax::codemap::{DUMMY_SP, Span};
 use syntax::parse::token::{mod, InternedString};
 use syntax::{ast, ast_map};
 use std::collections::enum_set::{EnumSet, CLike};
@@ -109,12 +112,16 @@ pub struct field<'tcx> {
     pub mt: mt<'tcx>
 }
 
+impl<'tcx> Copy for field<'tcx> {}
+
 #[deriving(Clone, Show)]
 pub enum ImplOrTraitItemContainer {
     TraitContainer(ast::DefId),
     ImplContainer(ast::DefId),
 }
 
+impl Copy for ImplOrTraitItemContainer {}
+
 impl ImplOrTraitItemContainer {
     pub fn id(&self) -> ast::DefId {
         match *self {
@@ -175,6 +182,8 @@ pub enum ImplOrTraitItemId {
     TypeTraitItemId(ast::DefId),
 }
 
+impl Copy for ImplOrTraitItemId {}
+
 impl ImplOrTraitItemId {
     pub fn def_id(&self) -> ast::DefId {
         match *self {
@@ -236,12 +245,16 @@ pub struct AssociatedType {
     pub container: ImplOrTraitItemContainer,
 }
 
+impl Copy for AssociatedType {}
+
 #[deriving(Clone, PartialEq, Eq, Hash, Show)]
 pub struct mt<'tcx> {
     pub ty: Ty<'tcx>,
     pub mutbl: ast::Mutability,
 }
 
+impl<'tcx> Copy for mt<'tcx> {}
+
 #[deriving(Clone, PartialEq, Eq, Hash, Encodable, Decodable, Show)]
 pub enum TraitStore {
     /// Box<Trait>
@@ -250,6 +263,8 @@ pub enum TraitStore {
     RegionTraitStore(Region, ast::Mutability),
 }
 
+impl Copy for TraitStore {}
+
 #[deriving(Clone, Show)]
 pub struct field_ty {
     pub name: Name,
@@ -258,6 +273,8 @@ pub struct field_ty {
     pub origin: ast::DefId,  // The DefId of the struct in which the field is declared.
 }
 
+impl Copy for field_ty {}
+
 // Contains information needed to resolve types and (in the future) look up
 // the types of AST nodes.
 #[deriving(PartialEq, Eq, Hash)]
@@ -267,11 +284,15 @@ pub struct creader_cache_key {
     pub len: uint
 }
 
+impl Copy for creader_cache_key {}
+
 pub enum ast_ty_to_ty_cache_entry<'tcx> {
     atttce_unresolved,  /* not resolved yet */
     atttce_resolved(Ty<'tcx>)  /* resolved to a type, irrespective of region */
 }
 
+impl<'tcx> Copy for ast_ty_to_ty_cache_entry<'tcx> {}
+
 #[deriving(Clone, PartialEq, Decodable, Encodable)]
 pub struct ItemVariances {
     pub types: VecPerParamSpace<Variance>,
@@ -286,6 +307,8 @@ pub enum Variance {
     Bivariant,      // T<A> <: T<B>            -- e.g., unused type parameter
 }
 
+impl Copy for Variance {}
+
 #[deriving(Clone, Show)]
 pub enum AutoAdjustment<'tcx> {
     AdjustAddEnv(ty::TraitStore),
@@ -431,6 +454,8 @@ pub struct param_index {
     pub index: uint
 }
 
+impl Copy for param_index {}
+
 #[deriving(Clone, Show)]
 pub enum MethodOrigin<'tcx> {
     // fully statically resolved method
@@ -485,6 +510,8 @@ pub struct MethodCallee<'tcx> {
     pub substs: subst::Substs<'tcx>
 }
 
+impl Copy for MethodCall {}
+
 /// With method calls, we store some extra information in
 /// side tables (i.e method_map). We use
 /// MethodCall as a key to index into these tables instead of
@@ -510,6 +537,8 @@ pub enum ExprAdjustment {
     AutoObject
 }
 
+impl Copy for ExprAdjustment {}
+
 impl MethodCall {
     pub fn expr(id: ast::NodeId) -> MethodCall {
         MethodCall {
@@ -594,6 +623,8 @@ pub struct TransmuteRestriction<'tcx> {
     pub id: ast::NodeId,
 }
 
+impl<'tcx> Copy for TransmuteRestriction<'tcx> {}
+
 /// The data structure to keep track of all the information that typechecker
 /// generates so that so that it can be reused and doesn't have to be redone
 /// later on.
@@ -746,6 +777,9 @@ pub struct ctxt<'tcx> {
 
     /// Caches the representation hints for struct definitions.
     pub repr_hint_cache: RefCell<DefIdMap<Rc<Vec<attr::ReprAttr>>>>,
+
+    /// Caches whether types move by default.
+    pub type_moves_by_default_cache: RefCell<HashMap<Ty<'tcx>,bool>>,
 }
 
 // Flags that we track on types. These flags are propagated upwards
@@ -766,6 +800,8 @@ bitflags! {
     }
 }
 
+impl Copy for TypeFlags {}
+
 #[deriving(Show)]
 pub struct TyS<'tcx> {
     pub sty: sty<'tcx>,
@@ -807,6 +843,7 @@ impl<'tcx> PartialEq for InternedTy<'tcx> {
         self.ty.sty == other.ty.sty
     }
 }
+
 impl<'tcx> Eq for InternedTy<'tcx> {}
 
 impl<'tcx, S: Writer> Hash<S> for InternedTy<'tcx> {
@@ -900,6 +937,8 @@ impl<'tcx> FnOutput<'tcx> {
     }
 }
 
+impl<'tcx> Copy for FnOutput<'tcx> {}
+
 /// Signature of a function type, which I have arbitrarily
 /// decided to use to refer to the input/output types.
 ///
@@ -924,6 +963,8 @@ pub struct ParamTy {
     pub def_id: DefId
 }
 
+impl Copy for ParamTy {}
+
 /// A [De Bruijn index][dbi] is a standard means of representing
 /// regions (and perhaps later types) in a higher-ranked setting. In
 /// particular, imagine a type like this:
@@ -1018,6 +1059,8 @@ pub struct UpvarId {
     pub closure_expr_id: ast::NodeId,
 }
 
+impl Copy for UpvarId {}
+
 #[deriving(Clone, PartialEq, Eq, Hash, Show, Encodable, Decodable)]
 pub enum BorrowKind {
     /// Data must be immutable and is aliasable.
@@ -1064,6 +1107,8 @@ pub enum BorrowKind {
     MutBorrow
 }
 
+impl Copy for BorrowKind {}
+
 /// Information describing the borrowing of an upvar. This is computed
 /// during `typeck`, specifically by `regionck`. The general idea is
 /// that the compiler analyses treat closures like:
@@ -1119,6 +1164,8 @@ pub struct UpvarBorrow {
 
 pub type UpvarBorrowMap = FnvHashMap<UpvarId, UpvarBorrow>;
 
+impl Copy for UpvarBorrow {}
+
 impl Region {
     pub fn is_bound(&self) -> bool {
         match *self {
@@ -1136,6 +1183,8 @@ impl Region {
     }
 }
 
+impl Copy for Region {}
+
 #[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Encodable, Decodable, Show)]
 /// A "free" region `fr` can be interpreted as "some region
 /// at least as big as the scope `fr.scope`".
@@ -1144,6 +1193,8 @@ pub struct FreeRegion {
     pub bound_region: BoundRegion
 }
 
+impl Copy for FreeRegion {}
+
 #[deriving(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Encodable, Decodable, Show)]
 pub enum BoundRegion {
     /// An anonymous region parameter for a given fn (&T)
@@ -1163,6 +1214,8 @@ pub enum BoundRegion {
     BrEnv
 }
 
+impl Copy for BoundRegion {}
+
 #[inline]
 pub fn mk_prim_t<'tcx>(primitive: &'tcx TyS<'static>) -> Ty<'tcx> {
     // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx.
@@ -1302,6 +1355,8 @@ pub enum IntVarValue {
     UintType(ast::UintTy),
 }
 
+impl Copy for IntVarValue {}
+
 #[deriving(Clone, Show)]
 pub enum terr_vstore_kind {
     terr_vec,
@@ -1310,12 +1365,16 @@ pub enum terr_vstore_kind {
     terr_trait
 }
 
+impl Copy for terr_vstore_kind {}
+
 #[deriving(Clone, Show)]
 pub struct expected_found<T> {
     pub expected: T,
     pub found: T
 }
 
+impl<T:Copy> Copy for expected_found<T> {}
+
 // Data structures used in type unification
 #[deriving(Clone, Show)]
 pub enum type_err<'tcx> {
@@ -1350,6 +1409,8 @@ pub enum type_err<'tcx> {
     terr_convergence_mismatch(expected_found<bool>)
 }
 
+impl<'tcx> Copy for type_err<'tcx> {}
+
 /// Bounds suitable for a named type parameter like `A` in `fn foo<A>`
 /// as well as the existential type parameter in an object type.
 #[deriving(PartialEq, Eq, Hash, Clone, Show)]
@@ -1370,6 +1431,8 @@ pub struct ExistentialBounds {
     pub builtin_bounds: BuiltinBounds
 }
 
+impl Copy for ExistentialBounds {}
+
 pub type BuiltinBounds = EnumSet<BuiltinBound>;
 
 #[deriving(Clone, Encodable, PartialEq, Eq, Decodable, Hash, Show)]
@@ -1381,6 +1444,8 @@ pub enum BuiltinBound {
     BoundSync,
 }
 
+impl Copy for BuiltinBound {}
+
 pub fn empty_builtin_bounds() -> BuiltinBounds {
     EnumSet::new()
 }
@@ -1413,21 +1478,29 @@ pub struct TyVid {
     pub index: uint
 }
 
+impl Copy for TyVid {}
+
 #[deriving(Clone, PartialEq, Eq, Hash)]
 pub struct IntVid {
     pub index: uint
 }
 
+impl Copy for IntVid {}
+
 #[deriving(Clone, PartialEq, Eq, Hash)]
 pub struct FloatVid {
     pub index: uint
 }
 
+impl Copy for FloatVid {}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub struct RegionVid {
     pub index: uint
 }
 
+impl Copy for RegionVid {}
+
 #[deriving(Clone, PartialEq, Eq, Hash)]
 pub enum InferTy {
     TyVar(TyVid),
@@ -1441,12 +1514,16 @@ pub enum InferTy {
     SkolemizedIntTy(uint),
 }
 
+impl Copy for InferTy {}
+
 #[deriving(Clone, Encodable, Decodable, Eq, Hash, Show)]
 pub enum InferRegion {
     ReVar(RegionVid),
     ReSkolemized(uint, BoundRegion)
 }
 
+impl Copy for InferRegion {}
+
 impl cmp::PartialEq for InferRegion {
     fn eq(&self, other: &InferRegion) -> bool {
         match ((*self), *other) {
@@ -1642,6 +1719,7 @@ impl<'tcx> TraitRef<'tcx> {
 /// bound lifetime parameters are replaced with free ones, but in the
 /// future I hope to refine the representation of types so as to make
 /// more distinctions clearer.
+#[deriving(Clone)]
 pub struct ParameterEnvironment<'tcx> {
     /// A substitution that can be applied to move from
     /// the "outer" view of a type or method to the "inner" view.
@@ -1690,14 +1768,14 @@ impl<'tcx> ParameterEnvironment<'tcx> {
                             }
                             TypeTraitItem(_) => {
                                 cx.sess
-                                  .bug("ParameterEnvironment::from_item(): \
+                                  .bug("ParameterEnvironment::for_item(): \
                                         can't create a parameter environment \
                                         for type trait items")
                             }
                         }
                     }
                     ast::TypeImplItem(_) => {
-                        cx.sess.bug("ParameterEnvironment::from_item(): \
+                        cx.sess.bug("ParameterEnvironment::for_item(): \
                                      can't create a parameter environment \
                                      for type impl items")
                     }
@@ -1707,7 +1785,7 @@ impl<'tcx> ParameterEnvironment<'tcx> {
                 match *trait_method {
                     ast::RequiredMethod(ref required) => {
                         cx.sess.span_bug(required.span,
-                                         "ParameterEnvironment::from_item():
+                                         "ParameterEnvironment::for_item():
                                           can't create a parameter \
                                           environment for required trait \
                                           methods")
@@ -1725,7 +1803,7 @@ impl<'tcx> ParameterEnvironment<'tcx> {
                             }
                             TypeTraitItem(_) => {
                                 cx.sess
-                                  .bug("ParameterEnvironment::from_item(): \
+                                  .bug("ParameterEnvironment::for_item(): \
                                         can't create a parameter environment \
                                         for type trait items")
                             }
@@ -1768,6 +1846,10 @@ impl<'tcx> ParameterEnvironment<'tcx> {
                     }
                 }
             }
+            Some(ast_map::NodeExpr(..)) => {
+                // This is a convenience to allow closures to work.
+                ParameterEnvironment::for_item(cx, cx.map.get_parent(id))
+            }
             _ => {
                 cx.sess.bug(format!("ParameterEnvironment::from_item(): \
                                      `{}` is not an item",
@@ -1825,6 +1907,8 @@ pub enum UnboxedClosureKind {
     FnOnceUnboxedClosureKind,
 }
 
+impl Copy for UnboxedClosureKind {}
+
 impl UnboxedClosureKind {
     pub fn trait_did(&self, cx: &ctxt) -> ast::DefId {
         let result = match *self {
@@ -1909,6 +1993,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
         associated_types: RefCell::new(DefIdMap::new()),
         selection_cache: traits::SelectionCache::new(),
         repr_hint_cache: RefCell::new(DefIdMap::new()),
+        type_moves_by_default_cache: RefCell::new(HashMap::new()),
    }
 }
 
@@ -2604,6 +2689,8 @@ pub struct TypeContents {
     pub bits: u64
 }
 
+impl Copy for TypeContents {}
+
 macro_rules! def_type_content_sets(
     (mod $mname:ident { $($name:ident = $bits:expr),+ }) => {
         #[allow(non_snake_case)]
@@ -2630,7 +2717,6 @@ def_type_content_sets!(
         OwnsOwned                           = 0b0000_0000__0000_0001__0000,
         OwnsDtor                            = 0b0000_0000__0000_0010__0000,
         OwnsManaged /* see [1] below */     = 0b0000_0000__0000_0100__0000,
-        OwnsAffine                          = 0b0000_0000__0000_1000__0000,
         OwnsAll                             = 0b0000_0000__1111_1111__0000,
 
         // Things that are reachable by the value in any way (fourth nibble):
@@ -2640,24 +2726,12 @@ def_type_content_sets!(
         ReachesFfiUnsafe                    = 0b0010_0000__0000_0000__0000,
         ReachesAll                          = 0b0011_1111__0000_0000__0000,
 
-        // Things that cause values to *move* rather than *copy*. This
-        // is almost the same as the `Copy` trait, but for managed
-        // data -- atm, we consider managed data to copy, not move,
-        // but it does not impl Copy as a pure memcpy is not good
-        // enough. Yuck.
-        Moves                               = 0b0000_0000__0000_1011__0000,
-
         // Things that mean drop glue is necessary
         NeedsDrop                           = 0b0000_0000__0000_0111__0000,
 
         // Things that prevent values from being considered sized
         Nonsized                            = 0b0000_0000__0000_0000__0001,
 
-        // Things that make values considered not POD (would be same
-        // as `Moves`, but for the fact that managed data `@` is
-        // not considered POD)
-        Noncopy                              = 0b0000_0000__0000_1111__0000,
-
         // Bits to set when a managed value is encountered
         //
         // [1] Do not set the bits TC::OwnsManaged or
@@ -2699,10 +2773,6 @@ impl TypeContents {
         self.intersects(TC::InteriorUnsized)
     }
 
-    pub fn moves_by_default(&self, _: &ctxt) -> bool {
-        self.intersects(TC::Moves)
-    }
-
     pub fn needs_drop(&self, _: &ctxt) -> bool {
         self.intersects(TC::NeedsDrop)
     }
@@ -2987,15 +3057,10 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
         mc | tc_ty(cx, mt.ty, cache)
     }
 
-    fn apply_lang_items(cx: &ctxt,
-                        did: ast::DefId,
-                        tc: TypeContents)
-                        -> TypeContents
-    {
+    fn apply_lang_items(cx: &ctxt, did: ast::DefId, tc: TypeContents)
+                        -> TypeContents {
         if Some(did) == cx.lang_items.managed_bound() {
             tc | TC::Managed
-        } else if Some(did) == cx.lang_items.no_copy_bound() {
-            tc | TC::OwnsAffine
         } else if Some(did) == cx.lang_items.unsafe_type() {
             tc | TC::InteriorUnsafe
         } else {
@@ -3008,7 +3073,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
                          mutbl: ast::Mutability)
                          -> TypeContents {
         let b = match mutbl {
-            ast::MutMutable => TC::ReachesMutable | TC::OwnsAffine,
+            ast::MutMutable => TC::ReachesMutable,
             ast::MutImmutable => TC::None,
         };
         b | (TC::ReachesBorrowed).when(region != ty::ReStatic)
@@ -3028,14 +3093,7 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
             }
         };
 
-        // This also prohibits "@once fn" from being copied, which allows it to
-        // be called. Neither way really makes much sense.
-        let ot = match cty.onceness {
-            ast::Once => TC::OwnsAffine,
-            ast::Many => TC::None,
-        };
-
-        st | ot
+        st
     }
 
     fn object_contents(cx: &ctxt,
@@ -3053,9 +3111,8 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
         let mut tc = TC::All;
         each_inherited_builtin_bound(cx, bounds, traits, |bound| {
             tc = tc - match bound {
-                BoundSync | BoundSend => TC::None,
+                BoundSync | BoundSend | BoundCopy => TC::None,
                 BoundSized => TC::Nonsized,
-                BoundCopy => TC::Noncopy,
             };
         });
         return tc;
@@ -3081,8 +3138,38 @@ pub fn type_contents<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> TypeContents {
     }
 }
 
-pub fn type_moves_by_default<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
-    type_contents(cx, ty).moves_by_default(cx)
+pub fn type_moves_by_default<'tcx>(cx: &ctxt<'tcx>,
+                                   ty: Ty<'tcx>,
+                                   param_env: &ParameterEnvironment<'tcx>)
+                                    -> bool {
+    if !type_has_params(ty) && !type_has_self(ty) {
+        match cx.type_moves_by_default_cache.borrow().get(&ty) {
+            None => {}
+            Some(&result) => {
+                debug!("determined whether {} moves by default (cached): {}",
+                       ty_to_string(cx, ty),
+                       result);
+                return result
+            }
+        }
+    }
+
+    let infcx = infer::new_infer_ctxt(cx);
+    let mut fulfill_cx = traits::FulfillmentContext::new();
+    let obligation = traits::obligation_for_builtin_bound(
+        cx,
+        ObligationCause::misc(DUMMY_SP),
+        ty,
+        ty::BoundCopy).unwrap();
+    fulfill_cx.register_obligation(cx, obligation);
+    let result = !fulfill_cx.select_all_or_error(&infcx,
+                                                 param_env,
+                                                 cx).is_ok();
+    cx.type_moves_by_default_cache.borrow_mut().insert(ty, result);
+    debug!("determined whether {} moves by default: {}",
+           ty_to_string(cx, ty),
+           result);
+    result
 }
 
 pub fn is_ffi_safe<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
@@ -3214,6 +3301,8 @@ pub enum Representability {
     SelfRecursive,
 }
 
+impl Copy for Representability {}
+
 /// Check whether a type is representable. This means it cannot contain unboxed
 /// structural recursion. This check is needed for structs and enums.
 pub fn is_type_representable<'tcx>(cx: &ctxt<'tcx>, sp: Span, ty: Ty<'tcx>)
@@ -3996,6 +4085,8 @@ pub enum ExprKind {
     RvalueStmtExpr
 }
 
+impl Copy for ExprKind {}
+
 pub fn expr_kind(tcx: &ctxt, expr: &ast::Expr) -> ExprKind {
     if tcx.method_map.borrow().contains_key(&MethodCall::expr(expr.id)) {
         // Overloaded operations are generally calls, and hence they are
@@ -4555,6 +4646,8 @@ pub struct AssociatedTypeInfo {
     pub name: ast::Name,
 }
 
+impl Copy for AssociatedTypeInfo {}
+
 impl PartialOrd for AssociatedTypeInfo {
     fn partial_cmp(&self, other: &AssociatedTypeInfo) -> Option<Ordering> {
         Some(self.index.cmp(&other.index))
@@ -4738,6 +4831,8 @@ pub enum DtorKind {
     TraitDtor(DefId, bool)
 }
 
+impl Copy for DtorKind {}
+
 impl DtorKind {
     pub fn is_present(&self) -> bool {
         match *self {
@@ -5125,6 +5220,8 @@ pub struct UnboxedClosureUpvar<'tcx> {
     pub ty: Ty<'tcx>,
 }
 
+impl<'tcx> Copy for UnboxedClosureUpvar<'tcx> {}
+
 // Returns a list of `UnboxedClosureUpvar`s for each upvar.
 pub fn unboxed_closure_upvars<'tcx>(tcx: &ctxt<'tcx>, closure_id: ast::DefId, substs: &Substs<'tcx>)
                                     -> Vec<UnboxedClosureUpvar<'tcx>> {
@@ -5954,6 +6051,8 @@ pub enum ExplicitSelfCategory {
     ByBoxExplicitSelfCategory,
 }
 
+impl Copy for ExplicitSelfCategory {}
+
 /// Pushes all the lifetimes in the given type onto the given list. A
 /// "lifetime in a type" is a lifetime specified by a reference or a lifetime
 /// in a list of type substitutions. This does *not* traverse into nominal
@@ -6023,6 +6122,8 @@ pub struct Freevar {
     pub span: Span
 }
 
+impl Copy for Freevar {}
+
 pub type FreevarMap = NodeMap<Vec<Freevar>>;
 
 pub type CaptureModeMap = NodeMap<ast::CaptureClause>;
@@ -6122,6 +6223,8 @@ impl DebruijnIndex {
     }
 }
 
+impl Copy for DebruijnIndex {}
+
 impl<'tcx> Repr<'tcx> for AutoAdjustment<'tcx> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
         match *self {
@@ -6229,3 +6332,43 @@ pub fn make_substs_for_receiver_types<'tcx>(tcx: &ty::ctxt<'tcx>,
     trait_ref.substs.clone().with_method(meth_tps, meth_regions)
 }
 
+pub enum CopyImplementationError {
+    FieldDoesNotImplementCopy(ast::Name),
+    VariantDoesNotImplementCopy(ast::Name),
+    TypeIsStructural,
+}
+
+impl Copy for CopyImplementationError {}
+
+pub fn can_type_implement_copy<'tcx>(tcx: &ctxt<'tcx>,
+                                     self_type: Ty<'tcx>,
+                                     param_env: &ParameterEnvironment<'tcx>)
+                                     -> Result<(),CopyImplementationError> {
+    match self_type.sty {
+        ty::ty_struct(struct_did, ref substs) => {
+            let fields = ty::struct_fields(tcx, struct_did, substs);
+            for field in fields.iter() {
+                if type_moves_by_default(tcx, field.mt.ty, param_env) {
+                    return Err(FieldDoesNotImplementCopy(field.name))
+                }
+            }
+        }
+        ty::ty_enum(enum_did, ref substs) => {
+            let enum_variants = ty::enum_variants(tcx, enum_did);
+            for variant in enum_variants.iter() {
+                for variant_arg_type in variant.args.iter() {
+                    let substd_arg_type =
+                        variant_arg_type.subst(tcx, substs);
+                    if type_moves_by_default(tcx,
+                                             substd_arg_type,
+                                             param_env) {
+                        return Err(VariantDoesNotImplementCopy(variant.name))
+                    }
+                }
+            }
+        }
+        _ => return Err(TypeIsStructural),
+    }
+
+    Ok(())
+}
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 981b58a3b7b..c7b5e1e8de9 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -55,6 +55,8 @@ pub enum OptLevel {
     Aggressive // -O3
 }
 
+impl Copy for OptLevel {}
+
 #[deriving(Clone, PartialEq)]
 pub enum DebugInfoLevel {
     NoDebugInfo,
@@ -62,6 +64,8 @@ pub enum DebugInfoLevel {
     FullDebugInfo,
 }
 
+impl Copy for DebugInfoLevel {}
+
 #[deriving(Clone, PartialEq, PartialOrd, Ord, Eq)]
 pub enum OutputType {
     OutputTypeBitcode,
@@ -71,6 +75,8 @@ pub enum OutputType {
     OutputTypeExe,
 }
 
+impl Copy for OutputType {}
+
 #[deriving(Clone)]
 pub struct Options {
     // The crate config requested for the session, which may be combined
@@ -87,7 +93,7 @@ pub struct Options {
     // parsed code. It remains mutable in case its replacements wants to use
     // this.
     pub addl_lib_search_paths: RefCell<Vec<Path>>,
-    pub libs: Vec<(String, cstore::NativeLibaryKind)>,
+    pub libs: Vec<(String, cstore::NativeLibraryKind)>,
     pub maybe_sysroot: Option<Path>,
     pub target_triple: String,
     // User-specified cfg meta items. The compiler itself will add additional
@@ -221,6 +227,8 @@ pub enum EntryFnType {
     EntryNone,
 }
 
+impl Copy for EntryFnType {}
+
 #[deriving(PartialEq, PartialOrd, Clone, Ord, Eq, Hash)]
 pub enum CrateType {
     CrateTypeExecutable,
@@ -229,6 +237,8 @@ pub enum CrateType {
     CrateTypeStaticlib,
 }
 
+impl Copy for CrateType {}
+
 macro_rules! debugging_opts(
     ([ $opt:ident ] $cnt:expr ) => (
         pub const $opt: u64 = 1 << $cnt;
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index ea252d9fd20..30318cc129c 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -25,6 +25,8 @@ use syntax::visit::Visitor;
 #[deriving(Clone,Show)]
 pub struct ErrorReported;
 
+impl Copy for ErrorReported {}
+
 pub fn time<T, U>(do_it: bool, what: &str, u: U, f: |U| -> T) -> T {
     thread_local!(static DEPTH: Cell<uint> = Cell::new(0));
     if !do_it { return f(u); }
diff --git a/src/librustc/util/nodemap.rs b/src/librustc/util/nodemap.rs
index 4dd6306c3c0..d1816c655fa 100644
--- a/src/librustc/util/nodemap.rs
+++ b/src/librustc/util/nodemap.rs
@@ -71,6 +71,9 @@ pub mod DefIdSet {
 #[deriving(Clone, Default)]
 pub struct FnvHasher;
 
+impl Copy for FnvHasher {}
+
+#[allow(missing_copy_implementations)]
 pub struct FnvState(u64);
 
 impl Hasher<FnvState> for FnvHasher {
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index b6441ab4944..d143d05acfe 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -49,12 +49,16 @@ pub enum PpSourceMode {
     PpmExpandedHygiene,
 }
 
+impl Copy for PpSourceMode {}
+
 #[deriving(PartialEq, Show)]
 pub enum PpMode {
     PpmSource(PpSourceMode),
     PpmFlowGraph,
 }
 
+impl Copy for PpMode {}
+
 pub fn parse_pretty(sess: &Session, name: &str) -> (PpMode, Option<UserIdentifiedItem>) {
     let mut split = name.splitn(1, '=');
     let first = split.next().unwrap();
diff --git a/src/librustc_llvm/diagnostic.rs b/src/librustc_llvm/diagnostic.rs
index d705c82dd9a..04196feafd2 100644
--- a/src/librustc_llvm/diagnostic.rs
+++ b/src/librustc_llvm/diagnostic.rs
@@ -24,6 +24,8 @@ pub enum OptimizationDiagnosticKind {
     OptimizationFailure,
 }
 
+impl Copy for OptimizationDiagnosticKind {}
+
 impl OptimizationDiagnosticKind {
     pub fn describe(self) -> &'static str {
         match self {
@@ -43,6 +45,8 @@ pub struct OptimizationDiagnostic {
     pub message: TwineRef,
 }
 
+impl Copy for OptimizationDiagnostic {}
+
 impl OptimizationDiagnostic {
     unsafe fn unpack(kind: OptimizationDiagnosticKind, di: DiagnosticInfoRef)
             -> OptimizationDiagnostic {
@@ -72,6 +76,8 @@ pub enum Diagnostic {
     UnknownDiagnostic(DiagnosticInfoRef),
 }
 
+impl Copy for Diagnostic {}
+
 impl Diagnostic {
     pub unsafe fn unpack(di: DiagnosticInfoRef) -> Diagnostic {
         let kind = super::LLVMGetDiagInfoKind(di);
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index a8211c0c9ea..23dad21e530 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -77,12 +77,16 @@ pub enum CallConv {
     X86_64_Win64 = 79,
 }
 
+impl Copy for CallConv {}
+
 pub enum Visibility {
     LLVMDefaultVisibility = 0,
     HiddenVisibility = 1,
     ProtectedVisibility = 2,
 }
 
+impl Copy for Visibility {}
+
 // This enum omits the obsolete (and no-op) linkage types DLLImportLinkage,
 // DLLExportLinkage, GhostLinkage and LinkOnceODRAutoHideLinkage.
 // LinkerPrivateLinkage and LinkerPrivateWeakLinkage are not included either;
@@ -101,6 +105,8 @@ pub enum Linkage {
     CommonLinkage = 14,
 }
 
+impl Copy for Linkage {}
+
 #[repr(C)]
 #[deriving(Show)]
 pub enum DiagnosticSeverity {
@@ -110,6 +116,8 @@ pub enum DiagnosticSeverity {
     Note,
 }
 
+impl Copy for DiagnosticSeverity {}
+
 bitflags! {
     flags Attribute : u32 {
         const ZExtAttribute = 1 << 0,
@@ -141,6 +149,8 @@ bitflags! {
     }
 }
 
+impl Copy for Attribute {}
+
 #[repr(u64)]
 pub enum OtherAttribute {
     // The following are not really exposed in
@@ -162,16 +172,22 @@ pub enum OtherAttribute {
     NonNullAttribute = 1 << 44,
 }
 
+impl Copy for OtherAttribute {}
+
 pub enum SpecialAttribute {
     DereferenceableAttribute(u64)
 }
 
+impl Copy for SpecialAttribute {}
+
 #[repr(C)]
 pub enum AttributeSet {
     ReturnIndex = 0,
     FunctionIndex = !0
 }
 
+impl Copy for AttributeSet {}
+
 pub trait AttrHelper {
     fn apply_llfn(&self, idx: c_uint, llfn: ValueRef);
     fn apply_callsite(&self, idx: c_uint, callsite: ValueRef);
@@ -271,6 +287,8 @@ pub enum IntPredicate {
     IntSLE = 41,
 }
 
+impl Copy for IntPredicate {}
+
 // enum for the LLVM RealPredicate type
 pub enum RealPredicate {
     RealPredicateFalse = 0,
@@ -291,6 +309,8 @@ pub enum RealPredicate {
     RealPredicateTrue = 15,
 }
 
+impl Copy for RealPredicate {}
+
 // The LLVM TypeKind type - must stay in sync with the def of
 // LLVMTypeKind in llvm/include/llvm-c/Core.h
 #[deriving(PartialEq)]
@@ -314,6 +334,8 @@ pub enum TypeKind {
     X86_MMX   = 15,
 }
 
+impl Copy for TypeKind {}
+
 #[repr(C)]
 pub enum AtomicBinOp {
     AtomicXchg = 0,
@@ -329,6 +351,8 @@ pub enum AtomicBinOp {
     AtomicUMin = 10,
 }
 
+impl Copy for AtomicBinOp {}
+
 #[repr(C)]
 pub enum AtomicOrdering {
     NotAtomic = 0,
@@ -341,6 +365,8 @@ pub enum AtomicOrdering {
     SequentiallyConsistent = 7
 }
 
+impl Copy for AtomicOrdering {}
+
 // Consts for the LLVMCodeGenFileType type (in include/llvm/c/TargetMachine.h)
 #[repr(C)]
 pub enum FileType {
@@ -348,6 +374,8 @@ pub enum FileType {
     ObjectFileType = 1
 }
 
+impl Copy for FileType {}
+
 pub enum MetadataType {
     MD_dbg = 0,
     MD_tbaa = 1,
@@ -357,12 +385,16 @@ pub enum MetadataType {
     MD_tbaa_struct = 5
 }
 
+impl Copy for MetadataType {}
+
 // Inline Asm Dialect
 pub enum AsmDialect {
     AD_ATT   = 0,
     AD_Intel = 1
 }
 
+impl Copy for AsmDialect {}
+
 #[deriving(PartialEq, Clone)]
 #[repr(C)]
 pub enum CodeGenOptLevel {
@@ -372,6 +404,8 @@ pub enum CodeGenOptLevel {
     CodeGenLevelAggressive = 3,
 }
 
+impl Copy for CodeGenOptLevel {}
+
 #[deriving(PartialEq)]
 #[repr(C)]
 pub enum RelocMode {
@@ -381,6 +415,8 @@ pub enum RelocMode {
     RelocDynamicNoPic = 3,
 }
 
+impl Copy for RelocMode {}
+
 #[repr(C)]
 pub enum CodeGenModel {
     CodeModelDefault = 0,
@@ -391,6 +427,8 @@ pub enum CodeGenModel {
     CodeModelLarge = 5,
 }
 
+impl Copy for CodeGenModel {}
+
 #[repr(C)]
 pub enum DiagnosticKind {
     DK_InlineAsm = 0,
@@ -403,47 +441,70 @@ pub enum DiagnosticKind {
     DK_OptimizationFailure,
 }
 
+impl Copy for DiagnosticKind {}
+
 // Opaque pointer types
+#[allow(missing_copy_implementations)]
 pub enum Module_opaque {}
 pub type ModuleRef = *mut Module_opaque;
+#[allow(missing_copy_implementations)]
 pub enum Context_opaque {}
 pub type ContextRef = *mut Context_opaque;
+#[allow(missing_copy_implementations)]
 pub enum Type_opaque {}
 pub type TypeRef = *mut Type_opaque;
+#[allow(missing_copy_implementations)]
 pub enum Value_opaque {}
 pub type ValueRef = *mut Value_opaque;
+#[allow(missing_copy_implementations)]
 pub enum BasicBlock_opaque {}
 pub type BasicBlockRef = *mut BasicBlock_opaque;
+#[allow(missing_copy_implementations)]
 pub enum Builder_opaque {}
 pub type BuilderRef = *mut Builder_opaque;
+#[allow(missing_copy_implementations)]
 pub enum ExecutionEngine_opaque {}
 pub type ExecutionEngineRef = *mut ExecutionEngine_opaque;
+#[allow(missing_copy_implementations)]
 pub enum MemoryBuffer_opaque {}
 pub type MemoryBufferRef = *mut MemoryBuffer_opaque;
+#[allow(missing_copy_implementations)]
 pub enum PassManager_opaque {}
 pub type PassManagerRef = *mut PassManager_opaque;
+#[allow(missing_copy_implementations)]
 pub enum PassManagerBuilder_opaque {}
 pub type PassManagerBuilderRef = *mut PassManagerBuilder_opaque;
+#[allow(missing_copy_implementations)]
 pub enum Use_opaque {}
 pub type UseRef = *mut Use_opaque;
+#[allow(missing_copy_implementations)]
 pub enum TargetData_opaque {}
 pub type TargetDataRef = *mut TargetData_opaque;
+#[allow(missing_copy_implementations)]
 pub enum ObjectFile_opaque {}
 pub type ObjectFileRef = *mut ObjectFile_opaque;
+#[allow(missing_copy_implementations)]
 pub enum SectionIterator_opaque {}
 pub type SectionIteratorRef = *mut SectionIterator_opaque;
+#[allow(missing_copy_implementations)]
 pub enum Pass_opaque {}
 pub type PassRef = *mut Pass_opaque;
+#[allow(missing_copy_implementations)]
 pub enum TargetMachine_opaque {}
 pub type TargetMachineRef = *mut TargetMachine_opaque;
+#[allow(missing_copy_implementations)]
 pub enum Archive_opaque {}
 pub type ArchiveRef = *mut Archive_opaque;
+#[allow(missing_copy_implementations)]
 pub enum Twine_opaque {}
 pub type TwineRef = *mut Twine_opaque;
+#[allow(missing_copy_implementations)]
 pub enum DiagnosticInfo_opaque {}
 pub type DiagnosticInfoRef = *mut DiagnosticInfo_opaque;
+#[allow(missing_copy_implementations)]
 pub enum DebugLoc_opaque {}
 pub type DebugLocRef = *mut DebugLoc_opaque;
+#[allow(missing_copy_implementations)]
 pub enum SMDiagnostic_opaque {}
 pub type SMDiagnosticRef = *mut SMDiagnostic_opaque;
 
@@ -454,6 +515,7 @@ pub mod debuginfo {
     pub use self::DIDescriptorFlags::*;
     use super::{ValueRef};
 
+    #[allow(missing_copy_implementations)]
     pub enum DIBuilder_opaque {}
     pub type DIBuilderRef = *mut DIBuilder_opaque;
 
@@ -490,6 +552,8 @@ pub mod debuginfo {
       FlagLValueReference    = 1 << 14,
       FlagRValueReference    = 1 << 15
     }
+
+    impl Copy for DIDescriptorFlags {}
 }
 
 
@@ -2123,6 +2187,7 @@ pub fn get_param(llfn: ValueRef, index: c_uint) -> ValueRef {
     }
 }
 
+#[allow(missing_copy_implementations)]
 pub enum RustString_opaque {}
 pub type RustStringRef = *mut RustString_opaque;
 type RustStringRepr = *mut RefCell<Vec<u8>>;
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index a919fe686ab..0ed6ae31171 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -33,6 +33,17 @@ use std::sync::{Arc, Mutex};
 use std::task::TaskBuilder;
 use libc::{c_uint, c_int, c_void};
 
+#[deriving(Clone, PartialEq, PartialOrd, Ord, Eq)]
+pub enum OutputType {
+    OutputTypeBitcode,
+    OutputTypeAssembly,
+    OutputTypeLlvmAssembly,
+    OutputTypeObject,
+    OutputTypeExe,
+}
+
+impl Copy for OutputType {}
+
 pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! {
     unsafe {
         let cstr = llvm::LLVMRustGetLastError();
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index 1482422b8d0..2a698a898fe 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -249,7 +249,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
             self.collecting = true;
             self.visit_pat(&*arg.pat);
             self.collecting = false;
-            let span_utils = self.span;
+            let span_utils = self.span.clone();
             for &(id, ref p, _, _) in self.collected_paths.iter() {
                 let typ = ppaux::ty_to_string(&self.analysis.ty_cx,
                     (*self.analysis.ty_cx.node_types.borrow())[id]);
diff --git a/src/librustc_trans/save/recorder.rs b/src/librustc_trans/save/recorder.rs
index f0bb441145c..c15ff1d7f0a 100644
--- a/src/librustc_trans/save/recorder.rs
+++ b/src/librustc_trans/save/recorder.rs
@@ -87,6 +87,8 @@ pub enum Row {
     FnRef,
 }
 
+impl Copy for Row {}
+
 impl<'a> FmtStrs<'a> {
     pub fn new(rec: Box<Recorder>, span: SpanUtils<'a>, krate: String) -> FmtStrs<'a> {
         FmtStrs {
@@ -223,7 +225,10 @@ impl<'a> FmtStrs<'a> {
 
         if self.recorder.dump_spans {
             if dump_spans {
-                self.recorder.dump_span(self.span, label, span, Some(sub_span));
+                self.recorder.dump_span(self.span.clone(),
+                                        label,
+                                        span,
+                                        Some(sub_span));
             }
             return;
         }
diff --git a/src/librustc_trans/save/span_utils.rs b/src/librustc_trans/save/span_utils.rs
index f76f2bea566..49e8e0fd347 100644
--- a/src/librustc_trans/save/span_utils.rs
+++ b/src/librustc_trans/save/span_utils.rs
@@ -21,6 +21,7 @@ use syntax::parse::lexer::{Reader,StringReader};
 use syntax::parse::token;
 use syntax::parse::token::{keywords, Token};
 
+#[deriving(Clone)]
 pub struct SpanUtils<'a> {
     pub sess: &'a Session,
     pub err_count: Cell<int>,
diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs
index f5155852aa0..1ed06938e95 100644
--- a/src/librustc_trans/trans/_match.rs
+++ b/src/librustc_trans/trans/_match.rs
@@ -231,6 +231,8 @@ use syntax::ptr::P;
 #[deriving(Show)]
 struct ConstantExpr<'a>(&'a ast::Expr);
 
+impl<'a> Copy for ConstantExpr<'a> {}
+
 impl<'a> ConstantExpr<'a> {
     fn eq(self, other: ConstantExpr<'a>, tcx: &ty::ctxt) -> bool {
         let ConstantExpr(expr) = self;
@@ -308,6 +310,8 @@ pub enum BranchKind {
     CompareSliceLength
 }
 
+impl Copy for BranchKind {}
+
 pub enum OptResult<'blk, 'tcx: 'blk> {
     SingleResult(Result<'blk, 'tcx>),
     RangeResult(Result<'blk, 'tcx>, Result<'blk, 'tcx>),
@@ -321,6 +325,8 @@ pub enum TransBindingMode {
     TrByRef,
 }
 
+impl Copy for TransBindingMode {}
+
 /// Information about a pattern binding:
 /// - `llmatch` is a pointer to a stack slot.  The stack slot contains a
 ///   pointer into the value being matched.  Hence, llmatch has type `T**`
@@ -337,6 +343,8 @@ pub struct BindingInfo<'tcx> {
     pub ty: Ty<'tcx>,
 }
 
+impl<'tcx> Copy for BindingInfo<'tcx> {}
+
 type BindingsMap<'tcx> = FnvHashMap<Ident, BindingInfo<'tcx>>;
 
 struct ArmData<'p, 'blk, 'tcx: 'blk> {
@@ -543,7 +551,11 @@ fn enter_opt<'a, 'p, 'blk, 'tcx>(
             check_match::Constructor::Variant(def_id)
     };
 
-    let mcx = check_match::MatchCheckCtxt { tcx: bcx.tcx() };
+    let param_env = ty::empty_parameter_environment();
+    let mcx = check_match::MatchCheckCtxt {
+        tcx: bcx.tcx(),
+        param_env: param_env,
+    };
     enter_match(bcx, dm, m, col, val, |pats|
         check_match::specialize(&mcx, pats.as_slice(), &ctor, col, variant_size)
     )
@@ -1001,7 +1013,10 @@ fn compile_submatch_continue<'a, 'p, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
         node_id_type(bcx, pat_id)
     };
 
-    let mcx = check_match::MatchCheckCtxt { tcx: bcx.tcx() };
+    let mcx = check_match::MatchCheckCtxt {
+        tcx: bcx.tcx(),
+        param_env: ty::empty_parameter_environment(),
+    };
     let adt_vals = if any_irrefutable_adt_pat(bcx.tcx(), m, col) {
         let repr = adt::represent_type(bcx.ccx(), left_ty);
         let arg_count = adt::num_args(&*repr, 0);
@@ -1254,7 +1269,8 @@ fn is_discr_reassigned(bcx: Block, discr: &ast::Expr, body: &ast::Expr) -> bool
         reassigned: false
     };
     {
-        let mut visitor = euv::ExprUseVisitor::new(&mut rc, bcx);
+        let param_env = ty::empty_parameter_environment();
+        let mut visitor = euv::ExprUseVisitor::new(&mut rc, bcx, param_env);
         visitor.walk_expr(body);
     }
     rc.reassigned
@@ -1312,12 +1328,15 @@ fn create_bindings_map<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, pat: &ast::Pat,
         let variable_ty = node_id_type(bcx, p_id);
         let llvariable_ty = type_of::type_of(ccx, variable_ty);
         let tcx = bcx.tcx();
+        let param_env = ty::empty_parameter_environment();
 
         let llmatch;
         let trmode;
         match bm {
             ast::BindByValue(_)
-                if !ty::type_moves_by_default(tcx, variable_ty) || reassigned => {
+                if !ty::type_moves_by_default(tcx,
+                                              variable_ty,
+                                              &param_env) || reassigned => {
                 llmatch = alloca_no_lifetime(bcx,
                                  llvariable_ty.ptr_to(),
                                  "__llmatch");
diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs
index 2f0f373325a..e273a56ce02 100644
--- a/src/librustc_trans/trans/adt.rs
+++ b/src/librustc_trans/trans/adt.rs
@@ -287,8 +287,11 @@ pub enum PointerField {
     FatPointer(uint)
 }
 
+impl Copy for PointerField {}
+
 impl<'tcx> Case<'tcx> {
-    fn is_zerolen<'a>(&self, cx: &CrateContext<'a, 'tcx>, scapegoat: Ty<'tcx>) -> bool {
+    fn is_zerolen<'a>(&self, cx: &CrateContext<'a, 'tcx>, scapegoat: Ty<'tcx>)
+                      -> bool {
         mk_struct(cx, self.tys.as_slice(), false, scapegoat).size == 0
     }
 
diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs
index 3090119788c..cef12616cf2 100644
--- a/src/librustc_trans/trans/base.rs
+++ b/src/librustc_trans/trans/base.rs
@@ -90,6 +90,7 @@ use libc::{c_uint, uint64_t};
 use std::c_str::ToCStr;
 use std::cell::{Cell, RefCell};
 use std::collections::HashSet;
+use std::mem;
 use std::rc::Rc;
 use std::{i8, i16, i32, i64};
 use syntax::abi::{Rust, RustCall, RustIntrinsic, Abi};
@@ -562,6 +563,8 @@ pub fn maybe_name_value(cx: &CrateContext, v: ValueRef, s: &str) {
 // Used only for creating scalar comparison glue.
 pub enum scalar_type { nil_type, signed_int, unsigned_int, floating_point, }
 
+impl Copy for scalar_type {}
+
 pub fn compare_scalar_types<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                                         lhs: ValueRef,
                                         rhs: ValueRef,
@@ -813,7 +816,10 @@ pub fn iter_structural_ty<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
                                       in iter_structural_ty")
           }
       }
-      _ => cx.sess().unimpl("type in iter_structural_ty")
+      _ => {
+          cx.sess().unimpl(format!("type in iter_structural_ty: {}",
+                                   ty_to_string(cx.tcx(), t)).as_slice())
+      }
     }
     return cx;
 }
@@ -1778,6 +1784,14 @@ pub fn build_return_block<'blk, 'tcx>(fcx: &FunctionContext<'blk, 'tcx>,
     }
 }
 
+#[deriving(Clone, Eq, PartialEq)]
+pub enum IsUnboxedClosureFlag {
+    NotUnboxedClosure,
+    IsUnboxedClosure,
+}
+
+impl Copy for IsUnboxedClosureFlag {}
+
 // trans_closure: Builds an LLVM function out of a source function.
 // If the function closes over its environment a closure will be
 // returned.
@@ -2182,6 +2196,8 @@ pub enum ValueOrigin {
     InlinedCopy,
 }
 
+impl Copy for ValueOrigin {}
+
 /// Set the appropriate linkage for an LLVM `ValueRef` (function or global).
 /// If the `llval` is the direct translation of a specific Rust item, `id`
 /// should be set to the `NodeId` of that item.  (This mapping should be
@@ -3036,7 +3052,11 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
         fn next(&mut self) -> Option<ValueRef> {
             let old = self.cur;
             if !old.is_null() {
-                self.cur = unsafe { (self.step)(old) };
+                self.cur = unsafe {
+                    let step: unsafe extern "C" fn(ValueRef) -> ValueRef =
+                        mem::transmute_copy(&self.step);
+                    step(old)
+                };
                 Some(old)
             } else {
                 None
diff --git a/src/librustc_trans/trans/basic_block.rs b/src/librustc_trans/trans/basic_block.rs
index 328c8e616c4..b55c268d9a9 100644
--- a/src/librustc_trans/trans/basic_block.rs
+++ b/src/librustc_trans/trans/basic_block.rs
@@ -15,6 +15,8 @@ use std::iter::{Filter, Map};
 
 pub struct BasicBlock(pub BasicBlockRef);
 
+impl Copy for BasicBlock {}
+
 pub type Preds<'a> = Map<'a, Value, BasicBlock, Filter<'a, Value, Users>>;
 
 /// Wrapper for LLVM BasicBlockRef
diff --git a/src/librustc_trans/trans/cabi.rs b/src/librustc_trans/trans/cabi.rs
index 518b0ba73f8..7aabd998f7a 100644
--- a/src/librustc_trans/trans/cabi.rs
+++ b/src/librustc_trans/trans/cabi.rs
@@ -31,6 +31,8 @@ pub enum ArgKind {
     Ignore,
 }
 
+impl Copy for ArgKind {}
+
 /// Information about how a specific C type
 /// should be passed to or returned from a function
 ///
@@ -48,6 +50,8 @@ pub struct ArgType {
     pub attr: option::Option<Attribute>
 }
 
+impl Copy for ArgType {}
+
 impl ArgType {
     pub fn direct(ty: Type, cast: option::Option<Type>,
                             pad: option::Option<Type>,
diff --git a/src/librustc_trans/trans/cabi_x86_64.rs b/src/librustc_trans/trans/cabi_x86_64.rs
index 69ee5301d18..00c91ddebb3 100644
--- a/src/librustc_trans/trans/cabi_x86_64.rs
+++ b/src/librustc_trans/trans/cabi_x86_64.rs
@@ -40,6 +40,8 @@ enum RegClass {
     Memory
 }
 
+impl Copy for RegClass {}
+
 trait TypeMethods {
     fn is_reg_ty(&self) -> bool;
 }
diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs
index 746109ef113..ff7ab91c39a 100644
--- a/src/librustc_trans/trans/callee.rs
+++ b/src/librustc_trans/trans/callee.rs
@@ -63,6 +63,8 @@ pub struct MethodData {
     pub llself: ValueRef,
 }
 
+impl Copy for MethodData {}
+
 pub enum CalleeData<'tcx> {
     Closure(Datum<'tcx, Lvalue>),
 
@@ -1200,6 +1202,8 @@ pub enum AutorefArg {
     DoAutorefArg(ast::NodeId)
 }
 
+impl Copy for AutorefArg {}
+
 pub fn trans_arg_datum<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                    formal_arg_ty: Ty<'tcx>,
                                    arg_datum: Datum<'tcx, Expr>,
diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs
index 33393ba76c5..ba3e70fe036 100644
--- a/src/librustc_trans/trans/cleanup.rs
+++ b/src/librustc_trans/trans/cleanup.rs
@@ -55,6 +55,8 @@ pub struct CustomScopeIndex {
     index: uint
 }
 
+impl Copy for CustomScopeIndex {}
+
 pub const EXIT_BREAK: uint = 0;
 pub const EXIT_LOOP: uint = 1;
 pub const EXIT_MAX: uint = 2;
@@ -88,11 +90,15 @@ pub enum EarlyExitLabel {
     LoopExit(ast::NodeId, uint)
 }
 
+impl Copy for EarlyExitLabel {}
+
 pub struct CachedEarlyExit {
     label: EarlyExitLabel,
     cleanup_block: BasicBlockRef,
 }
 
+impl Copy for CachedEarlyExit {}
+
 pub trait Cleanup<'tcx> {
     fn must_unwind(&self) -> bool;
     fn clean_on_unwind(&self) -> bool;
@@ -111,6 +117,8 @@ pub enum ScopeId {
     CustomScope(CustomScopeIndex)
 }
 
+impl Copy for ScopeId {}
+
 impl<'blk, 'tcx> CleanupMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx> {
     /// Invoked when we start to trans the code contained within a new cleanup scope.
     fn push_ast_cleanup_scope(&self, debug_loc: NodeInfo) {
@@ -876,6 +884,8 @@ pub struct DropValue<'tcx> {
     zero: bool
 }
 
+impl<'tcx> Copy for DropValue<'tcx> {}
+
 impl<'tcx> Cleanup<'tcx> for DropValue<'tcx> {
     fn must_unwind(&self) -> bool {
         self.must_unwind
@@ -910,12 +920,16 @@ pub enum Heap {
     HeapExchange
 }
 
+impl Copy for Heap {}
+
 pub struct FreeValue<'tcx> {
     ptr: ValueRef,
     heap: Heap,
     content_ty: Ty<'tcx>
 }
 
+impl<'tcx> Copy for FreeValue<'tcx> {}
+
 impl<'tcx> Cleanup<'tcx> for FreeValue<'tcx> {
     fn must_unwind(&self) -> bool {
         true
@@ -950,6 +964,8 @@ pub struct FreeSlice {
     heap: Heap,
 }
 
+impl Copy for FreeSlice {}
+
 impl<'tcx> Cleanup<'tcx> for FreeSlice {
     fn must_unwind(&self) -> bool {
         true
@@ -981,6 +997,8 @@ pub struct LifetimeEnd {
     ptr: ValueRef,
 }
 
+impl Copy for LifetimeEnd {}
+
 impl<'tcx> Cleanup<'tcx> for LifetimeEnd {
     fn must_unwind(&self) -> bool {
         false
diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs
index bb4df00bd94..b03f5ff8ecc 100644
--- a/src/librustc_trans/trans/closure.rs
+++ b/src/librustc_trans/trans/closure.rs
@@ -107,6 +107,8 @@ pub struct EnvValue<'tcx> {
     datum: Datum<'tcx, Lvalue>
 }
 
+impl<'tcx> Copy for EnvValue<'tcx> {}
+
 impl<'tcx> EnvValue<'tcx> {
     pub fn to_string<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> String {
         format!("{}({})", self.action, self.datum.to_string(ccx))
diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs
index a8256176c26..77412b00299 100644
--- a/src/librustc_trans/trans/common.rs
+++ b/src/librustc_trans/trans/common.rs
@@ -127,6 +127,8 @@ pub struct tydesc_info<'tcx> {
     pub name: ValueRef,
 }
 
+impl<'tcx> Copy for tydesc_info<'tcx> {}
+
 /*
  * A note on nomenclature of linking: "extern", "foreign", and "upcall".
  *
@@ -158,6 +160,8 @@ pub struct NodeInfo {
     pub span: Span,
 }
 
+impl Copy for NodeInfo {}
+
 pub fn expr_info(expr: &ast::Expr) -> NodeInfo {
     NodeInfo { id: expr.id, span: expr.span }
 }
@@ -867,10 +871,11 @@ pub enum ExprOrMethodCall {
     MethodCall(ty::MethodCall)
 }
 
+impl Copy for ExprOrMethodCall {}
+
 pub fn node_id_substs<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                   node: ExprOrMethodCall)
-                                  -> subst::Substs<'tcx>
-{
+                                  -> subst::Substs<'tcx> {
     let tcx = bcx.tcx();
 
     let substs = match node {
diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs
index 532ef690818..23a261842b2 100644
--- a/src/librustc_trans/trans/datum.rs
+++ b/src/librustc_trans/trans/datum.rs
@@ -46,6 +46,8 @@ pub struct Datum<'tcx, K> {
     pub kind: K,
 }
 
+impl<'tcx,K:Copy> Copy for Datum<'tcx,K> {}
+
 pub struct DatumBlock<'blk, 'tcx: 'blk, K> {
     pub bcx: Block<'blk, 'tcx>,
     pub datum: Datum<'tcx, K>,
@@ -66,6 +68,8 @@ pub enum Expr {
 #[deriving(Clone, Show)]
 pub struct Lvalue;
 
+impl Copy for Lvalue {}
+
 #[deriving(Show)]
 pub struct Rvalue {
     pub mode: RvalueMode
@@ -91,6 +95,8 @@ pub enum RvalueMode {
     ByValue,
 }
 
+impl Copy for RvalueMode {}
+
 pub fn immediate_rvalue<'tcx>(val: ValueRef, ty: Ty<'tcx>) -> Datum<'tcx, Rvalue> {
     return Datum::new(val, ty, Rvalue::new(ByValue));
 }
@@ -529,11 +535,19 @@ impl<'tcx, K: KindOps + fmt::Show> Datum<'tcx, K> {
     /// Copies the value into a new location. This function always preserves the existing datum as
     /// a valid value. Therefore, it does not consume `self` and, also, cannot be applied to affine
     /// values (since they must never be duplicated).
-    pub fn shallow_copy<'blk>(&self,
-                              bcx: Block<'blk, 'tcx>,
-                              dst: ValueRef)
-                              -> Block<'blk, 'tcx> {
-        assert!(!ty::type_moves_by_default(bcx.tcx(), self.ty));
+    pub fn shallow_copy<'blk, 'tcx>(&self,
+                                    bcx: Block<'blk, 'tcx>,
+                                    dst: ValueRef)
+                                    -> Block<'blk, 'tcx> {
+        /*!
+         * Copies the value into a new location. This function always
+         * preserves the existing datum as a valid value. Therefore,
+         * it does not consume `self` and, also, cannot be applied to
+         * affine values (since they must never be duplicated).
+         */
+
+        let param_env = ty::empty_parameter_environment();
+        assert!(!ty::type_moves_by_default(bcx.tcx(), self.ty, &param_env));
         self.shallow_copy_raw(bcx, dst)
     }
 
diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs
index 6c75086fec6..88a66320c0e 100644
--- a/src/librustc_trans/trans/debuginfo.rs
+++ b/src/librustc_trans/trans/debuginfo.rs
@@ -251,6 +251,8 @@ static FLAGS_NONE: c_uint = 0;
 #[deriving(Show, Hash, Eq, PartialEq, Clone)]
 struct UniqueTypeId(ast::Name);
 
+impl Copy for UniqueTypeId {}
+
 // The TypeMap is where the CrateDebugContext holds the type metadata nodes
 // created so far. The metadata nodes are indexed by UniqueTypeId, and, for
 // faster lookup, also by Ty. The TypeMap is responsible for creating
@@ -2323,6 +2325,8 @@ enum EnumDiscriminantInfo {
     NoDiscriminant
 }
 
+impl Copy for EnumDiscriminantInfo {}
+
 // Returns a tuple of (1) type_metadata_stub of the variant, (2) the llvm_type
 // of the variant, and (3) a MemberDescriptionFactory for producing the
 // descriptions of the fields of the variant. This is a rudimentary version of a
@@ -3048,6 +3052,8 @@ enum DebugLocation {
     UnknownLocation
 }
 
+impl Copy for DebugLocation {}
+
 impl DebugLocation {
     fn new(scope: DIScope, line: uint, col: uint) -> DebugLocation {
         KnownLocation {
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index d130dc0a55b..e3e6fff7234 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -79,6 +79,8 @@ pub enum Dest {
     Ignore,
 }
 
+impl Copy for Dest {}
+
 impl Dest {
     pub fn to_string(&self, ccx: &CrateContext) -> String {
         match *self {
@@ -1882,6 +1884,8 @@ pub enum cast_kind {
     cast_other,
 }
 
+impl Copy for cast_kind {}
+
 pub fn cast_type_kind<'tcx>(tcx: &ty::ctxt<'tcx>, t: Ty<'tcx>) -> cast_kind {
     match t.sty {
         ty::ty_char        => cast_integral,
diff --git a/src/librustc_trans/trans/mod.rs b/src/librustc_trans/trans/mod.rs
index c00c477f4b8..9234dfc48bd 100644
--- a/src/librustc_trans/trans/mod.rs
+++ b/src/librustc_trans/trans/mod.rs
@@ -59,6 +59,8 @@ pub struct ModuleTranslation {
     pub llmod: ModuleRef,
 }
 
+impl Copy for ModuleTranslation {}
+
 pub struct CrateTranslation {
     pub modules: Vec<ModuleTranslation>,
     pub metadata_module: ModuleTranslation,
diff --git a/src/librustc_trans/trans/tvec.rs b/src/librustc_trans/trans/tvec.rs
index 00f938191f8..18ea8055a4e 100644
--- a/src/librustc_trans/trans/tvec.rs
+++ b/src/librustc_trans/trans/tvec.rs
@@ -96,6 +96,8 @@ pub struct VecTypes<'tcx> {
     pub llunit_alloc_size: u64
 }
 
+impl<'tcx> Copy for VecTypes<'tcx> {}
+
 impl<'tcx> VecTypes<'tcx> {
     pub fn to_string<'a>(&self, ccx: &CrateContext<'a, 'tcx>) -> String {
         format!("VecTypes {{unit_ty={}, llunit_ty={}, \
@@ -301,8 +303,6 @@ pub fn write_content<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                         1 => expr::trans_into(bcx, &**element, SaveIn(lldest)),
                         count => {
                             let elem = unpack_datum!(bcx, expr::trans(bcx, &**element));
-                            assert!(!ty::type_moves_by_default(bcx.tcx(), elem.ty));
-
                             let bcx = iter_vec_loop(bcx, lldest, vt,
                                                     C_uint(bcx.ccx(), count),
                                                     |set_bcx, lleltptr, _| {
diff --git a/src/librustc_trans/trans/type_.rs b/src/librustc_trans/trans/type_.rs
index 8bff7602ddc..387af7390b2 100644
--- a/src/librustc_trans/trans/type_.rs
+++ b/src/librustc_trans/trans/type_.rs
@@ -31,6 +31,8 @@ pub struct Type {
     rf: TypeRef
 }
 
+impl Copy for Type {}
+
 macro_rules! ty (
     ($e:expr) => ( Type::from_ref(unsafe { $e }))
 )
diff --git a/src/librustc_trans/trans/type_of.rs b/src/librustc_trans/trans/type_of.rs
index 005f6ca4c70..adc919c91bf 100644
--- a/src/librustc_trans/trans/type_of.rs
+++ b/src/librustc_trans/trans/type_of.rs
@@ -449,12 +449,13 @@ pub enum named_ty {
     an_unboxed_closure,
 }
 
+impl Copy for named_ty {}
+
 pub fn llvm_type_name<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                 what: named_ty,
                                 did: ast::DefId,
                                 tps: &[Ty<'tcx>])
-                                -> String
-{
+                                -> String {
     let name = match what {
         a_struct => "struct",
         an_enum => "enum",
diff --git a/src/librustc_trans/trans/value.rs b/src/librustc_trans/trans/value.rs
index 33ea239412a..fa06e039023 100644
--- a/src/librustc_trans/trans/value.rs
+++ b/src/librustc_trans/trans/value.rs
@@ -16,6 +16,8 @@ use libc::c_uint;
 
 pub struct Value(pub ValueRef);
 
+impl Copy for Value {}
+
 macro_rules! opt_val ( ($e:expr) => (
     unsafe {
         match $e {
@@ -123,9 +125,14 @@ impl Value {
     }
 }
 
+/// Wrapper for LLVM UseRef
 pub struct Use(UseRef);
 
-/// Wrapper for LLVM UseRef
+impl Copy for Use {}
+
+/**
+ * Wrapper for LLVM UseRef
+ */
 impl Use {
     pub fn get(&self) -> UseRef {
         let Use(v) = *self; v
@@ -148,6 +155,7 @@ impl Use {
 }
 
 /// Iterator for the users of a value
+#[allow(missing_copy_implementations)]
 pub struct Users {
     next: Option<Use>
 }
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index f87a4c9294b..b6c9d8b2d21 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -52,6 +52,8 @@ pub enum CandidateSource {
     TraitSource(/* trait id */ ast::DefId),
 }
 
+impl Copy for CandidateSource {}
+
 type MethodIndex = uint; // just for doc purposes
 
 /// Determines whether the type `self_ty` supports a method name `method_name` or not.
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index cdf34c7f4d2..e42c9c20011 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -209,6 +209,8 @@ enum Expectation<'tcx> {
     ExpectCastableToType(Ty<'tcx>),
 }
 
+impl<'tcx> Copy for Expectation<'tcx> {}
+
 #[deriving(Clone)]
 pub struct FnStyleState {
     pub def: ast::NodeId,
@@ -216,6 +218,8 @@ pub struct FnStyleState {
     from_fn: bool
 }
 
+impl Copy for FnStyleState {}
+
 impl FnStyleState {
     pub fn function(fn_style: ast::FnStyle, def: ast::NodeId) -> FnStyleState {
         FnStyleState { def: def, fn_style: fn_style, from_fn: true }
@@ -2117,6 +2121,8 @@ pub enum LvaluePreference {
     NoPreference
 }
 
+impl Copy for LvaluePreference {}
+
 /// Executes an autoderef loop for the type `t`. At each step, invokes `should_stop` to decide
 /// whether to terminate the loop. Returns the final type and number of derefs that it performed.
 ///
@@ -2993,6 +2999,8 @@ pub enum DerefArgs {
     DoDerefArgs
 }
 
+impl Copy for DerefArgs {}
+
 /// Controls whether the arguments are tupled. This is used for the call
 /// operator.
 ///
diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs
index 1769c588ec1..a011982a1fc 100644
--- a/src/librustc_typeck/check/wf.rs
+++ b/src/librustc_typeck/check/wf.rs
@@ -203,6 +203,11 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
                 }
             }
 
+            if fcx.tcx().lang_items.copy_trait() == Some(trait_ref.def_id) {
+                // This is checked in coherence.
+                return
+            }
+
             // We are stricter on the trait-ref in an impl than the
             // self-type.  In particular, we enforce region
             // relationships. The reason for this is that (at least
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 777f354bec1..48f1ef8da1d 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -354,6 +354,8 @@ enum ResolveReason {
     ResolvingUnboxedClosure(ast::DefId),
 }
 
+impl Copy for ResolveReason {}
+
 impl ResolveReason {
     fn span(&self, tcx: &ty::ctxt) -> Span {
         match *self {
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index b8642ddde40..578ed916541 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -18,17 +18,15 @@
 
 use metadata::csearch::{each_impl, get_impl_trait};
 use metadata::csearch;
-use middle::subst;
+use middle::subst::{mod, Subst};
 use middle::ty::{ImplContainer, ImplOrTraitItemId, MethodTraitItemId};
-use middle::ty::{TypeTraitItemId, lookup_item_type};
-use middle::ty::{Ty, ty_bool, ty_char, ty_enum, ty_err};
-use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_open};
+use middle::ty::{ParameterEnvironment, TypeTraitItemId, lookup_item_type};
+use middle::ty::{Ty, ty_bool, ty_char, ty_closure, ty_enum, ty_err};
 use middle::ty::{ty_param, Polytype, ty_ptr};
 use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup};
+use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_open};
 use middle::ty::{ty_uint, ty_unboxed_closure, ty_uniq, ty_bare_fn};
-use middle::ty::{ty_closure};
-use middle::ty::type_is_ty_var;
-use middle::subst::Subst;
+use middle::ty::{type_is_ty_var};
 use middle::ty;
 use CrateCtxt;
 use middle::infer::combine::Combine;
@@ -190,6 +188,9 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
         // do this here, but it's actually the most convenient place, since
         // the coherence tables contain the trait -> type mappings.
         self.populate_destructor_table();
+
+        // Check to make sure implementations of `Copy` are legal.
+        self.check_implementations_of_copy();
     }
 
     fn check_implementation(&self,
@@ -474,6 +475,71 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
             }
         }
     }
+
+    /// Ensures that implementations of the built-in trait `Copy` are legal.
+    fn check_implementations_of_copy(&self) {
+        let tcx = self.crate_context.tcx;
+        let copy_trait = match tcx.lang_items.copy_trait() {
+            Some(id) => id,
+            None => return,
+        };
+
+        let trait_impls = match tcx.trait_impls
+                                   .borrow()
+                                   .get(&copy_trait)
+                                   .cloned() {
+            None => {
+                debug!("check_implementations_of_copy(): no types with \
+                        implementations of `Copy` found");
+                return
+            }
+            Some(found_impls) => found_impls
+        };
+
+        // Clone first to avoid a double borrow error.
+        let trait_impls = trait_impls.borrow().clone();
+
+        for &impl_did in trait_impls.iter() {
+            if impl_did.krate != ast::LOCAL_CRATE {
+                debug!("check_implementations_of_copy(): impl not in this \
+                        crate");
+                continue
+            }
+
+            let self_type = self.get_self_type_for_implementation(impl_did);
+            let span = tcx.map.span(impl_did.node);
+            let param_env = ParameterEnvironment::for_item(tcx,
+                                                           impl_did.node);
+            let self_type = self_type.ty.subst(tcx, &param_env.free_substs);
+
+            match ty::can_type_implement_copy(tcx, self_type, &param_env) {
+                Ok(()) => {}
+                Err(ty::FieldDoesNotImplementCopy(name)) => {
+                    tcx.sess
+                       .span_err(span,
+                                 format!("the trait `Copy` may not be \
+                                          implemented for this type; field \
+                                          `{}` does not implement `Copy`",
+                                         token::get_name(name)).as_slice())
+                }
+                Err(ty::VariantDoesNotImplementCopy(name)) => {
+                    tcx.sess
+                       .span_err(span,
+                                 format!("the trait `Copy` may not be \
+                                          implemented for this type; variant \
+                                          `{}` does not implement `Copy`",
+                                         token::get_name(name)).as_slice())
+                }
+                Err(ty::TypeIsStructural) => {
+                    tcx.sess
+                       .span_err(span,
+                                 "the trait `Copy` may not be implemented \
+                                  for this type; type is not a structure or \
+                                  enumeration")
+                }
+            }
+        }
+    }
 }
 
 fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 717e886029a..74ac9c480de 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -499,6 +499,8 @@ enum ConvertMethodContext<'a> {
     TraitConvertMethodContext(ast::DefId, &'a [ast::TraitItem]),
 }
 
+impl<'a> Copy for ConvertMethodContext<'a> {}
+
 fn convert_methods<'a,'tcx,'i,I>(ccx: &CrateCtxt<'a, 'tcx>,
                                  convert_method_context: ConvertMethodContext,
                                  container: ImplOrTraitItemContainer,
diff --git a/src/librustc_typeck/rscope.rs b/src/librustc_typeck/rscope.rs
index 3bca24f479f..39c7a87837c 100644
--- a/src/librustc_typeck/rscope.rs
+++ b/src/librustc_typeck/rscope.rs
@@ -38,6 +38,8 @@ pub trait RegionScope {
 // for types that appear in structs and so on.
 pub struct ExplicitRscope;
 
+impl Copy for ExplicitRscope {}
+
 impl RegionScope for ExplicitRscope {
     fn default_region_bound(&self, _span: Span) -> Option<ty::Region> {
         None
@@ -77,6 +79,7 @@ impl RegionScope for UnelidableRscope {
 // A scope in which any omitted region defaults to `default`. This is
 // used after the `->` in function signatures, but also for backwards
 // compatibility with object types. The latter use may go away.
+#[allow(missing_copy_implementations)]
 pub struct SpecificRscope {
     default: ty::Region
 }
diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs
index ade3144ce41..56f974ad665 100644
--- a/src/librustc_typeck/variance.rs
+++ b/src/librustc_typeck/variance.rs
@@ -232,12 +232,16 @@ type VarianceTermPtr<'a> = &'a VarianceTerm<'a>;
 #[deriving(Show)]
 struct InferredIndex(uint);
 
+impl Copy for InferredIndex {}
+
 enum VarianceTerm<'a> {
     ConstantTerm(ty::Variance),
     TransformTerm(VarianceTermPtr<'a>, VarianceTermPtr<'a>),
     InferredTerm(InferredIndex),
 }
 
+impl<'a> Copy for VarianceTerm<'a> {}
+
 impl<'a> fmt::Show for VarianceTerm<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
@@ -270,6 +274,8 @@ enum ParamKind {
     RegionParam
 }
 
+impl Copy for ParamKind {}
+
 struct InferredInfo<'a> {
     item_id: ast::NodeId,
     kind: ParamKind,
@@ -426,6 +432,8 @@ struct Constraint<'a> {
     variance: &'a VarianceTerm<'a>,
 }
 
+impl<'a> Copy for Constraint<'a> {}
+
 fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>,
                                         krate: &ast::Crate)
                                         -> ConstraintContext<'a, 'tcx> {
@@ -1015,7 +1023,7 @@ impl<'a, 'tcx> SolveContext<'a, 'tcx> {
 
             while index < num_inferred &&
                   inferred_infos[index].item_id == item_id {
-                let info = inferred_infos[index];
+                let info = &inferred_infos[index];
                 let variance = solutions[index];
                 debug!("Index {} Info {} / {} / {} Variance {}",
                        index, info.index, info.kind, info.space, variance);
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index bc870d39c5d..df7b922bd1a 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1178,6 +1178,8 @@ pub enum PrimitiveType {
     PrimitiveTuple,
 }
 
+impl Copy for PrimitiveType {}
+
 #[deriving(Clone, Encodable, Decodable)]
 pub enum TypeKind {
     TypeEnum,
@@ -1190,6 +1192,8 @@ pub enum TypeKind {
     TypeTypedef,
 }
 
+impl Copy for TypeKind {}
+
 impl PrimitiveType {
     fn from_str(s: &str) -> Option<PrimitiveType> {
         match s.as_slice() {
@@ -1843,6 +1847,8 @@ pub enum Mutability {
     Immutable,
 }
 
+impl Copy for Mutability {}
+
 impl Clean<Mutability> for ast::Mutability {
     fn clean(&self, _: &DocContext) -> Mutability {
         match self {
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index adfd9aa8213..1aac91c4a5c 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -82,6 +82,8 @@ pub enum StructType {
     Unit
 }
 
+impl Copy for StructType {}
+
 pub enum TypeBound {
     RegionBound,
     TraitBound(ast::TraitRef)
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 0fca59962d4..68ff2ddbcb0 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -48,6 +48,11 @@ pub struct WhereClause<'a>(pub &'a clean::Generics);
 /// Wrapper struct for emitting type parameter bounds.
 pub struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]);
 
+impl Copy for VisSpace {}
+impl Copy for FnStyleSpace {}
+impl Copy for MutableSpace {}
+impl Copy for RawMutableSpace {}
+
 impl VisSpace {
     pub fn get(&self) -> Option<ast::Visibility> {
         let VisSpace(v) = *self; v
diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs
index 0ad12b957ba..86787e5c805 100644
--- a/src/librustdoc/html/item_type.rs
+++ b/src/librustdoc/html/item_type.rs
@@ -41,6 +41,8 @@ pub enum ItemType {
     Constant        = 18,
 }
 
+impl Copy for ItemType {}
+
 impl ItemType {
     pub fn from_item(item: &clean::Item) -> ItemType {
         match item.inner {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index dab25c3b2ee..296493f3ba3 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -225,7 +225,13 @@ struct Source<'a>(&'a str);
 // Helper structs for rendering items/sidebars and carrying along contextual
 // information
 
-struct Item<'a> { cx: &'a Context, item: &'a clean::Item, }
+struct Item<'a> {
+    cx: &'a Context,
+    item: &'a clean::Item,
+}
+
+impl<'a> Copy for Item<'a> {}
+
 struct Sidebar<'a> { cx: &'a Context, item: &'a clean::Item, }
 
 /// Struct representing one entry in the JS search index. These are all emitted
diff --git a/src/librustdoc/stability_summary.rs b/src/librustdoc/stability_summary.rs
index 42f4c2a0ca6..881270afe14 100644
--- a/src/librustdoc/stability_summary.rs
+++ b/src/librustdoc/stability_summary.rs
@@ -39,6 +39,8 @@ pub struct Counts {
     pub unmarked: uint,
 }
 
+impl Copy for Counts {}
+
 impl Add<Counts, Counts> for Counts {
     fn add(&self, other: &Counts) -> Counts {
         Counts {
diff --git a/src/librustrt/bookkeeping.rs b/src/librustrt/bookkeeping.rs
index 714bbd569bd..e918a496d55 100644
--- a/src/librustrt/bookkeeping.rs
+++ b/src/librustrt/bookkeeping.rs
@@ -26,6 +26,7 @@ use mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
 static TASK_COUNT: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
 static TASK_LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
 
+#[allow(missing_copy_implementations)]
 pub struct Token { _private: () }
 
 impl Drop for Token {
diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs
index 261bd1b9f8c..07094f08c5d 100644
--- a/src/librustrt/c_str.rs
+++ b/src/librustrt/c_str.rs
@@ -85,6 +85,7 @@ use libc;
 ///
 /// This structure wraps a `*libc::c_char`, and will automatically free the
 /// memory it is pointing to when it goes out of scope.
+#[allow(missing_copy_implementations)]
 pub struct CString {
     buf: *const libc::c_char,
     owns_buffer_: bool,
diff --git a/src/librustrt/mutex.rs b/src/librustrt/mutex.rs
index 2f0daf8f6e2..5b58ec8fd3a 100644
--- a/src/librustrt/mutex.rs
+++ b/src/librustrt/mutex.rs
@@ -361,6 +361,7 @@ mod imp {
 
     #[cfg(any(target_os = "macos", target_os = "ios"))]
     mod os {
+        use core::kinds::Copy;
         use libc;
 
         #[cfg(target_arch = "x86_64")]
@@ -384,12 +385,17 @@ mod imp {
             __sig: libc::c_long,
             __opaque: [u8, ..__PTHREAD_MUTEX_SIZE__],
         }
+
+        impl Copy for pthread_mutex_t {}
+
         #[repr(C)]
         pub struct pthread_cond_t {
             __sig: libc::c_long,
             __opaque: [u8, ..__PTHREAD_COND_SIZE__],
         }
 
+        impl Copy for pthread_cond_t {}
+
         pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
             __sig: _PTHREAD_MUTEX_SIG_INIT,
             __opaque: [0, ..__PTHREAD_MUTEX_SIZE__],
@@ -402,6 +408,7 @@ mod imp {
 
     #[cfg(target_os = "linux")]
     mod os {
+        use core::kinds::Copy;
         use libc;
 
         // minus 8 because we have an 'align' field
@@ -431,12 +438,17 @@ mod imp {
             __align: libc::c_longlong,
             size: [u8, ..__SIZEOF_PTHREAD_MUTEX_T],
         }
+
+        impl Copy for pthread_mutex_t {}
+
         #[repr(C)]
         pub struct pthread_cond_t {
             __align: libc::c_longlong,
             size: [u8, ..__SIZEOF_PTHREAD_COND_T],
         }
 
+        impl Copy for pthread_cond_t {}
+
         pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
             __align: 0,
             size: [0, ..__SIZEOF_PTHREAD_MUTEX_T],
diff --git a/src/librustrt/unwind.rs b/src/librustrt/unwind.rs
index 697ee95df4c..714d30ae4b1 100644
--- a/src/librustrt/unwind.rs
+++ b/src/librustrt/unwind.rs
@@ -77,6 +77,7 @@ use task::Task;
 
 use libunwind as uw;
 
+#[allow(missing_copy_implementations)]
 pub struct Unwinder {
     unwinding: bool,
 }
diff --git a/src/librustrt/util.rs b/src/librustrt/util.rs
index c77fbd4aee0..fd30c3a48d2 100644
--- a/src/librustrt/util.rs
+++ b/src/librustrt/util.rs
@@ -29,6 +29,9 @@ pub const ENFORCE_SANITY: bool = true || !cfg!(rtopt) || cfg!(rtdebug) ||
 pub struct Stdio(libc::c_int);
 
 #[allow(non_upper_case_globals)]
+impl Copy for Stdio {}
+
+#[allow(non_uppercase_statics)]
 pub const Stdout: Stdio = Stdio(libc::STDOUT_FILENO);
 #[allow(non_upper_case_globals)]
 pub const Stderr: Stdio = Stdio(libc::STDERR_FILENO);
diff --git a/src/libserialize/base64.rs b/src/libserialize/base64.rs
index c8ec1700a1d..dd5039c9b82 100644
--- a/src/libserialize/base64.rs
+++ b/src/libserialize/base64.rs
@@ -26,6 +26,8 @@ pub enum CharacterSet {
     UrlSafe
 }
 
+impl Copy for CharacterSet {}
+
 /// Contains configuration parameters for `to_base64`.
 pub struct Config {
     /// Character set to use
@@ -36,6 +38,8 @@ pub struct Config {
     pub line_length: Option<uint>
 }
 
+impl Copy for Config {}
+
 /// Configuration for RFC 4648 standard base64 encoding
 pub static STANDARD: Config =
     Config {char_set: Standard, pad: true, line_length: None};
@@ -168,6 +172,8 @@ pub enum FromBase64Error {
     InvalidBase64Length,
 }
 
+impl Copy for FromBase64Error {}
+
 impl fmt::Show for FromBase64Error {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
diff --git a/src/libserialize/hex.rs b/src/libserialize/hex.rs
index 4c20f72cac5..22392056ddf 100644
--- a/src/libserialize/hex.rs
+++ b/src/libserialize/hex.rs
@@ -68,6 +68,8 @@ pub enum FromHexError {
     InvalidHexLength,
 }
 
+impl Copy for FromHexError {}
+
 impl fmt::Show for FromHexError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs
index 248d78236ad..318c21234f5 100644
--- a/src/libserialize/json.rs
+++ b/src/libserialize/json.rs
@@ -247,6 +247,8 @@ pub enum ErrorCode {
     NotUtf8,
 }
 
+impl Copy for ErrorCode {}
+
 #[deriving(Clone, PartialEq, Show)]
 pub enum ParserError {
     /// msg, line, col
@@ -254,6 +256,8 @@ pub enum ParserError {
     IoError(io::IoErrorKind, &'static str),
 }
 
+impl Copy for ParserError {}
+
 // Builder and Parser have the same errors.
 pub type BuilderError = ParserError;
 
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index 2872f74cf88..23eb367dbd1 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -18,6 +18,7 @@
 use core::kinds::Sized;
 use fmt;
 use iter::IteratorExt;
+use kinds::Copy;
 use mem;
 use option::Option;
 use option::Option::{Some, None};
@@ -30,6 +31,8 @@ use vec::Vec;
 #[deriving(Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
 pub struct Ascii { chr: u8 }
 
+impl Copy for Ascii {}
+
 impl Ascii {
     /// Converts an ascii character into a `u8`.
     #[inline]
diff --git a/src/libstd/bitflags.rs b/src/libstd/bitflags.rs
index 8a90c06f038..ffcd6505dad 100644
--- a/src/libstd/bitflags.rs
+++ b/src/libstd/bitflags.rs
@@ -33,6 +33,8 @@
 ///     }
 /// }
 ///
+/// impl Copy for Flags {}
+///
 /// fn main() {
 ///     let e1 = FLAG_A | FLAG_C;
 ///     let e2 = FLAG_B | FLAG_C;
@@ -55,6 +57,8 @@
 ///     }
 /// }
 ///
+/// impl Copy for Flags {}
+///
 /// impl Flags {
 ///     pub fn clear(&mut self) {
 ///         self.bits = 0;  // The `bits` field can be accessed from within the
@@ -260,6 +264,7 @@ macro_rules! bitflags {
 #[cfg(test)]
 #[allow(non_upper_case_globals)]
 mod tests {
+    use kinds::Copy;
     use hash;
     use option::Option::{Some, None};
     use ops::{BitOr, BitAnd, BitXor, Sub, Not};
@@ -283,12 +288,16 @@ mod tests {
         }
     }
 
+    impl Copy for Flags {}
+
     bitflags! {
         flags AnotherSetOfFlags: i8 {
             const AnotherFlag = -1_i8,
         }
     }
 
+    impl Copy for AnotherSetOfFlags {}
+
     #[test]
     fn test_bits(){
         assert_eq!(Flags::empty().bits(), 0x00000000);
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index de06a1e0bbd..ef4cabedc47 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -16,7 +16,7 @@ use clone::Clone;
 use cmp;
 use hash::{Hash, Hasher};
 use iter::{Iterator, count};
-use kinds::{Sized, marker};
+use kinds::{Copy, Sized, marker};
 use mem::{min_align_of, size_of};
 use mem;
 use num::{Int, UnsignedInt};
@@ -81,12 +81,16 @@ struct RawBucket<K, V> {
     val:  *mut V
 }
 
+impl<K,V> Copy for RawBucket<K,V> {}
+
 pub struct Bucket<K, V, M> {
     raw:   RawBucket<K, V>,
     idx:   uint,
     table: M
 }
 
+impl<K,V,M:Copy> Copy for Bucket<K,V,M> {}
+
 pub struct EmptyBucket<K, V, M> {
     raw:   RawBucket<K, V>,
     idx:   uint,
diff --git a/src/libstd/comm/mod.rs b/src/libstd/comm/mod.rs
index d291ed72567..6cff5a3dd23 100644
--- a/src/libstd/comm/mod.rs
+++ b/src/libstd/comm/mod.rs
@@ -405,6 +405,8 @@ pub enum TryRecvError {
     Disconnected,
 }
 
+impl Copy for TryRecvError {}
+
 /// This enumeration is the list of the possible error outcomes for the
 /// `SyncSender::try_send` method.
 #[deriving(PartialEq, Clone, Show)]
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index aa0c8b53c2e..5609fbf16cd 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -29,7 +29,10 @@ use str;
 use string::String;
 use vec::Vec;
 
-pub struct DynamicLibrary { handle: *mut u8 }
+#[allow(missing_copy_implementations)]
+pub struct DynamicLibrary {
+    handle: *mut u8
+}
 
 impl Drop for DynamicLibrary {
     fn drop(&mut self) {
@@ -210,6 +213,7 @@ pub mod dl {
 
     use c_str::{CString, ToCStr};
     use libc;
+    use kinds::Copy;
     use ptr;
     use result::*;
     use string::String;
@@ -262,6 +266,8 @@ pub mod dl {
         Local = 0,
     }
 
+    impl Copy for Rtld {}
+
     #[link_name = "dl"]
     extern {
         fn dlopen(filename: *const libc::c_char,
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index d43a7a66c5b..dc212e7cab3 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -231,6 +231,7 @@ use error::{FromError, Error};
 use fmt;
 use int;
 use iter::{Iterator, IteratorExt};
+use kinds::Copy;
 use mem::transmute;
 use ops::{BitOr, BitXor, BitAnd, Sub, Not};
 use option::Option;
@@ -420,6 +421,8 @@ pub enum IoErrorKind {
     NoProgress,
 }
 
+impl Copy for IoErrorKind {}
+
 /// A trait that lets you add a `detail` to an IoError easily
 trait UpdateIoError<T> {
     /// Returns an IoError with updated description and detail
@@ -1560,6 +1563,8 @@ pub enum SeekStyle {
     SeekCur,
 }
 
+impl Copy for SeekStyle {}
+
 /// An object implementing `Seek` internally has some form of cursor which can
 /// be moved within a stream of bytes. The stream typically has a fixed size,
 /// allowing seeking relative to either end.
@@ -1682,6 +1687,8 @@ pub enum FileMode {
     Truncate,
 }
 
+impl Copy for FileMode {}
+
 /// Access permissions with which the file should be opened. `File`s
 /// opened with `Read` will return an error if written to.
 pub enum FileAccess {
@@ -1693,6 +1700,8 @@ pub enum FileAccess {
     ReadWrite,
 }
 
+impl Copy for FileAccess {}
+
 /// Different kinds of files which can be identified by a call to stat
 #[deriving(PartialEq, Show, Hash, Clone)]
 pub enum FileType {
@@ -1715,6 +1724,8 @@ pub enum FileType {
     Unknown,
 }
 
+impl Copy for FileType {}
+
 /// A structure used to describe metadata information about a file. This
 /// structure is created through the `stat` method on a `Path`.
 ///
@@ -1766,6 +1777,8 @@ pub struct FileStat {
     pub unstable: UnstableFileStat,
 }
 
+impl Copy for FileStat {}
+
 /// This structure represents all of the possible information which can be
 /// returned from a `stat` syscall which is not contained in the `FileStat`
 /// structure. This information is not necessarily platform independent, and may
@@ -1795,6 +1808,8 @@ pub struct UnstableFileStat {
     pub gen: u64,
 }
 
+impl Copy for UnstableFileStat {}
+
 bitflags! {
     #[doc = "A set of permissions for a file or directory is represented"]
     #[doc = "by a set of flags which are or'd together."]
@@ -1889,6 +1904,8 @@ bitflags! {
     }
 }
 
+impl Copy for FilePermission {}
+
 impl Default for FilePermission {
     #[inline]
     fn default() -> FilePermission { FilePermission::empty() }
diff --git a/src/libstd/io/net/addrinfo.rs b/src/libstd/io/net/addrinfo.rs
index fea8372733c..fc81ab7b57a 100644
--- a/src/libstd/io/net/addrinfo.rs
+++ b/src/libstd/io/net/addrinfo.rs
@@ -22,6 +22,7 @@ pub use self::Protocol::*;
 use iter::IteratorExt;
 use io::{IoResult};
 use io::net::ip::{SocketAddr, IpAddr};
+use kinds::Copy;
 use option::Option;
 use option::Option::{Some, None};
 use sys;
@@ -32,6 +33,8 @@ pub enum SocketType {
     Stream, Datagram, Raw
 }
 
+impl Copy for SocketType {}
+
 /// Flags which can be or'd into the `flags` field of a `Hint`. These are used
 /// to manipulate how a query is performed.
 ///
@@ -46,12 +49,16 @@ pub enum Flag {
     V4Mapped,
 }
 
+impl Copy for Flag {}
+
 /// A transport protocol associated with either a hint or a return value of
 /// `lookup`
 pub enum Protocol {
     TCP, UDP
 }
 
+impl Copy for Protocol {}
+
 /// This structure is used to provide hints when fetching addresses for a
 /// remote host to control how the lookup is performed.
 ///
@@ -64,6 +71,8 @@ pub struct Hint {
     pub flags: uint,
 }
 
+impl Copy for Hint {}
+
 pub struct Info {
     pub address: SocketAddr,
     pub family: uint,
@@ -72,6 +81,8 @@ pub struct Info {
     pub flags: uint,
 }
 
+impl Copy for Info {}
+
 /// Easy name resolution. Given a hostname, returns the list of IP addresses for
 /// that hostname.
 pub fn get_host_addresses(host: &str) -> IoResult<Vec<IpAddr>> {
diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs
index 3fa6f4a6091..f59dd37c0da 100644
--- a/src/libstd/io/net/ip.rs
+++ b/src/libstd/io/net/ip.rs
@@ -18,6 +18,7 @@
 pub use self::IpAddr::*;
 
 use fmt;
+use kinds::Copy;
 use io::{mod, IoResult, IoError};
 use io::net;
 use iter::{Iterator, IteratorExt};
@@ -36,6 +37,8 @@ pub enum IpAddr {
     Ipv6Addr(u16, u16, u16, u16, u16, u16, u16, u16)
 }
 
+impl Copy for IpAddr {}
+
 impl fmt::Show for IpAddr {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
         match *self {
@@ -67,6 +70,8 @@ pub struct SocketAddr {
     pub port: Port,
 }
 
+impl Copy for SocketAddr {}
+
 impl fmt::Show for SocketAddr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self.ip {
diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs
index 61ebfb06c71..c46a6e82e44 100644
--- a/src/libstd/io/process.rs
+++ b/src/libstd/io/process.rs
@@ -480,6 +480,8 @@ pub enum StdioContainer {
     CreatePipe(bool /* readable */, bool /* writable */),
 }
 
+impl Copy for StdioContainer {}
+
 /// Describes the result of a process after it has terminated.
 /// Note that Windows have no signals, so the result is usually ExitStatus.
 #[deriving(PartialEq, Eq, Clone)]
@@ -491,6 +493,8 @@ pub enum ProcessExit {
     ExitSignal(int),
 }
 
+impl Copy for ProcessExit {}
+
 impl fmt::Show for ProcessExit {
     /// Format a ProcessExit enum, to nicely present the information.
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index e78bd1dd33f..faa52226a03 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -83,6 +83,8 @@ impl<R: Buffer> Buffer for LimitReader<R> {
 /// A `Writer` which ignores bytes written to it, like /dev/null.
 pub struct NullWriter;
 
+impl Copy for NullWriter {}
+
 impl Writer for NullWriter {
     #[inline]
     fn write(&mut self, _buf: &[u8]) -> io::IoResult<()> { Ok(()) }
@@ -91,6 +93,8 @@ impl Writer for NullWriter {
 /// A `Reader` which returns an infinite stream of 0 bytes, like /dev/zero.
 pub struct ZeroReader;
 
+impl Copy for ZeroReader {}
+
 impl Reader for ZeroReader {
     #[inline]
     fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
@@ -111,6 +115,8 @@ impl Buffer for ZeroReader {
 /// A `Reader` which is always at EOF, like /dev/null.
 pub struct NullReader;
 
+impl Copy for NullReader {}
+
 impl Reader for NullReader {
     #[inline]
     fn read(&mut self, _buf: &mut [u8]) -> io::IoResult<uint> {
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index c87f40f351b..1c9826ff5ac 100644
--- a/src/libstd/num/strconv.rs
+++ b/src/libstd/num/strconv.rs
@@ -18,6 +18,7 @@ pub use self::SignFormat::*;
 
 use char;
 use char::Char;
+use kinds::Copy;
 use num;
 use num::{Int, Float, FPNaN, FPInfinite, ToPrimitive};
 use slice::{SlicePrelude, CloneSliceAllocPrelude};
@@ -38,6 +39,8 @@ pub enum ExponentFormat {
     ExpBin,
 }
 
+impl Copy for ExponentFormat {}
+
 /// The number of digits used for emitting the fractional part of a number, if
 /// any.
 pub enum SignificantDigits {
@@ -55,6 +58,8 @@ pub enum SignificantDigits {
     DigExact(uint)
 }
 
+impl Copy for SignificantDigits {}
+
 /// How to emit the sign of a number.
 pub enum SignFormat {
     /// No sign will be printed. The exponent sign will also be emitted.
@@ -67,25 +72,33 @@ pub enum SignFormat {
     SignAll,
 }
 
-/// Converts an integral number to its string representation as a byte vector.
-/// This is meant to be a common base implementation for all integral string
-/// conversion functions like `to_string()` or `to_str_radix()`.
-///
-/// # Arguments
-///
-/// - `num`           - The number to convert. Accepts any number that
-///                     implements the numeric traits.
-/// - `radix`         - Base to use. Accepts only the values 2-36.
-/// - `sign`          - How to emit the sign. Options are:
-///     - `SignNone`: No sign at all. Basically emits `abs(num)`.
-///     - `SignNeg`:  Only `-` on negative values.
-///     - `SignAll`:  Both `+` on positive, and `-` on negative numbers.
-/// - `f`             - a callback which will be invoked for each ascii character
-///                     which composes the string representation of this integer
-///
-/// # Panics
-///
-/// - Panics if `radix` < 2 or `radix` > 36.
+impl Copy for SignFormat {}
+
+/**
+ * Converts an integral number to its string representation as a byte vector.
+ * This is meant to be a common base implementation for all integral string
+ * conversion functions like `to_string()` or `to_str_radix()`.
+ *
+ * # Arguments
+ * - `num`           - The number to convert. Accepts any number that
+ *                     implements the numeric traits.
+ * - `radix`         - Base to use. Accepts only the values 2-36.
+ * - `sign`          - How to emit the sign. Options are:
+ *     - `SignNone`: No sign at all. Basically emits `abs(num)`.
+ *     - `SignNeg`:  Only `-` on negative values.
+ *     - `SignAll`:  Both `+` on positive, and `-` on negative numbers.
+ * - `f`             - a callback which will be invoked for each ascii character
+ *                     which composes the string representation of this integer
+ *
+ * # Return value
+ * A tuple containing the byte vector, and a boolean flag indicating
+ * whether it represents a special value like `inf`, `-inf`, `NaN` or not.
+ * It returns a tuple because there can be ambiguity between a special value
+ * and a number representation at higher bases.
+ *
+ * # Failure
+ * - Fails if `radix` < 2 or `radix` > 36.
+ */
 fn int_to_str_bytes_common<T: Int>(num: T, radix: uint, sign: SignFormat, f: |u8|) {
     assert!(2 <= radix && radix <= 36);
 
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index 2b904acb565..f298ec74f6a 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -36,6 +36,7 @@ use error::{FromError, Error};
 use fmt;
 use io::{IoResult, IoError};
 use iter::{Iterator, IteratorExt};
+use kinds::Copy;
 use libc::{c_void, c_int};
 use libc;
 use boxed::Box;
@@ -619,6 +620,8 @@ pub struct Pipe {
     pub writer: c_int,
 }
 
+impl Copy for Pipe {}
+
 /// Creates a new low-level OS in-memory pipe.
 ///
 /// This function can fail to succeed if there are no more resources available
@@ -1185,6 +1188,9 @@ pub struct MemoryMap {
     kind: MemoryMapKind,
 }
 
+#[cfg(not(stage0))]
+impl Copy for MemoryMap {}
+
 /// Type of memory map
 pub enum MemoryMapKind {
     /// Virtual memory map. Usually used to change the permissions of a given
@@ -1196,6 +1202,8 @@ pub enum MemoryMapKind {
     MapVirtual
 }
 
+impl Copy for MemoryMapKind {}
+
 /// Options the memory map is created with
 pub enum MapOption {
     /// The memory should be readable
@@ -1219,6 +1227,8 @@ pub enum MapOption {
     MapNonStandardFlags(c_int),
 }
 
+impl Copy for MapOption {}
+
 /// Possible errors when creating a map.
 pub enum MapError {
     /// ## The following are POSIX-specific
@@ -1264,6 +1274,8 @@ pub enum MapError {
     ErrMapViewOfFile(uint)
 }
 
+impl Copy for MapError {}
+
 impl fmt::Show for MapError {
     fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
         let str = match *self {
diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs
index b53e6b2a5e0..ea522536d22 100644
--- a/src/libstd/path/windows.rs
+++ b/src/libstd/path/windows.rs
@@ -22,6 +22,7 @@ use hash;
 use io::Writer;
 use iter::{AdditiveIterator, DoubleEndedIteratorExt, Extend};
 use iter::{Iterator, IteratorExt, Map};
+use kinds::Copy;
 use mem;
 use option::Option;
 use option::Option::{Some, None};
@@ -985,6 +986,8 @@ pub enum PathPrefix {
     DiskPrefix
 }
 
+impl Copy for PathPrefix {}
+
 fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> {
     if path.starts_with("\\\\") {
         // \\
diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs
index cc3c46f3610..a359fcf7a9f 100644
--- a/src/libstd/rand/mod.rs
+++ b/src/libstd/rand/mod.rs
@@ -225,6 +225,7 @@ use cell::RefCell;
 use clone::Clone;
 use io::IoResult;
 use iter::{Iterator, IteratorExt};
+use kinds::Copy;
 use mem;
 use rc::Rc;
 use result::Result::{Ok, Err};
@@ -245,7 +246,11 @@ pub mod reader;
 
 /// The standard RNG. This is designed to be efficient on the current
 /// platform.
-pub struct StdRng { rng: IsaacWordRng }
+pub struct StdRng {
+    rng: IsaacWordRng,
+}
+
+impl Copy for StdRng {}
 
 impl StdRng {
     /// Create a randomly seeded instance of `StdRng`.
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index 86c3a1fdd32..7e6065129a3 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -13,6 +13,7 @@
 #![experimental]
 
 use {fmt, i64};
+use kinds::Copy;
 use ops::{Add, Sub, Mul, Div, Neg};
 use option::Option;
 use option::Option::{Some, None};
@@ -64,6 +65,8 @@ pub const MAX: Duration = Duration {
     nanos: (i64::MAX % MILLIS_PER_SEC) as i32 * NANOS_PER_MILLI
 };
 
+impl Copy for Duration {}
+
 impl Duration {
     /// Makes a new `Duration` with given number of weeks.
     /// Equivalent to `Duration::seconds(weeks * 7 * 24 * 60 * 60), with overflow checks.
diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs
index 87693f39bbd..71d29bca401 100644
--- a/src/libsyntax/abi.rs
+++ b/src/libsyntax/abi.rs
@@ -16,8 +16,17 @@ pub use self::AbiArchitecture::*;
 use std::fmt;
 
 #[deriving(PartialEq)]
-pub enum Os { OsWindows, OsMacos, OsLinux, OsAndroid, OsFreebsd, OsiOS,
-              OsDragonfly }
+pub enum Os {
+    OsWindows,
+    OsMacos,
+    OsLinux,
+    OsAndroid,
+    OsFreebsd,
+    OsiOS,
+    OsDragonfly,
+}
+
+impl Copy for Os {}
 
 #[deriving(PartialEq, Eq, Hash, Encodable, Decodable, Clone)]
 pub enum Abi {
@@ -39,6 +48,8 @@ pub enum Abi {
     RustCall,
 }
 
+impl Copy for Abi {}
+
 #[allow(non_camel_case_types)]
 #[deriving(PartialEq)]
 pub enum Architecture {
@@ -49,6 +60,8 @@ pub enum Architecture {
     Mipsel
 }
 
+impl Copy for Architecture {}
+
 pub struct AbiData {
     abi: Abi,
 
@@ -56,6 +69,8 @@ pub struct AbiData {
     name: &'static str,
 }
 
+impl Copy for AbiData {}
+
 pub enum AbiArchitecture {
     /// Not a real ABI (e.g., intrinsic)
     RustArch,
@@ -66,6 +81,9 @@ pub enum AbiArchitecture {
 }
 
 #[allow(non_upper_case_globals)]
+impl Copy for AbiArchitecture {}
+
+#[allow(non_upper_case_globals)]
 static AbiDatas: &'static [AbiData] = &[
     // Platform-specific ABIs
     AbiData {abi: Cdecl, name: "cdecl" },
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 7e421df505d..0a04a953b31 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -86,6 +86,8 @@ pub struct Ident {
     pub ctxt: SyntaxContext
 }
 
+impl Copy for Ident {}
+
 impl Ident {
     /// Construct an identifier with the given name and an empty context:
     pub fn new(name: Name) -> Ident { Ident {name: name, ctxt: EMPTY_CTXT}}
@@ -161,6 +163,8 @@ pub const ILLEGAL_CTXT : SyntaxContext = 1;
 #[deriving(Eq, Ord, PartialEq, PartialOrd, Hash, Encodable, Decodable, Clone)]
 pub struct Name(pub u32);
 
+impl Copy for Name {}
+
 impl Name {
     pub fn as_str<'a>(&'a self) -> &'a str {
         unsafe {
@@ -204,6 +208,8 @@ pub struct Lifetime {
     pub name: Name
 }
 
+impl Copy for Lifetime {}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct LifetimeDef {
     pub lifetime: Lifetime,
@@ -338,6 +344,8 @@ pub struct DefId {
     pub node: NodeId,
 }
 
+impl Copy for DefId {}
+
 /// Item definitions in the currently-compiled crate would have the CrateNum
 /// LOCAL_CRATE in their DefId.
 pub const LOCAL_CRATE: CrateNum = 0;
@@ -482,6 +490,8 @@ pub enum BindingMode {
     BindByValue(Mutability),
 }
 
+impl Copy for BindingMode {}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum PatWildKind {
     /// Represents the wildcard pattern `_`
@@ -491,6 +501,8 @@ pub enum PatWildKind {
     PatWildMulti,
 }
 
+impl Copy for PatWildKind {}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum Pat_ {
     /// Represents a wildcard pattern (either `_` or `..`)
@@ -526,6 +538,8 @@ pub enum Mutability {
     MutImmutable,
 }
 
+impl Copy for Mutability {}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum BinOp {
     BiAdd,
@@ -548,6 +562,9 @@ pub enum BinOp {
     BiGt,
 }
 
+#[cfg(not(stage0))]
+impl Copy for BinOp {}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum UnOp {
     UnUniq,
@@ -556,6 +573,8 @@ pub enum UnOp {
     UnNeg
 }
 
+impl Copy for UnOp {}
+
 pub type Stmt = Spanned<Stmt_>;
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
@@ -581,6 +600,8 @@ pub enum LocalSource {
     LocalFor,
 }
 
+impl Copy for LocalSource {}
+
 // FIXME (pending discussion of #1697, #2178...): local should really be
 // a refinement on pat.
 /// Local represents a `let` statement, e.g., `let <pat>:<ty> = <expr>;`
@@ -628,12 +649,16 @@ pub enum BlockCheckMode {
     UnsafeBlock(UnsafeSource),
 }
 
+impl Copy for BlockCheckMode {}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum UnsafeSource {
     CompilerGenerated,
     UserProvided,
 }
 
+impl Copy for UnsafeSource {}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct Expr {
     pub id: NodeId,
@@ -718,12 +743,16 @@ pub enum MatchSource {
     MatchWhileLetDesugar,
 }
 
+impl Copy for MatchSource {}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub enum CaptureClause {
     CaptureByValue,
     CaptureByRef,
 }
 
+impl Copy for CaptureClause {}
+
 /// A delimited sequence of token trees
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct Delimited {
@@ -780,6 +809,8 @@ pub enum KleeneOp {
     OneOrMore,
 }
 
+impl Copy for KleeneOp {}
+
 /// When the main rust parser encounters a syntax-extension invocation, it
 /// parses the arguments to the invocation as a token-tree. This is a very
 /// loose structure, such that all sorts of different AST-fragments can
@@ -895,6 +926,8 @@ pub enum StrStyle {
     RawStr(uint)
 }
 
+impl Copy for StrStyle {}
+
 pub type Lit = Spanned<Lit_>;
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
@@ -903,7 +936,9 @@ pub enum Sign {
     Plus
 }
 
-impl<T: Int> Sign {
+impl Copy for Sign {}
+
+impl<T> Sign where T: Int {
     pub fn new(n: T) -> Sign {
         if n < Int::zero() {
             Minus
@@ -920,6 +955,8 @@ pub enum LitIntType {
     UnsuffixedIntLit(Sign)
 }
 
+impl Copy for LitIntType {}
+
 impl LitIntType {
     pub fn suffix_len(&self) -> uint {
         match *self {
@@ -1015,6 +1052,8 @@ pub enum IntTy {
     TyI64,
 }
 
+impl Copy for IntTy {}
+
 impl fmt::Show for IntTy {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "{}", ast_util::int_ty_to_string(*self, None))
@@ -1040,6 +1079,8 @@ pub enum UintTy {
     TyU64,
 }
 
+impl Copy for UintTy {}
+
 impl UintTy {
     pub fn suffix_len(&self) -> uint {
         match *self {
@@ -1062,6 +1103,8 @@ pub enum FloatTy {
     TyF64,
 }
 
+impl Copy for FloatTy {}
+
 impl fmt::Show for FloatTy {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "{}", ast_util::float_ty_to_string(*self))
@@ -1095,12 +1138,16 @@ pub enum PrimTy {
     TyChar
 }
 
+impl Copy for PrimTy {}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash)]
 pub enum Onceness {
     Once,
     Many
 }
 
+impl Copy for Onceness {}
+
 impl fmt::Show for Onceness {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
@@ -1171,6 +1218,8 @@ pub enum AsmDialect {
     AsmIntel
 }
 
+impl Copy for AsmDialect {}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct InlineAsm {
     pub asm: InternedString,
@@ -1228,6 +1277,8 @@ pub enum FnStyle {
     NormalFn,
 }
 
+impl Copy for FnStyle {}
+
 impl fmt::Show for FnStyle {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
@@ -1345,6 +1396,8 @@ pub enum PathListItem_ {
     PathListMod { id: NodeId }
 }
 
+impl Copy for PathListItem_ {}
+
 impl PathListItem_ {
     pub fn id(&self) -> NodeId {
         match *self {
@@ -1404,9 +1457,13 @@ pub enum AttrStyle {
     AttrInner,
 }
 
+impl Copy for AttrStyle {}
+
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct AttrId(pub uint);
 
+impl Copy for AttrId {}
+
 /// Doc-comments are promoted to attributes that have is_sugared_doc = true
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
 pub struct Attribute_ {
@@ -1442,6 +1499,8 @@ pub enum Visibility {
     Inherited,
 }
 
+impl Copy for Visibility {}
+
 impl Visibility {
     pub fn inherit_from(&self, parent_visibility: Visibility) -> Visibility {
         match self {
@@ -1477,6 +1536,8 @@ pub enum StructFieldKind {
     UnnamedField(Visibility),
 }
 
+impl Copy for StructFieldKind {}
+
 impl StructFieldKind {
     pub fn is_unnamed(&self) -> bool {
         match *self {
@@ -1583,6 +1644,8 @@ pub enum UnboxedClosureKind {
     FnOnceUnboxedClosureKind,
 }
 
+impl Copy for UnboxedClosureKind {}
+
 /// The data we save and restore about an inlined item or method.  This is not
 /// part of the AST that we parse from a file, but it becomes part of the tree
 /// that we trans.
diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs
index 8db12fbd835..639a33a8063 100644
--- a/src/libsyntax/ast_map/blocks.rs
+++ b/src/libsyntax/ast_map/blocks.rs
@@ -43,6 +43,8 @@ use visit;
 /// To construct one, use the `Code::from_node` function.
 pub struct FnLikeNode<'a> { node: ast_map::Node<'a> }
 
+impl<'a> Copy for FnLikeNode<'a> {}
+
 /// MaybeFnLike wraps a method that indicates if an object
 /// corresponds to some FnLikeNode.
 pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; }
@@ -85,6 +87,8 @@ pub enum Code<'a> {
     BlockCode(&'a Block),
 }
 
+impl<'a> Copy for Code<'a> {}
+
 impl<'a> Code<'a> {
     pub fn id(&self) -> ast::NodeId {
         match *self {
diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs
index ce2fe6e7220..2c985f403f8 100644
--- a/src/libsyntax/ast_map/mod.rs
+++ b/src/libsyntax/ast_map/mod.rs
@@ -38,6 +38,8 @@ pub enum PathElem {
     PathName(Name)
 }
 
+impl Copy for PathElem {}
+
 impl PathElem {
     pub fn name(&self) -> Name {
         match *self {
@@ -120,6 +122,8 @@ pub enum Node<'ast> {
     NodeLifetime(&'ast Lifetime),
 }
 
+impl<'ast> Copy for Node<'ast> {}
+
 /// Represents an entry and its parent Node ID
 /// The odd layout is to bring down the total size.
 #[deriving(Show)]
@@ -147,6 +151,8 @@ enum MapEntry<'ast> {
     RootInlinedParent(&'ast InlinedParent)
 }
 
+impl<'ast> Copy for MapEntry<'ast> {}
+
 impl<'ast> Clone for MapEntry<'ast> {
     fn clone(&self) -> MapEntry<'ast> {
         *self
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index 68bb7ecfb85..7dba6a57fc4 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -315,6 +315,8 @@ pub struct IdRange {
     pub max: NodeId,
 }
 
+impl Copy for IdRange {}
+
 impl IdRange {
     pub fn max() -> IdRange {
         IdRange {
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index a2811681efd..5894a88ece6 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -282,6 +282,8 @@ pub enum InlineAttr {
     InlineNever,
 }
 
+impl Copy for InlineAttr {}
+
 /// Determine what `#[inline]` attribute is present in `attrs`, if any.
 pub fn find_inline_attr(attrs: &[Attribute]) -> InlineAttr {
     // FIXME (#2809)---validate the usage of #[inline] and #[inline]
@@ -354,6 +356,8 @@ pub enum StabilityLevel {
     Locked
 }
 
+impl Copy for StabilityLevel {}
+
 pub fn find_stability_generic<'a,
                               AM: AttrMetaMethods,
                               I: Iterator<&'a AM>>
@@ -469,6 +473,8 @@ pub enum ReprAttr {
     ReprPacked,
 }
 
+impl Copy for ReprAttr {}
+
 impl ReprAttr {
     pub fn is_ffi_safe(&self) -> bool {
         match *self {
@@ -486,6 +492,8 @@ pub enum IntType {
     UnsignedInt(ast::UintTy)
 }
 
+impl Copy for IntType {}
+
 impl IntType {
     #[inline]
     pub fn is_signed(self) -> bool {
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index 6bcf562204b..50b4f342368 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -34,12 +34,16 @@ pub trait Pos {
 #[deriving(Clone, PartialEq, Eq, Hash, PartialOrd, Show)]
 pub struct BytePos(pub u32);
 
+impl Copy for BytePos {}
+
 /// A character offset. Because of multibyte utf8 characters, a byte offset
 /// is not equivalent to a character offset. The CodeMap will convert BytePos
 /// values to CharPos values as necessary.
 #[deriving(PartialEq, Hash, PartialOrd, Show)]
 pub struct CharPos(pub uint);
 
+impl Copy for CharPos {}
+
 // FIXME: Lots of boilerplate in these impls, but so far my attempts to fix
 // have been unsuccessful
 
@@ -90,6 +94,8 @@ pub struct Span {
     pub expn_id: ExpnId
 }
 
+impl Copy for Span {}
+
 pub const DUMMY_SP: Span = Span { lo: BytePos(0), hi: BytePos(0), expn_id: NO_EXPANSION };
 
 #[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
@@ -98,6 +104,8 @@ pub struct Spanned<T> {
     pub span: Span,
 }
 
+impl<T:Copy> Copy for Spanned<T> {}
+
 impl PartialEq for Span {
     fn eq(&self, other: &Span) -> bool {
         return (*self).lo == (*other).lo && (*self).hi == (*other).hi;
@@ -183,6 +191,8 @@ pub enum MacroFormat {
     MacroBang
 }
 
+impl Copy for MacroFormat {}
+
 #[deriving(Clone, Hash, Show)]
 pub struct NameAndSpan {
     /// The name of the macro that was invoked to create the thing
@@ -221,6 +231,8 @@ pub struct ExpnInfo {
 #[deriving(PartialEq, Eq, Clone, Show, Hash, Encodable, Decodable)]
 pub struct ExpnId(u32);
 
+impl Copy for ExpnId {}
+
 pub const NO_EXPANSION: ExpnId = ExpnId(-1);
 
 impl ExpnId {
@@ -249,6 +261,8 @@ pub struct MultiByteChar {
     pub bytes: uint,
 }
 
+impl Copy for MultiByteChar {}
+
 /// A single source in the CodeMap
 pub struct FileMap {
     /// The name of the file that the source came from, source that doesn't
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index 293c1b3a953..bbda80bd96c 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -40,6 +40,8 @@ pub enum RenderSpan {
     FileLine(Span),
 }
 
+impl Copy for RenderSpan {}
+
 impl RenderSpan {
     fn span(self) -> Span {
         match self {
@@ -61,6 +63,8 @@ pub enum ColorConfig {
     Never
 }
 
+impl Copy for ColorConfig {}
+
 pub trait Emitter {
     fn emit(&mut self, cmsp: Option<(&codemap::CodeMap, Span)>,
             msg: &str, code: Option<&str>, lvl: Level);
@@ -73,10 +77,14 @@ pub trait Emitter {
 /// how a rustc task died (if so desired).
 pub struct FatalError;
 
+impl Copy for FatalError {}
+
 /// Signifies that the compiler died with an explicit call to `.bug`
 /// or `.span_bug` rather than a failed assertion, etc.
 pub struct ExplicitBug;
 
+impl Copy for ExplicitBug {}
+
 /// A span-handler is like a handler but also
 /// accepts span information for source-location
 /// reporting.
@@ -230,6 +238,8 @@ pub enum Level {
     Help,
 }
 
+impl Copy for Level {}
+
 impl fmt::Show for Level {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         use std::fmt::Show;
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 0787518f04f..3c7a4a81d20 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -57,7 +57,7 @@ impl ItemDecorator for fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, |P<ast
               meta_item: &ast::MetaItem,
               item: &ast::Item,
               push: |P<ast::Item>|) {
-        (*self)(ecx, sp, meta_item, item, push)
+        self.clone()(ecx, sp, meta_item, item, push)
     }
 }
 
@@ -77,7 +77,7 @@ impl ItemModifier for fn(&mut ExtCtxt, Span, &ast::MetaItem, P<ast::Item>) -> P<
               meta_item: &ast::MetaItem,
               item: P<ast::Item>)
               -> P<ast::Item> {
-        (*self)(ecx, span, meta_item, item)
+        self.clone()(ecx, span, meta_item, item)
     }
 }
 
@@ -99,7 +99,7 @@ impl TTMacroExpander for MacroExpanderFn {
                    span: Span,
                    token_tree: &[ast::TokenTree])
                    -> Box<MacResult+'cx> {
-        (*self)(ecx, span, token_tree)
+        self.clone()(ecx, span, token_tree)
     }
 }
 
@@ -122,7 +122,7 @@ impl IdentMacroExpander for IdentMacroExpanderFn {
                    ident: ast::Ident,
                    token_tree: Vec<ast::TokenTree> )
                    -> Box<MacResult+'cx> {
-        (*self)(cx, sp, ident, token_tree)
+        self.clone()(cx, sp, ident, token_tree)
     }
 }
 
@@ -228,6 +228,8 @@ pub struct DummyResult {
     span: Span
 }
 
+impl Copy for DummyResult {}
+
 impl DummyResult {
     /// Create a default MacResult that can be anything.
     ///
diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs
index 787c6e844d5..1bd55b5d504 100644
--- a/src/libsyntax/ext/deriving/cmp/ord.rs
+++ b/src/libsyntax/ext/deriving/cmp/ord.rs
@@ -85,6 +85,8 @@ pub enum OrderingOp {
     PartialCmpOp, LtOp, LeOp, GtOp, GeOp,
 }
 
+impl Copy for OrderingOp {}
+
 pub fn some_ordering_collapsed(cx: &mut ExtCtxt,
                                span: Span,
                                op: OrderingOp,
diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs
index 6ba90bbebed..48120b575ac 100644
--- a/src/libsyntax/ext/mtwt.rs
+++ b/src/libsyntax/ext/mtwt.rs
@@ -56,6 +56,8 @@ pub enum SyntaxContext_ {
     IllegalCtxt
 }
 
+impl Copy for SyntaxContext_ {}
+
 /// A list of ident->name renamings
 pub type RenameList = Vec<(Ident, Name)>;
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 4af7b35079a..ac36e508f3b 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -103,6 +103,8 @@ pub struct Features {
     pub quote: bool,
 }
 
+impl Copy for Features {}
+
 impl Features {
     pub fn new() -> Features {
         Features {
diff --git a/src/libsyntax/parse/lexer/comments.rs b/src/libsyntax/parse/lexer/comments.rs
index aeec6ee13fd..a17d66476c0 100644
--- a/src/libsyntax/parse/lexer/comments.rs
+++ b/src/libsyntax/parse/lexer/comments.rs
@@ -36,6 +36,8 @@ pub enum CommentStyle {
     BlankLine,
 }
 
+impl Copy for CommentStyle {}
+
 #[deriving(Clone)]
 pub struct Comment {
     pub style: CommentStyle,
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 650f8295d01..2a2bb42cef0 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -34,6 +34,8 @@ pub enum ObsoleteSyntax {
     ObsoleteExternCrateRenaming,
 }
 
+impl Copy for ObsoleteSyntax {}
+
 pub trait ParserObsoleteMethods {
     /// Reports an obsolete syntax non-fatal error.
     fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax);
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index bb3d28ce2bb..4929ee885ac 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -98,6 +98,8 @@ bitflags! {
     }
 }
 
+impl Copy for Restrictions {}
+
 type ItemInfo = (Ident, Item_, Option<Vec<Attribute> >);
 
 /// How to parse a path. There are four different kinds of paths, all of which
@@ -114,6 +116,8 @@ pub enum PathParsingMode {
     LifetimeAndTypesWithColons,
 }
 
+impl Copy for PathParsingMode {}
+
 enum ItemOrViewItem {
     /// Indicates a failure to parse any kind of item. The attributes are
     /// returned.
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 52b54bc7f2d..4b1e9482a7d 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -42,6 +42,8 @@ pub enum BinOpToken {
     Shr,
 }
 
+impl Copy for BinOpToken {}
+
 /// A delimeter token
 #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash, Show)]
 pub enum DelimToken {
@@ -53,6 +55,8 @@ pub enum DelimToken {
     Brace,
 }
 
+impl Copy for DelimToken {}
+
 #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash, Show)]
 pub enum IdentStyle {
     /// `::` follows the identifier with no whitespace in-between.
@@ -85,6 +89,12 @@ impl Lit {
     }
 }
 
+#[cfg(not(stage0))]
+impl Copy for Lit {}
+
+#[cfg(not(stage0))]
+impl Copy for IdentStyle {}
+
 #[allow(non_camel_case_types)]
 #[deriving(Clone, Encodable, Decodable, PartialEq, Eq, Hash, Show)]
 pub enum Token {
@@ -435,6 +445,8 @@ macro_rules! declare_special_idents_and_keywords {(
             $( $rk_variant, )*
         }
 
+        impl Copy for Keyword {}
+
         impl Keyword {
             pub fn to_name(&self) -> ast::Name {
                 match *self {
diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs
index 7ab3d5dbcd1..c4e040a0f7c 100644
--- a/src/libsyntax/print/pp.rs
+++ b/src/libsyntax/print/pp.rs
@@ -72,18 +72,24 @@ pub enum Breaks {
     Inconsistent,
 }
 
+impl Copy for Breaks {}
+
 #[deriving(Clone)]
 pub struct BreakToken {
     offset: int,
     blank_space: int
 }
 
+impl Copy for BreakToken {}
+
 #[deriving(Clone)]
 pub struct BeginToken {
     offset: int,
     breaks: Breaks
 }
 
+impl Copy for BeginToken {}
+
 #[deriving(Clone)]
 pub enum Token {
     String(string::String, int),
@@ -152,11 +158,15 @@ pub enum PrintStackBreak {
     Broken(Breaks),
 }
 
+impl Copy for PrintStackBreak {}
+
 pub struct PrintStackElem {
     offset: int,
     pbreak: PrintStackBreak
 }
 
+impl Copy for PrintStackElem {}
+
 static SIZE_INFINITY: int = 0xffff;
 
 pub fn mk_printer(out: Box<io::Writer+'static>, linewidth: uint) -> Printer {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 6ce0ee79c62..eab03f73091 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -47,6 +47,8 @@ pub trait PpAnn {
 
 pub struct NoAnn;
 
+impl Copy for NoAnn {}
+
 impl PpAnn for NoAnn {}
 
 pub struct CurrentCommentAndLiteral {
@@ -54,6 +56,8 @@ pub struct CurrentCommentAndLiteral {
     cur_lit: uint,
 }
 
+impl Copy for CurrentCommentAndLiteral {}
+
 pub struct State<'a> {
     pub s: pp::Printer,
     cm: Option<&'a CodeMap>,
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 18623ca2a81..f5e89dd61ff 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -44,6 +44,8 @@ pub enum FnKind<'a> {
     FkFnBlock,
 }
 
+impl<'a> Copy for FnKind<'a> {}
+
 /// Each method of the Visitor trait is a hook to be potentially
 /// overridden.  Each method's default implementation recursively visits
 /// the substructure of the input via the corresponding `walk` method;
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs
index 0e4ecb8f73e..575ec860f97 100644
--- a/src/libterm/lib.rs
+++ b/src/libterm/lib.rs
@@ -165,6 +165,7 @@ pub mod color {
 /// Terminal attributes
 pub mod attr {
     pub use self::Attr::*;
+    use std::kinds::Copy;
 
     /// Terminal attributes for use with term.attr().
     ///
@@ -193,6 +194,8 @@ pub mod attr {
         /// Convenience attribute to set the background color
         BackgroundColor(super::color::Color)
     }
+
+    impl Copy for Attr {}
 }
 
 /// A terminal with similar capabilities to an ANSI Terminal
diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs
index ee8178fed91..c81bff6a1ae 100644
--- a/src/libterm/terminfo/parm.rs
+++ b/src/libterm/terminfo/parm.rs
@@ -33,6 +33,8 @@ enum States {
     SeekIfEndPercent(int)
 }
 
+impl Copy for States {}
+
 #[deriving(PartialEq)]
 enum FormatState {
     FormatStateFlags,
@@ -40,6 +42,8 @@ enum FormatState {
     FormatStatePrecision
 }
 
+impl Copy for FormatState {}
+
 /// Types of parameters a capability can use
 #[allow(missing_docs)]
 #[deriving(Clone)]
@@ -452,6 +456,8 @@ struct Flags {
     space: bool
 }
 
+impl Copy for Flags {}
+
 impl Flags {
     fn new() -> Flags {
         Flags{ width: 0, precision: 0, alternate: false,
@@ -467,6 +473,8 @@ enum FormatOp {
     FormatString
 }
 
+impl Copy for FormatOp {}
+
 impl FormatOp {
     fn from_char(c: char) -> FormatOp {
         match c {
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 06105ca61ca..ffc26738dd7 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -109,7 +109,13 @@ impl Show for TestName {
 }
 
 #[deriving(Clone)]
-enum NamePadding { PadNone, PadOnLeft, PadOnRight }
+enum NamePadding {
+    PadNone,
+    PadOnLeft,
+    PadOnRight,
+}
+
+impl Copy for NamePadding {}
 
 impl TestDesc {
     fn padded_name(&self, column_count: uint, align: NamePadding) -> String {
@@ -179,13 +185,14 @@ impl fmt::Show for TestFn {
 /// This is feed into functions marked with `#[bench]` to allow for
 /// set-up & tear-down before running a piece of code repeatedly via a
 /// call to `iter`.
+#[deriving(Copy)]
 pub struct Bencher {
     iterations: u64,
     dur: Duration,
     pub bytes: u64,
 }
 
-#[deriving(Clone, Show, PartialEq, Eq, Hash)]
+#[deriving(Copy, Clone, Show, PartialEq, Eq, Hash)]
 pub enum ShouldFail {
     No,
     Yes(Option<&'static str>)
@@ -212,6 +219,8 @@ pub struct Metric {
     noise: f64
 }
 
+impl Copy for Metric {}
+
 impl Metric {
     pub fn new(value: f64, noise: f64) -> Metric {
         Metric {value: value, noise: noise}
@@ -238,6 +247,8 @@ pub enum MetricChange {
     Regression(f64)
 }
 
+impl Copy for MetricChange {}
+
 pub type MetricDiff = TreeMap<String,MetricChange>;
 
 // The default console test runner. It accepts the command line
@@ -280,6 +291,8 @@ pub enum ColorConfig {
     NeverColor,
 }
 
+impl Copy for ColorConfig {}
+
 pub struct TestOpts {
     pub filter: Option<Regex>,
     pub run_ignored: bool,
@@ -1135,7 +1148,7 @@ pub fn run_test(opts: &TestOpts,
             return;
         }
         StaticBenchFn(benchfn) => {
-            let bs = ::bench::benchmark(|harness| benchfn(harness));
+            let bs = ::bench::benchmark(|harness| (benchfn.clone())(harness));
             monitor_ch.send((desc, TrBench(bs), Vec::new()));
             return;
         }
diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs
index 4453034fe06..e293c547944 100644
--- a/src/libtime/lib.rs
+++ b/src/libtime/lib.rs
@@ -77,7 +77,13 @@ mod imp {
 
 /// A record specifying a time value in seconds and nanoseconds.
 #[deriving(Clone, PartialEq, Eq, PartialOrd, Ord, Encodable, Decodable, Show)]
-pub struct Timespec { pub sec: i64, pub nsec: i32 }
+pub struct Timespec {
+    pub sec: i64,
+    pub nsec: i32,
+}
+
+impl Copy for Timespec {}
+
 /*
  * Timespec assumes that pre-epoch Timespecs have negative sec and positive
  * nsec fields. Darwin's and Linux's struct timespec functions handle pre-
@@ -269,6 +275,8 @@ pub struct Tm {
     pub tm_nsec: i32,
 }
 
+impl Copy for Tm {}
+
 pub fn empty_tm() -> Tm {
     Tm {
         tm_sec: 0_i32,
@@ -428,6 +436,8 @@ pub enum ParseError {
     UnexpectedCharacter(char, char),
 }
 
+impl Copy for ParseError {}
+
 impl Show for ParseError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
diff --git a/src/libunicode/tables.rs b/src/libunicode/tables.rs
index c91ce5c6464..54f7b3501b8 100644
--- a/src/libunicode/tables.rs
+++ b/src/libunicode/tables.rs
@@ -7138,6 +7138,7 @@ pub mod charwidth {
 pub mod grapheme {
     pub use self::GraphemeCat::*;
     use core::slice::SlicePrelude;
+    use core::kinds::Copy;
     use core::slice;
 
     #[allow(non_camel_case_types)]
@@ -7155,6 +7156,8 @@ pub mod grapheme {
         GC_Any,
     }
 
+    impl Copy for GraphemeCat {}
+
     fn bsearch_range_value_table(c: char, r: &'static [(char, char, GraphemeCat)]) -> GraphemeCat {
         use core::cmp::Ordering::{Equal, Less, Greater};
         match r.binary_search(|&(lo, hi, _)| {
diff --git a/src/test/auxiliary/issue-14422.rs b/src/test/auxiliary/issue-14422.rs
index 04e1d993011..9ecb1195de0 100644
--- a/src/test/auxiliary/issue-14422.rs
+++ b/src/test/auxiliary/issue-14422.rs
@@ -25,6 +25,8 @@ mod src {
 
         pub struct A;
 
+        impl Copy for A {}
+
         pub fn make() -> B { A }
 
         impl A {
diff --git a/src/test/auxiliary/issue13213aux.rs b/src/test/auxiliary/issue13213aux.rs
index 5bd52ef5010..cf8d0c167a1 100644
--- a/src/test/auxiliary/issue13213aux.rs
+++ b/src/test/auxiliary/issue13213aux.rs
@@ -22,6 +22,10 @@ mod private {
         p: i32,
     }
     pub const THREE: P = P { p: 3 };
+    impl Copy for P {}
 }
 
 pub static A: S = S { p: private::THREE };
+
+impl Copy for S {}
+
diff --git a/src/test/auxiliary/lang-item-public.rs b/src/test/auxiliary/lang-item-public.rs
index ea2461ccfa8..e6bae462887 100644
--- a/src/test/auxiliary/lang-item-public.rs
+++ b/src/test/auxiliary/lang-item-public.rs
@@ -22,3 +22,8 @@ extern fn stack_exhausted() {}
 
 #[lang = "eh_personality"]
 extern fn eh_personality() {}
+
+#[lang="copy"]
+pub trait Copy {}
+
+
diff --git a/src/test/auxiliary/method_self_arg1.rs b/src/test/auxiliary/method_self_arg1.rs
index d02222931e5..37022131c3d 100644
--- a/src/test/auxiliary/method_self_arg1.rs
+++ b/src/test/auxiliary/method_self_arg1.rs
@@ -16,6 +16,8 @@ pub fn get_count() -> u64 { unsafe { COUNT } }
 
 pub struct Foo;
 
+impl Copy for Foo {}
+
 impl Foo {
     pub fn foo(self, x: &Foo) {
         unsafe { COUNT *= 2; }
diff --git a/src/test/auxiliary/method_self_arg2.rs b/src/test/auxiliary/method_self_arg2.rs
index 99eb665388b..e1e79b59e3e 100644
--- a/src/test/auxiliary/method_self_arg2.rs
+++ b/src/test/auxiliary/method_self_arg2.rs
@@ -16,6 +16,8 @@ pub fn get_count() -> u64 { unsafe { COUNT } }
 
 pub struct Foo;
 
+impl Copy for Foo {}
+
 impl Foo {
     pub fn run_trait(self) {
         unsafe { COUNT *= 17; }
diff --git a/src/test/auxiliary/xcrate_unit_struct.rs b/src/test/auxiliary/xcrate_unit_struct.rs
index d56d7a70edf..5a918db1cfa 100644
--- a/src/test/auxiliary/xcrate_unit_struct.rs
+++ b/src/test/auxiliary/xcrate_unit_struct.rs
@@ -14,20 +14,31 @@
 
 pub struct Struct;
 
+impl Copy for Struct {}
+
 pub enum Unit {
     UnitVariant,
     Argument(Struct)
 }
 
+impl Copy for Unit {}
+
 pub struct TupleStruct(pub uint, pub &'static str);
 
+impl Copy for TupleStruct {}
+
 // used by the cfail test
 
 pub struct StructWithFields {
     foo: int,
 }
 
+impl Copy for StructWithFields {}
+
 pub enum EnumWithVariants {
     EnumVariant,
     EnumVariantArg(int)
 }
+
+impl Copy for EnumWithVariants {}
+
diff --git a/src/test/bench/noise.rs b/src/test/bench/noise.rs
index 419e39b53cf..025f8467d20 100644
--- a/src/test/bench/noise.rs
+++ b/src/test/bench/noise.rs
@@ -21,6 +21,8 @@ struct Vec2 {
     y: f32,
 }
 
+impl Copy for Vec2 {}
+
 fn lerp(a: f32, b: f32, v: f32) -> f32 { a * (1.0 - v) + b * v }
 
 fn smooth(v: f32) -> f32 { v * v * (3.0 - 2.0 * v) }
diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs
index 3059a014528..e954d0fed5e 100644
--- a/src/test/bench/shootout-chameneos-redux.rs
+++ b/src/test/bench/shootout-chameneos-redux.rs
@@ -53,7 +53,14 @@ fn print_complements() {
     }
 }
 
-enum Color { Red, Yellow, Blue }
+enum Color {
+    Red,
+    Yellow,
+    Blue,
+}
+
+impl Copy for Color {}
+
 impl fmt::Show for Color {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let str = match *self {
@@ -70,6 +77,8 @@ struct CreatureInfo {
     color: Color
 }
 
+impl Copy for CreatureInfo {}
+
 fn show_color_list(set: Vec<Color>) -> String {
     let mut out = String::new();
     for col in set.iter() {
diff --git a/src/test/bench/shootout-fannkuch-redux.rs b/src/test/bench/shootout-fannkuch-redux.rs
index b38b8e66d7d..4b890bbd8d3 100644
--- a/src/test/bench/shootout-fannkuch-redux.rs
+++ b/src/test/bench/shootout-fannkuch-redux.rs
@@ -67,6 +67,8 @@ struct P {
     p: [i32, .. 16],
 }
 
+impl Copy for P {}
+
 struct Perm {
     cnt: [i32, .. 16],
     fact: [u32, .. 16],
@@ -75,6 +77,8 @@ struct Perm {
     perm: P,
 }
 
+impl Copy for Perm {}
+
 impl Perm {
     fn new(n: u32) -> Perm {
         let mut fact = [1, .. 16];
diff --git a/src/test/bench/shootout-fasta-redux.rs b/src/test/bench/shootout-fasta-redux.rs
index 0b4a1d91968..afffbe5bed4 100644
--- a/src/test/bench/shootout-fasta-redux.rs
+++ b/src/test/bench/shootout-fasta-redux.rs
@@ -109,6 +109,8 @@ struct AminoAcid {
     p: f32,
 }
 
+impl Copy for AminoAcid {}
+
 struct RepeatFasta<'a, W:'a> {
     alu: &'static str,
     out: &'a mut W
diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs
index 8ed041513c4..847ae2c1c88 100644
--- a/src/test/bench/shootout-k-nucleotide.rs
+++ b/src/test/bench/shootout-k-nucleotide.rs
@@ -62,6 +62,8 @@ static OCCURRENCES: [&'static str, ..5] = [
 #[deriving(PartialEq, PartialOrd, Ord, Eq)]
 struct Code(u64);
 
+impl Copy for Code {}
+
 impl Code {
     fn hash(&self) -> u64 {
         let Code(ret) = *self;
diff --git a/src/test/bench/shootout-nbody.rs b/src/test/bench/shootout-nbody.rs
index b62504d7ba8..3f36c16aff6 100644
--- a/src/test/bench/shootout-nbody.rs
+++ b/src/test/bench/shootout-nbody.rs
@@ -100,6 +100,8 @@ struct Planet {
     mass: f64,
 }
 
+impl Copy for Planet {}
+
 fn advance(bodies: &mut [Planet, ..N_BODIES], dt: f64, steps: int) {
     for _ in range(0, steps) {
         let mut b_slice = bodies.as_mut_slice();
diff --git a/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs b/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs
index c071691c947..d5998c8ca99 100644
--- a/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs
+++ b/src/test/compile-fail/borrowck-borrow-from-owned-ptr.rs
@@ -14,11 +14,15 @@ struct Foo {
   bar2: Bar
 }
 
+impl Copy for Foo {}
+
 struct Bar {
   int1: int,
   int2: int,
 }
 
+impl Copy for Bar {}
+
 fn make_foo() -> Box<Foo> { panic!() }
 
 fn borrow_same_field_twice_mut_mut() {
diff --git a/src/test/compile-fail/borrowck-borrow-from-stack-variable.rs b/src/test/compile-fail/borrowck-borrow-from-stack-variable.rs
index 3a85b45ad12..d252d442297 100644
--- a/src/test/compile-fail/borrowck-borrow-from-stack-variable.rs
+++ b/src/test/compile-fail/borrowck-borrow-from-stack-variable.rs
@@ -13,11 +13,15 @@ struct Foo {
   bar2: Bar
 }
 
+impl Copy for Foo {}
+
 struct Bar {
   int1: int,
   int2: int,
 }
 
+impl Copy for Bar {}
+
 fn make_foo() -> Foo { panic!() }
 
 fn borrow_same_field_twice_mut_mut() {
diff --git a/src/test/compile-fail/borrowck-loan-local-as-both-mut-and-imm.rs b/src/test/compile-fail/borrowck-loan-local-as-both-mut-and-imm.rs
deleted file mode 100644
index 2063d7388a9..00000000000
--- a/src/test/compile-fail/borrowck-loan-local-as-both-mut-and-imm.rs
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2012 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.
-
-enum Either<T, U> { Left(T), Right(U) }
-
-    fn f(x: &mut Either<int,f64>, y: &Either<int,f64>) -> int {
-        match *y {
-            Either::Left(ref z) => {
-                *x = Either::Right(1.0);
-                *z
-            }
-            _ => panic!()
-        }
-    }
-
-    fn g() {
-        let mut x: Either<int,f64> = Either::Left(3);
-        println!("{}", f(&mut x, &x)); //~ ERROR cannot borrow
-    }
-
-    fn h() {
-        let mut x: Either<int,f64> = Either::Left(3);
-        let y: &Either<int, f64> = &x;
-        let z: &mut Either<int, f64> = &mut x; //~ ERROR cannot borrow
-        *z = *y;
-    }
-
-    fn main() {}
diff --git a/src/test/compile-fail/borrowck-use-mut-borrow.rs b/src/test/compile-fail/borrowck-use-mut-borrow.rs
index 7414bb930d4..0d27473cb2d 100644
--- a/src/test/compile-fail/borrowck-use-mut-borrow.rs
+++ b/src/test/compile-fail/borrowck-use-mut-borrow.rs
@@ -9,6 +9,9 @@
 // except according to those terms.
 
 struct A { a: int, b: int }
+
+impl Copy for A {}
+
 struct B { a: int, b: Box<int> }
 
 fn var_copy_after_var_borrow() {
diff --git a/src/test/compile-fail/dst-index.rs b/src/test/compile-fail/dst-index.rs
index f6511d68662..af97c864dc8 100644
--- a/src/test/compile-fail/dst-index.rs
+++ b/src/test/compile-fail/dst-index.rs
@@ -16,6 +16,8 @@ use std::fmt::Show;
 
 struct S;
 
+impl Copy for S {}
+
 impl Index<uint, str> for S {
     fn index<'a>(&'a self, _: &uint) -> &'a str {
         "hello"
@@ -24,6 +26,8 @@ impl Index<uint, str> for S {
 
 struct T;
 
+impl Copy for T {}
+
 impl Index<uint, Show + 'static> for T {
     fn index<'a>(&'a self, idx: &uint) -> &'a (Show + 'static) {
         static x: uint = 42;
@@ -33,7 +37,8 @@ impl Index<uint, Show + 'static> for T {
 
 fn main() {
     S[0];
-    //~^ ERROR E0161
+    //~^ ERROR cannot move out of dereference
+    //~^^ ERROR E0161
     T[0];
     //~^ ERROR cannot move out of dereference
     //~^^ ERROR E0161
diff --git a/src/test/compile-fail/dst-rvalue.rs b/src/test/compile-fail/dst-rvalue.rs
index 52b7ea9efa5..4c1dafd8c1a 100644
--- a/src/test/compile-fail/dst-rvalue.rs
+++ b/src/test/compile-fail/dst-rvalue.rs
@@ -13,8 +13,10 @@
 pub fn main() {
     let _x: Box<str> = box *"hello world";
     //~^ ERROR E0161
+    //~^^ ERROR cannot move out of dereference
 
     let array: &[int] = &[1, 2, 3];
     let _x: Box<[int]> = box *array;
     //~^ ERROR E0161
+    //~^^ ERROR cannot move out of dereference
 }
diff --git a/src/test/compile-fail/issue-17651.rs b/src/test/compile-fail/issue-17651.rs
index ef8174a26aa..ab396edddf4 100644
--- a/src/test/compile-fail/issue-17651.rs
+++ b/src/test/compile-fail/issue-17651.rs
@@ -13,5 +13,6 @@
 
 fn main() {
     (|| box *[0u].as_slice())();
-    //~^ ERROR cannot move a value of type [uint]
+    //~^ ERROR cannot move out of dereference
+    //~^^ ERROR cannot move a value of type [uint]
 }
diff --git a/src/test/compile-fail/kindck-copy.rs b/src/test/compile-fail/kindck-copy.rs
index f0c4a4243ac..8868c7f8256 100644
--- a/src/test/compile-fail/kindck-copy.rs
+++ b/src/test/compile-fail/kindck-copy.rs
@@ -14,6 +14,7 @@
 use std::rc::Rc;
 
 fn assert_copy<T:Copy>() { }
+
 trait Dummy { }
 
 struct MyStruct {
@@ -21,6 +22,8 @@ struct MyStruct {
     y: int,
 }
 
+impl Copy for MyStruct {}
+
 struct MyNoncopyStruct {
     x: Box<char>,
 }
diff --git a/src/test/compile-fail/lint-dead-code-1.rs b/src/test/compile-fail/lint-dead-code-1.rs
index 1a4a87e608b..9e5f15c2721 100644
--- a/src/test/compile-fail/lint-dead-code-1.rs
+++ b/src/test/compile-fail/lint-dead-code-1.rs
@@ -12,6 +12,7 @@
 #![allow(unused_variables)]
 #![allow(non_camel_case_types)]
 #![allow(non_upper_case_globals)]
+#![allow(missing_copy_implementations)]
 #![deny(dead_code)]
 
 #![crate_type="lib"]
diff --git a/src/test/compile-fail/lint-missing-doc.rs b/src/test/compile-fail/lint-missing-doc.rs
index 8d4ecde692d..b73c3fa2610 100644
--- a/src/test/compile-fail/lint-missing-doc.rs
+++ b/src/test/compile-fail/lint-missing-doc.rs
@@ -13,6 +13,7 @@
 #![feature(globs)]
 #![deny(missing_docs)]
 #![allow(dead_code)]
+#![allow(missing_copy_implementations)]
 
 //! Some garbage docs for the crate here
 #![doc="More garbage"]
diff --git a/src/test/compile-fail/opt-in-copy.rs b/src/test/compile-fail/opt-in-copy.rs
new file mode 100644
index 00000000000..56f71c844ac
--- /dev/null
+++ b/src/test/compile-fail/opt-in-copy.rs
@@ -0,0 +1,33 @@
+// Copyright 2014 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.
+
+struct CantCopyThis;
+
+struct IWantToCopyThis {
+    but_i_cant: CantCopyThis,
+}
+
+impl Copy for IWantToCopyThis {}
+//~^ ERROR the trait `Copy` may not be implemented for this type
+
+enum CantCopyThisEither {
+    A,
+    B,
+}
+
+enum IWantToCopyThisToo {
+    ButICant(CantCopyThisEither),
+}
+
+impl Copy for IWantToCopyThisToo {}
+//~^ ERROR the trait `Copy` may not be implemented for this type
+
+fn main() {}
+
diff --git a/src/test/compile-fail/stage0-clone-contravariant-lifetime.rs b/src/test/compile-fail/stage0-clone-contravariant-lifetime.rs
deleted file mode 100644
index 1d1b244ab5a..00000000000
--- a/src/test/compile-fail/stage0-clone-contravariant-lifetime.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2014 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.
-
-// A zero-dependency test that covers some basic traits, default
-// methods, etc.  When mucking about with basic type system stuff I
-// often encounter problems in the iterator trait, so it's useful to
-// have hanging around. -nmatsakis
-
-// error-pattern: requires `start` lang_item
-
-#![no_std]
-#![feature(lang_items)]
-
-#[lang = "sized"]
-pub trait Sized for Sized? {
-    // Empty.
-}
-
-pub mod std {
-    pub mod clone {
-        pub trait Clone {
-            fn clone(&self) -> Self;
-        }
-    }
-}
-
-pub struct ContravariantLifetime<'a>;
-
-impl <'a> ::std::clone::Clone for ContravariantLifetime<'a> {
-    #[inline]
-    fn clone(&self) -> ContravariantLifetime<'a> {
-        match *self { ContravariantLifetime => ContravariantLifetime, }
-    }
-}
-
-fn main() { }
diff --git a/src/test/compile-fail/stage0-cmp.rs b/src/test/compile-fail/stage0-cmp.rs
deleted file mode 100644
index f68eb6400fa..00000000000
--- a/src/test/compile-fail/stage0-cmp.rs
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2014 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.
-
-
-// A zero-dependency test that covers some basic traits, default
-// methods, etc.  When mucking about with basic type system stuff I
-// often encounter problems in the iterator trait, so it's useful to
-// have hanging around. -nmatsakis
-
-// error-pattern: requires `start` lang_item
-
-#![no_std]
-#![feature(lang_items)]
-
-#[lang = "sized"]
-pub trait Sized for Sized? {
-    // Empty.
-}
-
-#[unstable = "Definition may change slightly after trait reform"]
-pub trait PartialEq for Sized? {
-    /// This method tests for `self` and `other` values to be equal, and is used by `==`.
-    fn eq(&self, other: &Self) -> bool;
-}
-
-#[unstable = "Trait is unstable."]
-impl<'a, Sized? T: PartialEq> PartialEq for &'a T {
-    #[inline]
-    fn eq(&self, other: & &'a T) -> bool { PartialEq::eq(*self, *other) }
-}
-
-fn main() { }
diff --git a/src/test/debuginfo/c-style-enum.rs b/src/test/debuginfo/c-style-enum.rs
index fec1d1b2789..b0a0142f6dd 100644
--- a/src/test/debuginfo/c-style-enum.rs
+++ b/src/test/debuginfo/c-style-enum.rs
@@ -104,18 +104,21 @@ use self::AutoDiscriminant::{One, Two, Three};
 use self::ManualDiscriminant::{OneHundred, OneThousand, OneMillion};
 use self::SingleVariant::TheOnlyVariant;
 
+#[deriving(Copy)]
 enum AutoDiscriminant {
     One,
     Two,
     Three
 }
 
+#[deriving(Copy)]
 enum ManualDiscriminant {
     OneHundred = 100,
     OneThousand = 1000,
     OneMillion = 1000000
 }
 
+#[deriving(Copy)]
 enum SingleVariant {
     TheOnlyVariant
 }
diff --git a/src/test/debuginfo/generic-method-on-generic-struct.rs b/src/test/debuginfo/generic-method-on-generic-struct.rs
index 7ceac0e7cea..4c0c82efea3 100644
--- a/src/test/debuginfo/generic-method-on-generic-struct.rs
+++ b/src/test/debuginfo/generic-method-on-generic-struct.rs
@@ -147,3 +147,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl<T:Copy> Copy for Struct<T> {}
+
diff --git a/src/test/debuginfo/method-on-enum.rs b/src/test/debuginfo/method-on-enum.rs
index d86aa54f451..8cb8fae75cf 100644
--- a/src/test/debuginfo/method-on-enum.rs
+++ b/src/test/debuginfo/method-on-enum.rs
@@ -148,3 +148,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl Copy for Enum {}
+
diff --git a/src/test/debuginfo/method-on-generic-struct.rs b/src/test/debuginfo/method-on-generic-struct.rs
index 2455c7aa519..d4244ee27d4 100644
--- a/src/test/debuginfo/method-on-generic-struct.rs
+++ b/src/test/debuginfo/method-on-generic-struct.rs
@@ -147,3 +147,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl<T:Copy> Copy for Struct<T> {}
+
diff --git a/src/test/debuginfo/method-on-struct.rs b/src/test/debuginfo/method-on-struct.rs
index 5e47d32e376..ca00587ba44 100644
--- a/src/test/debuginfo/method-on-struct.rs
+++ b/src/test/debuginfo/method-on-struct.rs
@@ -146,3 +146,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl Copy for Struct {}
+
diff --git a/src/test/debuginfo/method-on-trait.rs b/src/test/debuginfo/method-on-trait.rs
index 4d5f53fc120..e70f86a5367 100644
--- a/src/test/debuginfo/method-on-trait.rs
+++ b/src/test/debuginfo/method-on-trait.rs
@@ -152,3 +152,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl Copy for Struct {}
+
diff --git a/src/test/debuginfo/method-on-tuple-struct.rs b/src/test/debuginfo/method-on-tuple-struct.rs
index fb3bede37fd..31bdd20e409 100644
--- a/src/test/debuginfo/method-on-tuple-struct.rs
+++ b/src/test/debuginfo/method-on-tuple-struct.rs
@@ -144,3 +144,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl Copy for TupleStruct {}
+
diff --git a/src/test/debuginfo/self-in-default-method.rs b/src/test/debuginfo/self-in-default-method.rs
index 287813a959f..87fdb2c42c8 100644
--- a/src/test/debuginfo/self-in-default-method.rs
+++ b/src/test/debuginfo/self-in-default-method.rs
@@ -148,3 +148,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl Copy for Struct {}
+
diff --git a/src/test/debuginfo/self-in-generic-default-method.rs b/src/test/debuginfo/self-in-generic-default-method.rs
index bfb8abc9f66..6f488230521 100644
--- a/src/test/debuginfo/self-in-generic-default-method.rs
+++ b/src/test/debuginfo/self-in-generic-default-method.rs
@@ -149,3 +149,6 @@ fn main() {
 }
 
 fn zzz() {()}
+
+impl Copy for Struct {}
+
diff --git a/src/test/pretty/block-disambig.rs b/src/test/pretty/block-disambig.rs
index 1b1765475f3..db01bc94e32 100644
--- a/src/test/pretty/block-disambig.rs
+++ b/src/test/pretty/block-disambig.rs
@@ -21,6 +21,8 @@ fn test2() -> int { let val = &0i; { } *val }
 
 struct S { eax: int }
 
+impl Copy for S {}
+
 fn test3() {
     let regs = &Cell::new(S {eax: 0});
     match true { true => { } _ => { } }
diff --git a/src/test/run-make/extern-fn-with-packed-struct/test.rs b/src/test/run-make/extern-fn-with-packed-struct/test.rs
index 8d8daed1393..12d961bd59e 100644
--- a/src/test/run-make/extern-fn-with-packed-struct/test.rs
+++ b/src/test/run-make/extern-fn-with-packed-struct/test.rs
@@ -16,6 +16,8 @@ struct Foo {
     c: i8
 }
 
+impl Copy for Foo {}
+
 #[link(name = "test", kind = "static")]
 extern {
     fn foo(f: Foo) -> Foo;
diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make/target-specs/foo.rs
index eeddd5e19a8..cab98204b17 100644
--- a/src/test/run-make/target-specs/foo.rs
+++ b/src/test/run-make/target-specs/foo.rs
@@ -11,6 +11,9 @@
 #![feature(lang_items)]
 #![no_std]
 
+#[lang="copy"]
+trait Copy { }
+
 #[lang="sized"]
 trait Sized { }
 
diff --git a/src/test/run-pass/borrowck-univariant-enum.rs b/src/test/run-pass/borrowck-univariant-enum.rs
index 3d191f6c4b4..df4106c9844 100644
--- a/src/test/run-pass/borrowck-univariant-enum.rs
+++ b/src/test/run-pass/borrowck-univariant-enum.rs
@@ -15,6 +15,8 @@ enum newtype {
     newvar(int)
 }
 
+impl Copy for newtype {}
+
 pub fn main() {
 
     // Test that borrowck treats enums with a single variant
diff --git a/src/test/run-pass/builtin-superkinds-in-metadata.rs b/src/test/run-pass/builtin-superkinds-in-metadata.rs
index 683e7ece871..382caa83c61 100644
--- a/src/test/run-pass/builtin-superkinds-in-metadata.rs
+++ b/src/test/run-pass/builtin-superkinds-in-metadata.rs
@@ -19,10 +19,12 @@ use trait_superkinds_in_metadata::{RequiresCopy};
 
 struct X<T>(T);
 
-impl <T:Sync> RequiresShare for X<T> { }
+impl<T:Copy> Copy for X<T> {}
 
-impl <T:Sync+Send> RequiresRequiresShareAndSend for X<T> { }
+impl<T:Sync> RequiresShare for X<T> { }
 
-impl <T:Copy> RequiresCopy for X<T> { }
+impl<T:Sync+Send> RequiresRequiresShareAndSend for X<T> { }
+
+impl<T:Copy> RequiresCopy for X<T> { }
 
 pub fn main() { }
diff --git a/src/test/run-pass/cell-does-not-clone.rs b/src/test/run-pass/cell-does-not-clone.rs
index c7c655b3db4..6455f1e4bb2 100644
--- a/src/test/run-pass/cell-does-not-clone.rs
+++ b/src/test/run-pass/cell-does-not-clone.rs
@@ -24,6 +24,8 @@ impl Clone for Foo {
     }
 }
 
+impl Copy for Foo {}
+
 pub fn main() {
     let x = Cell::new(Foo { x: 22 });
     let _y = x.get();
diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs
index a0d35fd596b..2a9756d7714 100644
--- a/src/test/run-pass/class-impl-very-parameterized-trait.rs
+++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs
@@ -14,6 +14,8 @@ use std::cmp;
 #[deriving(Show)]
 enum cat_type { tuxedo, tabby, tortoiseshell }
 
+impl Copy for cat_type {}
+
 impl cmp::PartialEq for cat_type {
     fn eq(&self, other: &cat_type) -> bool {
         ((*self) as uint) == ((*other) as uint)
diff --git a/src/test/run-pass/coherence-impl-in-fn.rs b/src/test/run-pass/coherence-impl-in-fn.rs
index 51cd62677ca..df0012e07ec 100644
--- a/src/test/run-pass/coherence-impl-in-fn.rs
+++ b/src/test/run-pass/coherence-impl-in-fn.rs
@@ -10,6 +10,7 @@
 
 pub fn main() {
     enum x { foo }
+    impl Copy for x {}
     impl ::std::cmp::PartialEq for x {
         fn eq(&self, other: &x) -> bool {
             (*self) as int == (*other) as int
diff --git a/src/test/run-pass/coherence-where-clause.rs b/src/test/run-pass/coherence-where-clause.rs
index faec0c50280..e0d9d569d17 100644
--- a/src/test/run-pass/coherence-where-clause.rs
+++ b/src/test/run-pass/coherence-where-clause.rs
@@ -28,6 +28,8 @@ struct MyType {
     dummy: uint
 }
 
+impl Copy for MyType {}
+
 impl MyTrait for MyType {
     fn get(&self) -> MyType { (*self).clone() }
 }
diff --git a/src/test/run-pass/const-nullary-univariant-enum.rs b/src/test/run-pass/const-nullary-univariant-enum.rs
index fe171a9f73d..9a1a5de9360 100644
--- a/src/test/run-pass/const-nullary-univariant-enum.rs
+++ b/src/test/run-pass/const-nullary-univariant-enum.rs
@@ -12,6 +12,8 @@ enum Foo {
     Bar = 0xDEADBEE
 }
 
+impl Copy for Foo {}
+
 static X: Foo = Foo::Bar;
 
 pub fn main() {
diff --git a/src/test/run-pass/dst-struct-sole.rs b/src/test/run-pass/dst-struct-sole.rs
index 04fe6d5cefd..26cb27cc653 100644
--- a/src/test/run-pass/dst-struct-sole.rs
+++ b/src/test/run-pass/dst-struct-sole.rs
@@ -33,6 +33,8 @@ fn foo2<T:ToBar>(x: &Fat<[T]>) {
 #[deriving(PartialEq,Eq)]
 struct Bar;
 
+impl Copy for Bar {}
+
 trait ToBar {
     fn to_bar(&self) -> Bar;
 }
diff --git a/src/test/run-pass/dst-struct.rs b/src/test/run-pass/dst-struct.rs
index 6b8e25e8559..bf5b300f7cf 100644
--- a/src/test/run-pass/dst-struct.rs
+++ b/src/test/run-pass/dst-struct.rs
@@ -49,6 +49,8 @@ fn foo3(x: &Fat<Fat<[int]>>) {
 #[deriving(PartialEq,Eq)]
 struct Bar;
 
+impl Copy for Bar {}
+
 trait ToBar {
     fn to_bar(&self) -> Bar;
 }
diff --git a/src/test/run-pass/dst-trait.rs b/src/test/run-pass/dst-trait.rs
index 97627309551..907c7810736 100644
--- a/src/test/run-pass/dst-trait.rs
+++ b/src/test/run-pass/dst-trait.rs
@@ -17,11 +17,15 @@ struct Fat<Sized? T> {
 #[deriving(PartialEq,Eq)]
 struct Bar;
 
+impl Copy for Bar {}
+
 #[deriving(PartialEq,Eq)]
 struct Bar1 {
     f: int
 }
 
+impl Copy for Bar1 {}
+
 trait ToBar {
     fn to_bar(&self) -> Bar;
     fn to_val(&self) -> int;
diff --git a/src/test/run-pass/empty-tag.rs b/src/test/run-pass/empty-tag.rs
index 6b780d85459..e5d11ac1adb 100644
--- a/src/test/run-pass/empty-tag.rs
+++ b/src/test/run-pass/empty-tag.rs
@@ -11,6 +11,8 @@
 #[deriving(Show)]
 enum chan { chan_t, }
 
+impl Copy for chan {}
+
 impl PartialEq for chan {
     fn eq(&self, other: &chan) -> bool {
         ((*self) as uint) == ((*other) as uint)
diff --git a/src/test/run-pass/enum-discrim-width-stuff.rs b/src/test/run-pass/enum-discrim-width-stuff.rs
index deb3f6b6c7c..cf8e742947d 100644
--- a/src/test/run-pass/enum-discrim-width-stuff.rs
+++ b/src/test/run-pass/enum-discrim-width-stuff.rs
@@ -20,6 +20,7 @@ macro_rules! check {
                 A = 0
             }
             static C: E = E::V;
+            impl Copy for E {}
             pub fn check() {
                 assert_eq!(size_of::<E>(), size_of::<$t>());
                 assert_eq!(E::V as $t, $v as $t);
diff --git a/src/test/run-pass/explicit-self-generic.rs b/src/test/run-pass/explicit-self-generic.rs
index 829870930a4..eeda299c71f 100644
--- a/src/test/run-pass/explicit-self-generic.rs
+++ b/src/test/run-pass/explicit-self-generic.rs
@@ -18,10 +18,14 @@ type EqFn<K> = proc(K, K):'static -> bool;
 
 struct LM { resize_at: uint, size: uint }
 
+impl Copy for LM {}
+
 enum HashMap<K,V> {
     HashMap_(LM)
 }
 
+impl<K,V> Copy for HashMap<K,V> {}
+
 fn linear_map<K,V>() -> HashMap<K,V> {
     HashMap::HashMap_(LM{
         resize_at: 32,
diff --git a/src/test/run-pass/export-unexported-dep.rs b/src/test/run-pass/export-unexported-dep.rs
index 3fc5310a29b..48e9d9dea22 100644
--- a/src/test/run-pass/export-unexported-dep.rs
+++ b/src/test/run-pass/export-unexported-dep.rs
@@ -15,6 +15,8 @@ mod foo {
     // not exported
     enum t { t1, t2, }
 
+    impl Copy for t {}
+
     impl PartialEq for t {
         fn eq(&self, other: &t) -> bool {
             ((*self) as uint) == ((*other) as uint)
diff --git a/src/test/run-pass/expr-copy.rs b/src/test/run-pass/expr-copy.rs
index 4a45ce66058..6e9ba4f8f41 100644
--- a/src/test/run-pass/expr-copy.rs
+++ b/src/test/run-pass/expr-copy.rs
@@ -15,6 +15,8 @@ fn f(arg: &mut A) {
 
 struct A { a: int }
 
+impl Copy for A {}
+
 pub fn main() {
     let mut x = A {a: 10};
     f(&mut x);
diff --git a/src/test/run-pass/expr-if-struct.rs b/src/test/run-pass/expr-if-struct.rs
index 758d726851d..c95ca3fff8c 100644
--- a/src/test/run-pass/expr-if-struct.rs
+++ b/src/test/run-pass/expr-if-struct.rs
@@ -16,6 +16,8 @@
 
 struct I { i: int }
 
+impl Copy for I {}
+
 fn test_rec() {
     let rs = if true { I {i: 100} } else { I {i: 101} };
     assert_eq!(rs.i, 100);
@@ -24,6 +26,8 @@ fn test_rec() {
 #[deriving(Show)]
 enum mood { happy, sad, }
 
+impl Copy for mood {}
+
 impl PartialEq for mood {
     fn eq(&self, other: &mood) -> bool {
         ((*self) as uint) == ((*other) as uint)
diff --git a/src/test/run-pass/expr-match-struct.rs b/src/test/run-pass/expr-match-struct.rs
index ea96005dc60..83101a3d2cc 100644
--- a/src/test/run-pass/expr-match-struct.rs
+++ b/src/test/run-pass/expr-match-struct.rs
@@ -15,6 +15,8 @@
 // Tests for match as expressions resulting in struct types
 struct R { i: int }
 
+impl Copy for R {}
+
 fn test_rec() {
     let rs = match true { true => R {i: 100}, _ => panic!() };
     assert_eq!(rs.i, 100);
@@ -23,6 +25,8 @@ fn test_rec() {
 #[deriving(Show)]
 enum mood { happy, sad, }
 
+impl Copy for mood {}
+
 impl PartialEq for mood {
     fn eq(&self, other: &mood) -> bool {
         ((*self) as uint) == ((*other) as uint)
diff --git a/src/test/run-pass/exterior.rs b/src/test/run-pass/exterior.rs
index e95c2034131..2ca5f430a2a 100644
--- a/src/test/run-pass/exterior.rs
+++ b/src/test/run-pass/exterior.rs
@@ -13,6 +13,8 @@ use std::cell::Cell;
 
 struct Point {x: int, y: int, z: int}
 
+impl Copy for Point {}
+
 fn f(p: &Cell<Point>) {
     assert!((p.get().z == 12));
     p.set(Point {x: 10, y: 11, z: 13});
diff --git a/src/test/run-pass/extern-pass-TwoU16s.rs b/src/test/run-pass/extern-pass-TwoU16s.rs
index 6161d31c4a9..2b80a404036 100644
--- a/src/test/run-pass/extern-pass-TwoU16s.rs
+++ b/src/test/run-pass/extern-pass-TwoU16s.rs
@@ -16,6 +16,8 @@ pub struct TwoU16s {
     one: u16, two: u16
 }
 
+impl Copy for TwoU16s {}
+
 #[link(name = "rust_test_helpers")]
 extern {
     pub fn rust_dbg_extern_identity_TwoU16s(v: TwoU16s) -> TwoU16s;
diff --git a/src/test/run-pass/extern-pass-TwoU32s.rs b/src/test/run-pass/extern-pass-TwoU32s.rs
index 3e6b6502074..be4998c86fd 100644
--- a/src/test/run-pass/extern-pass-TwoU32s.rs
+++ b/src/test/run-pass/extern-pass-TwoU32s.rs
@@ -16,6 +16,8 @@ pub struct TwoU32s {
     one: u32, two: u32
 }
 
+impl Copy for TwoU32s {}
+
 #[link(name = "rust_test_helpers")]
 extern {
     pub fn rust_dbg_extern_identity_TwoU32s(v: TwoU32s) -> TwoU32s;
diff --git a/src/test/run-pass/extern-pass-TwoU64s.rs b/src/test/run-pass/extern-pass-TwoU64s.rs
index 5ad1e89425b..e8d91815bf9 100644
--- a/src/test/run-pass/extern-pass-TwoU64s.rs
+++ b/src/test/run-pass/extern-pass-TwoU64s.rs
@@ -16,6 +16,8 @@ pub struct TwoU64s {
     one: u64, two: u64
 }
 
+impl Copy for TwoU64s {}
+
 #[link(name = "rust_test_helpers")]
 extern {
     pub fn rust_dbg_extern_identity_TwoU64s(v: TwoU64s) -> TwoU64s;
diff --git a/src/test/run-pass/extern-pass-TwoU8s.rs b/src/test/run-pass/extern-pass-TwoU8s.rs
index 14ba7c80059..7aa710df800 100644
--- a/src/test/run-pass/extern-pass-TwoU8s.rs
+++ b/src/test/run-pass/extern-pass-TwoU8s.rs
@@ -16,6 +16,8 @@ pub struct TwoU8s {
     one: u8, two: u8
 }
 
+impl Copy for TwoU8s {}
+
 #[link(name = "rust_test_helpers")]
 extern {
     pub fn rust_dbg_extern_identity_TwoU8s(v: TwoU8s) -> TwoU8s;
diff --git a/src/test/run-pass/foreign-fn-with-byval.rs b/src/test/run-pass/foreign-fn-with-byval.rs
index 6a26ec44312..5d6815fc3c7 100644
--- a/src/test/run-pass/foreign-fn-with-byval.rs
+++ b/src/test/run-pass/foreign-fn-with-byval.rs
@@ -14,6 +14,8 @@ pub struct S {
     z: u64,
 }
 
+impl Copy for S {}
+
 #[link(name = "rust_test_helpers")]
 extern {
     pub fn get_x(x: S) -> u64;
diff --git a/src/test/run-pass/generic-fn.rs b/src/test/run-pass/generic-fn.rs
index 89f342b4ee5..a341bfe22eb 100644
--- a/src/test/run-pass/generic-fn.rs
+++ b/src/test/run-pass/generic-fn.rs
@@ -14,6 +14,8 @@ fn id<T>(x: T) -> T { return x; }
 
 struct Triple {x: int, y: int, z: int}
 
+impl Copy for Triple {}
+
 pub fn main() {
     let mut x = 62;
     let mut y = 63;
diff --git a/src/test/run-pass/guards-not-exhaustive.rs b/src/test/run-pass/guards-not-exhaustive.rs
index c7f3c9d7182..b1bc40b662d 100644
--- a/src/test/run-pass/guards-not-exhaustive.rs
+++ b/src/test/run-pass/guards-not-exhaustive.rs
@@ -10,6 +10,8 @@
 
 enum Q { R(Option<uint>) }
 
+impl Copy for Q {}
+
 fn xyzzy(q: Q) -> uint {
     match q {
         Q::R(S) if S.is_some() => { 0 }
diff --git a/src/test/run-pass/guards.rs b/src/test/run-pass/guards.rs
index 5bfbe4bf5a0..0157423863c 100644
--- a/src/test/run-pass/guards.rs
+++ b/src/test/run-pass/guards.rs
@@ -10,6 +10,8 @@
 
 struct Pair { x: int, y: int }
 
+impl Copy for Pair {}
+
 pub fn main() {
     let a: int =
         match 10i { x if x < 7 => { 1i } x if x < 11 => { 2i } 10 => { 3i } _ => { 4i } };
diff --git a/src/test/run-pass/issue-12860.rs b/src/test/run-pass/issue-12860.rs
index 4496a921e24..1caa04ae0b1 100644
--- a/src/test/run-pass/issue-12860.rs
+++ b/src/test/run-pass/issue-12860.rs
@@ -20,6 +20,8 @@ struct XYZ {
     z: int
 }
 
+impl Copy for XYZ {}
+
 fn main() {
     let mut connected = HashSet::new();
     let mut border = HashSet::new();
diff --git a/src/test/run-pass/issue-19100.rs b/src/test/run-pass/issue-19100.rs
index cee5c808f99..0ebd3ae8d97 100644
--- a/src/test/run-pass/issue-19100.rs
+++ b/src/test/run-pass/issue-19100.rs
@@ -13,6 +13,8 @@ enum Foo {
     Baz
 }
 
+impl Copy for Foo {}
+
 impl Foo {
     fn foo(&self) {
         match self {
diff --git a/src/test/run-pass/issue-2288.rs b/src/test/run-pass/issue-2288.rs
index 85dd879c830..1f371f0a1c2 100644
--- a/src/test/run-pass/issue-2288.rs
+++ b/src/test/run-pass/issue-2288.rs
@@ -12,10 +12,13 @@
 trait clam<A> {
   fn chowder(&self, y: A);
 }
+
 struct foo<A> {
   x: A,
 }
 
+impl<A:Copy> Copy for foo<A> {}
+
 impl<A> clam<A> for foo<A> {
   fn chowder(&self, _y: A) {
   }
diff --git a/src/test/run-pass/issue-2633.rs b/src/test/run-pass/issue-2633.rs
index a9ebfbcbf33..bc014f699c7 100644
--- a/src/test/run-pass/issue-2633.rs
+++ b/src/test/run-pass/issue-2633.rs
@@ -12,6 +12,8 @@ struct cat {
     meow: extern "Rust" fn(),
 }
 
+impl Copy for cat {}
+
 fn meow() {
     println!("meow")
 }
@@ -24,6 +26,8 @@ fn cat() -> cat {
 
 struct KittyInfo {kitty: cat}
 
+impl Copy for KittyInfo {}
+
 // Code compiles and runs successfully if we add a + before the first arg
 fn nyan(kitty: cat, _kitty_info: KittyInfo) {
     (kitty.meow)();
diff --git a/src/test/run-pass/issue-3121.rs b/src/test/run-pass/issue-3121.rs
index d0e995da5f1..9e9d611f1a3 100644
--- a/src/test/run-pass/issue-3121.rs
+++ b/src/test/run-pass/issue-3121.rs
@@ -13,6 +13,10 @@ enum side { mayo, catsup, vinegar }
 enum order { hamburger, fries(side), shake }
 enum meal { to_go(order), for_here(order) }
 
+impl Copy for side {}
+impl Copy for order {}
+impl Copy for meal {}
+
 fn foo(m: Box<meal>, cond: bool) {
     match *m {
       meal::to_go(_) => { }
diff --git a/src/test/run-pass/issue-3563-3.rs b/src/test/run-pass/issue-3563-3.rs
index 4e330b9a0e7..d04d8f92ac4 100644
--- a/src/test/run-pass/issue-3563-3.rs
+++ b/src/test/run-pass/issue-3563-3.rs
@@ -29,6 +29,8 @@ struct Point {
     y: int,
 }
 
+impl Copy for Point {}
+
 // Represents an offset on a canvas. (This has the same structure as a Point.
 // but different semantics).
 struct Size {
@@ -36,11 +38,15 @@ struct Size {
     height: int,
 }
 
+impl Copy for Size {}
+
 struct Rect {
     top_left: Point,
     size: Size,
 }
 
+impl Copy for Rect {}
+
 // Contains the information needed to do shape rendering via ASCII art.
 struct AsciiArt {
     width: uint,
diff --git a/src/test/run-pass/issue-3743.rs b/src/test/run-pass/issue-3743.rs
index bebaad2d297..ada3e37c092 100644
--- a/src/test/run-pass/issue-3743.rs
+++ b/src/test/run-pass/issue-3743.rs
@@ -13,6 +13,8 @@ struct Vec2 {
     y: f64
 }
 
+impl Copy for Vec2 {}
+
 // methods we want to export as methods as well as operators
 impl Vec2 {
 #[inline(always)]
diff --git a/src/test/run-pass/issue-3753.rs b/src/test/run-pass/issue-3753.rs
index 9fbabed3a94..de6926e5512 100644
--- a/src/test/run-pass/issue-3753.rs
+++ b/src/test/run-pass/issue-3753.rs
@@ -19,11 +19,15 @@ pub struct Point {
     y: f64
 }
 
+impl Copy for Point {}
+
 pub enum Shape {
     Circle(Point, f64),
     Rectangle(Point, Point)
 }
 
+impl Copy for Shape {}
+
 impl Shape {
     pub fn area(&self, sh: Shape) -> f64 {
         match sh {
diff --git a/src/test/run-pass/issue-5688.rs b/src/test/run-pass/issue-5688.rs
index 73bf375923a..0a13e001fab 100644
--- a/src/test/run-pass/issue-5688.rs
+++ b/src/test/run-pass/issue-5688.rs
@@ -18,7 +18,11 @@ failed to typecheck correctly.
 */
 
 struct X { vec: &'static [int] }
+
+impl Copy for X {}
+
 static V: &'static [X] = &[X { vec: &[1, 2, 3] }];
+
 pub fn main() {
     for &v in V.iter() {
         println!("{}", v.vec);
diff --git a/src/test/run-pass/lang-item-public.rs b/src/test/run-pass/lang-item-public.rs
index 982d4f6a0b5..81774c73c39 100644
--- a/src/test/run-pass/lang-item-public.rs
+++ b/src/test/run-pass/lang-item-public.rs
@@ -13,6 +13,7 @@
 // ignore-windows #13361
 
 #![no_std]
+#![feature(lang_items)]
 
 extern crate "lang-item-public" as lang_lib;
 
diff --git a/src/test/run-pass/match-arm-statics.rs b/src/test/run-pass/match-arm-statics.rs
index 85fa61266a3..400aab64b4c 100644
--- a/src/test/run-pass/match-arm-statics.rs
+++ b/src/test/run-pass/match-arm-statics.rs
@@ -38,6 +38,8 @@ const VARIANT2_NORTH: EnumWithStructVariants = EnumWithStructVariants::Variant2
 pub mod glfw {
     pub struct InputState(uint);
 
+    impl Copy for InputState {}
+
     pub const RELEASE  : InputState = InputState(0);
     pub const PRESS    : InputState = InputState(1);
     pub const REPEAT   : InputState = InputState(2);
diff --git a/src/test/run-pass/method-self-arg-trait.rs b/src/test/run-pass/method-self-arg-trait.rs
index b821c064cac..36dfe83a9eb 100644
--- a/src/test/run-pass/method-self-arg-trait.rs
+++ b/src/test/run-pass/method-self-arg-trait.rs
@@ -14,6 +14,8 @@ static mut COUNT: u64 = 1;
 
 struct Foo;
 
+impl Copy for Foo {}
+
 trait Bar {
     fn foo1(&self);
     fn foo2(self);
diff --git a/src/test/run-pass/method-self-arg.rs b/src/test/run-pass/method-self-arg.rs
index 3d73f34f8cf..788a25efcf9 100644
--- a/src/test/run-pass/method-self-arg.rs
+++ b/src/test/run-pass/method-self-arg.rs
@@ -14,6 +14,8 @@ static mut COUNT: uint = 1;
 
 struct Foo;
 
+impl Copy for Foo {}
+
 impl Foo {
     fn foo(self, x: &Foo) {
         unsafe { COUNT *= 2; }
diff --git a/src/test/run-pass/monomorphize-abi-alignment.rs b/src/test/run-pass/monomorphize-abi-alignment.rs
index 2233a5c3ea7..f5b51cd4233 100644
--- a/src/test/run-pass/monomorphize-abi-alignment.rs
+++ b/src/test/run-pass/monomorphize-abi-alignment.rs
@@ -19,12 +19,25 @@
  */
 
 struct S<T> { i:u8, t:T }
-impl<T> S<T> { fn unwrap(self) -> T { self.t } }
+
+impl<T:Copy> Copy for S<T> {}
+
+impl<T> S<T> {
+    fn unwrap(self) -> T {
+        self.t
+    }
+}
+
 #[deriving(PartialEq, Show)]
 struct A((u32, u32));
+
+impl Copy for A {}
+
 #[deriving(PartialEq, Show)]
 struct B(u64);
 
+impl Copy for B {}
+
 pub fn main() {
     static Ca: S<A> = S { i: 0, t: A((13, 104)) };
     static Cb: S<B> = S { i: 0, t: B(31337) };
diff --git a/src/test/run-pass/multidispatch1.rs b/src/test/run-pass/multidispatch1.rs
index 76c87f5d4c5..87d188418bd 100644
--- a/src/test/run-pass/multidispatch1.rs
+++ b/src/test/run-pass/multidispatch1.rs
@@ -18,6 +18,8 @@ struct MyType {
     dummy: uint
 }
 
+impl Copy for MyType {}
+
 impl MyTrait<uint> for MyType {
     fn get(&self) -> uint { self.dummy }
 }
diff --git a/src/test/run-pass/multidispatch2.rs b/src/test/run-pass/multidispatch2.rs
index 13131be93c8..1aa15cc5983 100644
--- a/src/test/run-pass/multidispatch2.rs
+++ b/src/test/run-pass/multidispatch2.rs
@@ -27,6 +27,8 @@ struct MyType {
     dummy: uint
 }
 
+impl Copy for MyType {}
+
 impl MyTrait<uint> for MyType {
     fn get(&self) -> uint { self.dummy }
 }
diff --git a/src/test/run-pass/newtype.rs b/src/test/run-pass/newtype.rs
index 0d1103086ae..093fd6c81cc 100644
--- a/src/test/run-pass/newtype.rs
+++ b/src/test/run-pass/newtype.rs
@@ -10,7 +10,14 @@
 
 struct mytype(Mytype);
 
-struct Mytype {compute: fn(mytype) -> int, val: int}
+impl Copy for mytype {}
+
+struct Mytype {
+    compute: fn(mytype) -> int,
+    val: int,
+}
+
+impl Copy for Mytype {}
 
 fn compute(i: mytype) -> int {
     let mytype(m) = i;
diff --git a/src/test/run-pass/out-pointer-aliasing.rs b/src/test/run-pass/out-pointer-aliasing.rs
index 2a44df7a1b5..5f399deb885 100644
--- a/src/test/run-pass/out-pointer-aliasing.rs
+++ b/src/test/run-pass/out-pointer-aliasing.rs
@@ -13,6 +13,8 @@ pub struct Foo {
     _f2: int,
 }
 
+impl Copy for Foo {}
+
 #[inline(never)]
 pub fn foo(f: &mut Foo) -> Foo {
     let ret = *f;
diff --git a/src/test/run-pass/overloaded-autoderef-order.rs b/src/test/run-pass/overloaded-autoderef-order.rs
index 0a9ac734c26..f0daf371ca7 100644
--- a/src/test/run-pass/overloaded-autoderef-order.rs
+++ b/src/test/run-pass/overloaded-autoderef-order.rs
@@ -15,6 +15,8 @@ struct DerefWrapper<X, Y> {
     y: Y
 }
 
+impl<X:Copy,Y:Copy> Copy for DerefWrapper<X,Y> {}
+
 impl<X, Y> DerefWrapper<X, Y> {
     fn get_x(self) -> X {
         self.x
@@ -33,6 +35,8 @@ mod priv_test {
         pub y: Y
     }
 
+    impl<X:Copy,Y:Copy> Copy for DerefWrapperHideX<X,Y> {}
+
     impl<X, Y> DerefWrapperHideX<X, Y> {
         pub fn new(x: X, y: Y) -> DerefWrapperHideX<X, Y> {
             DerefWrapperHideX {
diff --git a/src/test/run-pass/packed-struct-vec.rs b/src/test/run-pass/packed-struct-vec.rs
index c20e62351a6..59bb5678b69 100644
--- a/src/test/run-pass/packed-struct-vec.rs
+++ b/src/test/run-pass/packed-struct-vec.rs
@@ -19,6 +19,8 @@ struct Foo {
     baz: u64
 }
 
+impl Copy for Foo {}
+
 pub fn main() {
     let foos = [Foo { bar: 1, baz: 2 }, .. 10];
 
diff --git a/src/test/run-pass/rec-tup.rs b/src/test/run-pass/rec-tup.rs
index 0dc547f1a02..8adad012ec6 100644
--- a/src/test/run-pass/rec-tup.rs
+++ b/src/test/run-pass/rec-tup.rs
@@ -10,6 +10,8 @@
 
 struct Point {x: int, y: int}
 
+impl Copy for Point {}
+
 type rect = (Point, Point);
 
 fn fst(r: rect) -> Point { let (fst, _) = r; return fst; }
diff --git a/src/test/run-pass/rec.rs b/src/test/run-pass/rec.rs
index b9b5cfebb0b..02fcf1ad068 100644
--- a/src/test/run-pass/rec.rs
+++ b/src/test/run-pass/rec.rs
@@ -13,6 +13,8 @@
 
 struct Rect {x: int, y: int, w: int, h: int}
 
+impl Copy for Rect {}
+
 fn f(r: Rect, x: int, y: int, w: int, h: int) {
     assert_eq!(r.x, x);
     assert_eq!(r.y, y);
diff --git a/src/test/run-pass/regions-dependent-addr-of.rs b/src/test/run-pass/regions-dependent-addr-of.rs
index f074ca9a889..79f8ca48882 100644
--- a/src/test/run-pass/regions-dependent-addr-of.rs
+++ b/src/test/run-pass/regions-dependent-addr-of.rs
@@ -29,6 +29,8 @@ struct C {
     f: int
 }
 
+impl Copy for C {}
+
 fn get_v1(a: &A) -> &int {
     // Region inferencer must deduce that &v < L2 < L1
     let foo = &a.value; // L1
diff --git a/src/test/run-pass/regions-early-bound-used-in-bound-method.rs b/src/test/run-pass/regions-early-bound-used-in-bound-method.rs
index c011d11749b..5b4169a4e84 100644
--- a/src/test/run-pass/regions-early-bound-used-in-bound-method.rs
+++ b/src/test/run-pass/regions-early-bound-used-in-bound-method.rs
@@ -19,6 +19,8 @@ struct Box<'a> {
     t: &'a int
 }
 
+impl<'a> Copy for Box<'a> {}
+
 impl<'a> GetRef<'a> for Box<'a> {
     fn get(&self) -> &'a int {
         self.t
diff --git a/src/test/run-pass/regions-early-bound-used-in-bound.rs b/src/test/run-pass/regions-early-bound-used-in-bound.rs
index 58de2e0e20e..73eb7ca7188 100644
--- a/src/test/run-pass/regions-early-bound-used-in-bound.rs
+++ b/src/test/run-pass/regions-early-bound-used-in-bound.rs
@@ -19,6 +19,8 @@ struct Box<'a, T:'a> {
     t: &'a T
 }
 
+impl<'a,T:'a> Copy for Box<'a,T> {}
+
 impl<'a,T:Clone> GetRef<'a,T> for Box<'a,T> {
     fn get(&self) -> &'a T {
         self.t
diff --git a/src/test/run-pass/regions-early-bound-used-in-type-param.rs b/src/test/run-pass/regions-early-bound-used-in-type-param.rs
index 708664f33e9..622f820971f 100644
--- a/src/test/run-pass/regions-early-bound-used-in-type-param.rs
+++ b/src/test/run-pass/regions-early-bound-used-in-type-param.rs
@@ -19,6 +19,8 @@ struct Box<T> {
     t: T
 }
 
+impl<T:Copy> Copy for Box<T> {}
+
 impl<T:Clone> Get<T> for Box<T> {
     fn get(&self) -> T {
         self.t.clone()
diff --git a/src/test/run-pass/regions-mock-tcx.rs b/src/test/run-pass/regions-mock-tcx.rs
index e13edae330a..e10c12a6037 100644
--- a/src/test/run-pass/regions-mock-tcx.rs
+++ b/src/test/run-pass/regions-mock-tcx.rs
@@ -32,6 +32,9 @@ enum TypeStructure<'tcx> {
     TypeInt,
     TypeFunction(Type<'tcx>, Type<'tcx>),
 }
+
+impl<'tcx> Copy for TypeStructure<'tcx> {}
+
 impl<'tcx> PartialEq for TypeStructure<'tcx> {
     fn eq(&self, other: &TypeStructure<'tcx>) -> bool {
         match (*self, *other) {
@@ -93,6 +96,8 @@ struct NodeId {
     id: uint
 }
 
+impl Copy for NodeId {}
+
 type Ast<'ast> = &'ast AstStructure<'ast>;
 
 struct AstStructure<'ast> {
@@ -100,12 +105,16 @@ struct AstStructure<'ast> {
     kind: AstKind<'ast>
 }
 
+impl<'ast> Copy for AstStructure<'ast> {}
+
 enum AstKind<'ast> {
     ExprInt,
     ExprVar(uint),
     ExprLambda(Ast<'ast>),
 }
 
+impl<'ast> Copy for AstKind<'ast> {}
+
 fn compute_types<'tcx,'ast>(tcx: &mut TypeContext<'tcx,'ast>,
                             ast: Ast<'ast>) -> Type<'tcx>
 {
diff --git a/src/test/run-pass/self-in-mut-slot-immediate-value.rs b/src/test/run-pass/self-in-mut-slot-immediate-value.rs
index f2482474073..1603f7f9763 100644
--- a/src/test/run-pass/self-in-mut-slot-immediate-value.rs
+++ b/src/test/run-pass/self-in-mut-slot-immediate-value.rs
@@ -15,6 +15,8 @@ struct Value {
     n: int
 }
 
+impl Copy for Value {}
+
 impl Value {
     fn squared(mut self) -> Value {
         self.n *= self.n;
diff --git a/src/test/run-pass/shape_intrinsic_tag_then_rec.rs b/src/test/run-pass/shape_intrinsic_tag_then_rec.rs
deleted file mode 100644
index 930364c0e22..00000000000
--- a/src/test/run-pass/shape_intrinsic_tag_then_rec.rs
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2012 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.
-
-
-// Exercises a bug in the shape code that was exposed
-// on x86_64: when there is an enum embedded in an
-// interior record which is then itself interior to
-// something else, shape calculations were off.
-
-#[deriving(Clone, Show)]
-enum opt_span {
-    //hack (as opposed to option), to make `span` compile
-    os_none,
-    os_some(Box<Span>),
-}
-
-#[deriving(Clone, Show)]
-struct Span {
-    lo: uint,
-    hi: uint,
-    expanded_from: opt_span,
-}
-
-#[deriving(Clone, Show)]
-struct Spanned<T> {
-    data: T,
-    span: Span,
-}
-
-type ty_ = uint;
-
-#[deriving(Clone, Show)]
-struct Path_ {
-    global: bool,
-    idents: Vec<String> ,
-    types: Vec<Box<ty>>,
-}
-
-type path = Spanned<Path_>;
-type ty = Spanned<ty_>;
-
-#[deriving(Clone, Show)]
-struct X {
-    sp: Span,
-    path: path,
-}
-
-pub fn main() {
-    let sp: Span = Span {lo: 57451u, hi: 57542u, expanded_from: opt_span::os_none};
-    let t: Box<ty> = box Spanned { data: 3u, span: sp.clone() };
-    let p_: Path_ = Path_ {
-        global: true,
-        idents: vec!("hi".to_string()),
-        types: vec!(t),
-    };
-    let p: path = Spanned { data: p_, span: sp.clone() };
-    let x = X { sp: sp, path: p };
-    println!("{}", x.path.clone());
-    println!("{}", x.clone());
-}
diff --git a/src/test/run-pass/simd-generics.rs b/src/test/run-pass/simd-generics.rs
index 68c210b018a..31c29b615fc 100644
--- a/src/test/run-pass/simd-generics.rs
+++ b/src/test/run-pass/simd-generics.rs
@@ -15,6 +15,8 @@ use std::ops;
 
 #[simd] struct f32x4(f32, f32, f32, f32);
 
+impl Copy for f32x4 {}
+
 fn add<T: ops::Add<T, T>>(lhs: T, rhs: T) -> T {
     lhs + rhs
 }
diff --git a/src/test/run-pass/small-enum-range-edge.rs b/src/test/run-pass/small-enum-range-edge.rs
index 17d647e58b5..de38a553e12 100644
--- a/src/test/run-pass/small-enum-range-edge.rs
+++ b/src/test/run-pass/small-enum-range-edge.rs
@@ -14,11 +14,17 @@
 
 #[repr(u8)]
 enum Eu { Lu = 0, Hu = 255 }
+
+impl Copy for Eu {}
+
 static CLu: Eu = Eu::Lu;
 static CHu: Eu = Eu::Hu;
 
 #[repr(i8)]
 enum Es { Ls = -128, Hs = 127 }
+
+impl Copy for Es {}
+
 static CLs: Es = Es::Ls;
 static CHs: Es = Es::Hs;
 
diff --git a/src/test/run-pass/struct-return.rs b/src/test/run-pass/struct-return.rs
index 63574316fe5..bb06aec23f6 100644
--- a/src/test/run-pass/struct-return.rs
+++ b/src/test/run-pass/struct-return.rs
@@ -11,8 +11,13 @@
 // ignore-lexer-test FIXME #15883
 
 pub struct Quad { a: u64, b: u64, c: u64, d: u64 }
+
+impl Copy for Quad {}
+
 pub struct Floats { a: f64, b: u8, c: f64 }
 
+impl Copy for Floats {}
+
 mod rustrt {
     use super::{Floats, Quad};
 
diff --git a/src/test/run-pass/structured-compare.rs b/src/test/run-pass/structured-compare.rs
index 88f72932ca0..d0446d83d2e 100644
--- a/src/test/run-pass/structured-compare.rs
+++ b/src/test/run-pass/structured-compare.rs
@@ -13,6 +13,8 @@
 #[deriving(Show)]
 enum foo { large, small, }
 
+impl Copy for foo {}
+
 impl PartialEq for foo {
     fn eq(&self, other: &foo) -> bool {
         ((*self) as uint) == ((*other) as uint)
diff --git a/src/test/run-pass/tag-variant-disr-val.rs b/src/test/run-pass/tag-variant-disr-val.rs
index 7aa2ba280ac..cf53c1a912a 100644
--- a/src/test/run-pass/tag-variant-disr-val.rs
+++ b/src/test/run-pass/tag-variant-disr-val.rs
@@ -20,6 +20,8 @@ enum color {
     orange = 8 >> 1
 }
 
+impl Copy for color {}
+
 impl PartialEq for color {
     fn eq(&self, other: &color) -> bool {
         ((*self) as uint) == ((*other) as uint)
diff --git a/src/test/run-pass/trait-coercion-generic.rs b/src/test/run-pass/trait-coercion-generic.rs
index 1e241ad2278..7d924f977cb 100644
--- a/src/test/run-pass/trait-coercion-generic.rs
+++ b/src/test/run-pass/trait-coercion-generic.rs
@@ -18,6 +18,8 @@ struct Struct {
     y: int,
 }
 
+impl Copy for Struct {}
+
 impl Trait<&'static str> for Struct {
     fn f(&self, x: &'static str) {
         println!("Hi, {}!", x);
diff --git a/src/test/run-pass/trait-coercion.rs b/src/test/run-pass/trait-coercion.rs
index 55beebbf2bc..37d69ddfe07 100644
--- a/src/test/run-pass/trait-coercion.rs
+++ b/src/test/run-pass/trait-coercion.rs
@@ -19,6 +19,8 @@ struct Struct {
     y: int,
 }
 
+impl Copy for Struct {}
+
 impl Trait for Struct {
     fn f(&self) {
         println!("Hi!");
diff --git a/src/test/run-pass/typeclasses-eq-example-static.rs b/src/test/run-pass/typeclasses-eq-example-static.rs
index a5547c0eea9..6b00a8b5c2d 100644
--- a/src/test/run-pass/typeclasses-eq-example-static.rs
+++ b/src/test/run-pass/typeclasses-eq-example-static.rs
@@ -18,8 +18,11 @@ trait Equal {
     fn isEq(a: &Self, b: &Self) -> bool;
 }
 
+#[deriving(Clone)]
 enum Color { cyan, magenta, yellow, black }
 
+impl Copy for Color {}
+
 impl Equal for Color {
     fn isEq(a: &Color, b: &Color) -> bool {
         match (*a, *b) {
@@ -32,6 +35,7 @@ impl Equal for Color {
     }
 }
 
+#[deriving(Clone)]
 enum ColorTree {
     leaf(Color),
     branch(Box<ColorTree>, Box<ColorTree>)
@@ -40,9 +44,12 @@ enum ColorTree {
 impl Equal for ColorTree {
     fn isEq(a: &ColorTree, b: &ColorTree) -> bool {
         match (a, b) {
-          (&leaf(x), &leaf(y)) => { Equal::isEq(&x, &y) }
+          (&leaf(ref x), &leaf(ref y)) => {
+              Equal::isEq(&(*x).clone(), &(*y).clone())
+          }
           (&branch(ref l1, ref r1), &branch(ref l2, ref r2)) => {
-            Equal::isEq(&**l1, &**l2) && Equal::isEq(&**r1, &**r2)
+            Equal::isEq(&(**l1).clone(), &(**l2).clone()) &&
+                Equal::isEq(&(**r1).clone(), &(**r2).clone())
           }
           _ => { false }
         }
diff --git a/src/test/run-pass/typeclasses-eq-example.rs b/src/test/run-pass/typeclasses-eq-example.rs
index 21b9c774e8c..e4b7d2eb60b 100644
--- a/src/test/run-pass/typeclasses-eq-example.rs
+++ b/src/test/run-pass/typeclasses-eq-example.rs
@@ -17,8 +17,11 @@ trait Equal {
     fn isEq(&self, a: &Self) -> bool;
 }
 
+#[deriving(Clone)]
 enum Color { cyan, magenta, yellow, black }
 
+impl Copy for Color {}
+
 impl Equal for Color {
     fn isEq(&self, a: &Color) -> bool {
         match (*self, *a) {
@@ -31,6 +34,7 @@ impl Equal for Color {
     }
 }
 
+#[deriving(Clone)]
 enum ColorTree {
     leaf(Color),
     branch(Box<ColorTree>, Box<ColorTree>)
@@ -39,9 +43,9 @@ enum ColorTree {
 impl Equal for ColorTree {
     fn isEq(&self, a: &ColorTree) -> bool {
         match (self, a) {
-          (&leaf(x), &leaf(y)) => { x.isEq(&y) }
+          (&leaf(ref x), &leaf(ref y)) => { x.isEq(&(*y).clone()) }
           (&branch(ref l1, ref r1), &branch(ref l2, ref r2)) => {
-            (&**l1).isEq(&**l2) && (&**r1).isEq(&**r2)
+            (*l1).isEq(&(**l2).clone()) && (*r1).isEq(&(**r2).clone())
           }
           _ => { false }
         }
diff --git a/src/test/run-pass/ufcs-explicit-self.rs b/src/test/run-pass/ufcs-explicit-self.rs
index b96820eee14..b6b9fb67f90 100644
--- a/src/test/run-pass/ufcs-explicit-self.rs
+++ b/src/test/run-pass/ufcs-explicit-self.rs
@@ -12,6 +12,8 @@ struct Foo {
     f: int,
 }
 
+impl Copy for Foo {}
+
 impl Foo {
     fn foo(self: Foo, x: int) -> int {
         self.f + x
@@ -28,6 +30,8 @@ struct Bar<T> {
     f: T,
 }
 
+impl<T:Copy> Copy for Bar<T> {}
+
 impl<T> Bar<T> {
     fn foo(self: Bar<T>, x: int) -> int {
         x
diff --git a/src/test/run-pass/unboxed-closures-monomorphization.rs b/src/test/run-pass/unboxed-closures-monomorphization.rs
index 43fb4b296cc..cd97fd96fa3 100644
--- a/src/test/run-pass/unboxed-closures-monomorphization.rs
+++ b/src/test/run-pass/unboxed-closures-monomorphization.rs
@@ -30,6 +30,9 @@ fn main(){
 
     #[deriving(Show, PartialEq)]
     struct Foo(uint, &'static str);
+
+    impl Copy for Foo {}
+
     let x = Foo(42, "forty-two");
     let f = bar(x);
     assert_eq!(f.call_once(()), x);