about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in2
-rw-r--r--doc/tutorial-ffi.md14
-rw-r--r--src/libcore/at_vec.rs14
-rw-r--r--src/libcore/bool.rs8
-rw-r--r--src/libcore/cast.rs8
-rw-r--r--src/libcore/char.rs8
-rw-r--r--src/libcore/cleanup.rs6
-rw-r--r--src/libcore/comm.rs234
-rw-r--r--src/libcore/core.rc6
-rw-r--r--src/libcore/either.rs4
-rw-r--r--src/libcore/flate.rs5
-rw-r--r--src/libcore/hash.rs219
-rw-r--r--src/libcore/hashmap.rs2
-rw-r--r--src/libcore/io.rs113
-rw-r--r--src/libcore/iter.rs11
-rw-r--r--src/libcore/iterator.rs2
-rw-r--r--src/libcore/logging.rs2
-rw-r--r--src/libcore/managed.rs10
-rw-r--r--src/libcore/nil.rs10
-rw-r--r--src/libcore/num/f32.rs18
-rw-r--r--src/libcore/num/f64.rs18
-rw-r--r--src/libcore/num/float.rs18
-rw-r--r--src/libcore/num/int-template.rs28
-rw-r--r--src/libcore/num/uint-template.rs28
-rw-r--r--src/libcore/os.rs11
-rw-r--r--src/libcore/owned.rs6
-rw-r--r--src/libcore/pipes.rs324
-rw-r--r--src/libcore/ptr.rs15
-rw-r--r--src/libcore/rand.rs220
-rw-r--r--src/libcore/rand/distributions.rs12
-rw-r--r--src/libcore/repr.rs59
-rw-r--r--src/libcore/result.rs2
-rw-r--r--src/libcore/rt/local_services.rs4
-rw-r--r--src/libcore/rt/mod.rs25
-rw-r--r--src/libcore/rt/uvll.rs26
-rw-r--r--src/libcore/run.rs6
-rw-r--r--src/libcore/stackwalk.rs2
-rw-r--r--src/libcore/str.rs42
-rw-r--r--src/libcore/task/mod.rs279
-rw-r--r--src/libcore/task/spawn.rs112
-rw-r--r--src/libcore/tuple.rs14
-rw-r--r--src/libcore/unstable.rs25
-rw-r--r--src/libcore/unstable/at_exit.rs7
-rw-r--r--src/libcore/unstable/intrinsics.rs4
-rw-r--r--src/libcore/unstable/simd.rs43
-rw-r--r--src/libcore/unstable/weak_task.rs12
-rw-r--r--src/libcore/vec.rs42
-rw-r--r--src/libfuzzer/fuzzer.rc2
-rw-r--r--src/librustc/back/link.rs48
-rw-r--r--src/librustc/back/upcall.rs4
-rw-r--r--src/librustc/driver/driver.rs8
-rw-r--r--src/librustc/front/intrinsic.rs2
-rw-r--r--src/librustc/lib/llvm.rs18
-rw-r--r--src/librustc/metadata/decoder.rs15
-rw-r--r--src/librustc/metadata/encoder.rs56
-rw-r--r--src/librustc/metadata/tyencode.rs3
-rw-r--r--src/librustc/middle/astencode.rs2
-rw-r--r--src/librustc/middle/check_match.rs2
-rw-r--r--src/librustc/middle/entry.rs150
-rw-r--r--src/librustc/middle/kind.rs2
-rw-r--r--src/librustc/middle/lint.rs30
-rw-r--r--src/librustc/middle/mem_categorization.rs24
-rw-r--r--src/librustc/middle/region.rs12
-rw-r--r--src/librustc/middle/resolve.rs85
-rw-r--r--src/librustc/middle/resolve_stage0.rs6
-rw-r--r--src/librustc/middle/trans/_match.rs28
-rw-r--r--src/librustc/middle/trans/base.rs19
-rw-r--r--src/librustc/middle/trans/build.rs20
-rw-r--r--src/librustc/middle/trans/cabi_x86_64.rs6
-rw-r--r--src/librustc/middle/trans/callee.rs2
-rw-r--r--src/librustc/middle/trans/common.rs8
-rw-r--r--src/librustc/middle/trans/controlflow.rs4
-rw-r--r--src/librustc/middle/trans/expr.rs16
-rw-r--r--src/librustc/middle/trans/foreign.rs2
-rw-r--r--src/librustc/middle/trans/glue.rs4
-rw-r--r--src/librustc/middle/trans/meth.rs2
-rw-r--r--src/librustc/middle/trans/tvec.rs3
-rw-r--r--src/librustc/middle/trans/type_of.rs43
-rw-r--r--src/librustc/middle/trans/type_use.rs4
-rw-r--r--src/librustc/middle/ty.rs101
-rw-r--r--src/librustc/middle/typeck/check/mod.rs37
-rw-r--r--src/librustc/middle/typeck/check/writeback.rs2
-rw-r--r--src/librustc/middle/typeck/infer/region_inference.rs8
-rw-r--r--src/librustc/middle/typeck/mod.rs2
-rw-r--r--src/librustc/rustc.rc1
-rw-r--r--src/librustdoc/extract.rs4
-rw-r--r--src/librustdoc/markdown_pass.rs6
-rw-r--r--src/librustdoc/markdown_writer.rs5
-rw-r--r--src/librustdoc/pass.rs2
-rw-r--r--src/librustpkg/util.rs7
-rw-r--r--src/libstd/arc.rs18
-rw-r--r--src/libstd/arena.rs2
-rw-r--r--src/libstd/base64.rs44
-rw-r--r--src/libstd/bitv.rs16
-rw-r--r--src/libstd/comm.rs2
-rw-r--r--src/libstd/ebml.rs22
-rw-r--r--src/libstd/fileinput.rs4
-rw-r--r--src/libstd/flatpipes.rs26
-rw-r--r--src/libstd/future.rs87
-rw-r--r--src/libstd/getopts.rs4
-rw-r--r--src/libstd/io_util.rs8
-rw-r--r--src/libstd/json.rs13
-rw-r--r--src/libstd/net_ip.rs2
-rw-r--r--src/libstd/net_tcp.rs52
-rw-r--r--src/libstd/par.rs4
-rw-r--r--src/libstd/priority_queue.rs2
-rw-r--r--src/libstd/rc.rs12
-rw-r--r--src/libstd/sha1.rs6
-rw-r--r--src/libstd/sort.rs16
-rw-r--r--src/libstd/sort_stage0.rs2
-rw-r--r--src/libstd/std.rc4
-rw-r--r--src/libstd/sync.rs2
-rw-r--r--src/libstd/task_pool.rs4
-rw-r--r--src/libstd/tempfile.rs2
-rw-r--r--src/libstd/term.rs3
-rw-r--r--src/libstd/test.rs17
-rw-r--r--src/libstd/time.rs17
-rw-r--r--src/libstd/timer.rs40
-rw-r--r--src/libstd/treemap.rs2
-rw-r--r--src/libstd/uv_global_loop.rs11
-rw-r--r--src/libstd/uv_iotask.rs6
-rw-r--r--src/libstd/uv_ll.rs29
-rw-r--r--src/libsyntax/ast.rs37
-rw-r--r--src/libsyntax/ast_util.rs4
-rw-r--r--src/libsyntax/ext/auto_encode.rs12
-rw-r--r--src/libsyntax/ext/build.rs102
-rw-r--r--src/libsyntax/ext/deriving/clone.rs13
-rw-r--r--src/libsyntax/ext/deriving/cmp/eq.rs19
-rw-r--r--src/libsyntax/ext/deriving/cmp/ord.rs42
-rw-r--r--src/libsyntax/ext/deriving/cmp/totaleq.rs13
-rw-r--r--src/libsyntax/ext/deriving/cmp/totalord.rs12
-rw-r--r--src/libsyntax/ext/deriving/decodable.rs6
-rw-r--r--src/libsyntax/ext/deriving/encodable.rs14
-rw-r--r--src/libsyntax/ext/deriving/generic.rs781
-rw-r--r--src/libsyntax/ext/deriving/iter_bytes.rs282
-rw-r--r--src/libsyntax/ext/deriving/mod.rs270
-rw-r--r--src/libsyntax/ext/deriving/rand.rs141
-rw-r--r--src/libsyntax/ext/deriving/to_str.rs54
-rw-r--r--src/libsyntax/ext/deriving/ty.rs242
-rw-r--r--src/libsyntax/ext/pipes/pipec.rs15
-rw-r--r--src/libsyntax/fold.rs1
-rw-r--r--src/libsyntax/parse/parser.rs23
-rw-r--r--src/libsyntax/print/pprust.rs5
-rw-r--r--src/libsyntax/util/interner.rs2
-rw-r--r--src/rt/rust_builtin.cpp7
-rw-r--r--src/rt/rustrt.def.in1
-rw-r--r--src/test/auxiliary/cci_class_6.rs2
-rw-r--r--src/test/bench/core-map.rs2
-rw-r--r--src/test/bench/core-set.rs33
-rw-r--r--src/test/bench/core-std.rs15
-rw-r--r--src/test/bench/graph500-bfs.rs21
-rw-r--r--src/test/bench/msgsend-pipes-shared.rs8
-rw-r--r--src/test/bench/msgsend-pipes.rs6
-rw-r--r--src/test/bench/msgsend-ring-mutex-arcs.rs9
-rw-r--r--src/test/bench/msgsend-ring-pipes.rs8
-rw-r--r--src/test/bench/msgsend-ring-rw-arcs.rs9
-rw-r--r--src/test/bench/noise.rs18
-rw-r--r--src/test/bench/pingpong.rs5
-rw-r--r--src/test/bench/shootout-fasta.rs5
-rw-r--r--src/test/bench/shootout-pfib.rs13
-rw-r--r--src/test/bench/task-perf-linked-failure.rs7
-rw-r--r--src/test/bench/task-perf-spawnalot.rs2
-rw-r--r--src/test/compile-fail/block-coerce-no.rs6
-rw-r--r--src/test/compile-fail/borrowck-pat-enum.rs4
-rw-r--r--src/test/compile-fail/borrowck-unary-move.rs4
-rw-r--r--src/test/compile-fail/disallowed-deconstructing-destructing-struct.rs2
-rw-r--r--src/test/compile-fail/elided-test.rs2
-rw-r--r--src/test/compile-fail/issue-2766-a.rs4
-rw-r--r--src/test/compile-fail/issue-2995.rs2
-rw-r--r--src/test/compile-fail/issue-3296.rs2
-rw-r--r--src/test/compile-fail/liveness-use-after-send.rs2
-rw-r--r--src/test/compile-fail/main-wrong-location.rs (renamed from src/test/compile-fail/multiple-main.rs)12
-rw-r--r--src/test/compile-fail/missing-main.rs2
-rw-r--r--src/test/compile-fail/mutable-huh-ptr-assign.rs2
-rw-r--r--src/test/compile-fail/simd-type.rs13
-rw-r--r--src/test/compile-fail/tag-variant-disr-dup.rs2
-rw-r--r--src/test/compile-fail/unique-vec-res.rs2
-rw-r--r--src/test/run-fail/morestack3.rs2
-rw-r--r--src/test/run-fail/morestack4.rs2
-rw-r--r--src/test/run-fail/unwind-move.rs2
-rw-r--r--src/test/run-pass/argument-passing.rs6
-rw-r--r--src/test/run-pass/auto-ref-sliceable.rs4
-rw-r--r--src/test/run-pass/bind-by-move.rs2
-rw-r--r--src/test/run-pass/borrowck-lend-args.rs4
-rw-r--r--src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs2
-rw-r--r--src/test/run-pass/borrowck-newtype-issue-2573.rs2
-rw-r--r--src/test/run-pass/capture_nil.rs2
-rw-r--r--src/test/run-pass/child-outlives-parent.rs6
-rw-r--r--src/test/run-pass/class-poly-methods.rs2
-rw-r--r--src/test/run-pass/cleanup-copy-mode.rs2
-rw-r--r--src/test/run-pass/deriving-rand.rs39
-rw-r--r--src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs32
-rw-r--r--src/test/run-pass/deriving-self-lifetime.rs33
-rw-r--r--src/test/run-pass/deriving-to-str.rs45
-rw-r--r--src/test/run-pass/dupe-first-attr.rc2
-rw-r--r--src/test/run-pass/extern-pass-TwoU64s-ref.rs2
-rw-r--r--src/test/run-pass/extern-pub.rs6
-rw-r--r--src/test/run-pass/fn-bare-spawn.rs2
-rw-r--r--src/test/run-pass/foreign-struct.rs2
-rw-r--r--src/test/run-pass/intrinsic-alignment.rs4
-rw-r--r--src/test/run-pass/intrinsic-move-val.rs4
-rw-r--r--src/test/run-pass/issue-2633-2.rs2
-rw-r--r--src/test/run-pass/issue-2718.rs24
-rw-r--r--src/test/run-pass/issue-2904.rs2
-rw-r--r--src/test/run-pass/issue-3176.rs3
-rw-r--r--src/test/run-pass/issue-3656.rs2
-rw-r--r--src/test/run-pass/iter-min-max.rs2
-rw-r--r--src/test/run-pass/liveness-move-in-loop.rs2
-rw-r--r--src/test/run-pass/morestack5.rs2
-rw-r--r--src/test/run-pass/morestack6.rs2
-rw-r--r--src/test/run-pass/move-arg-2-unique.rs2
-rw-r--r--src/test/run-pass/move-arg-2.rs2
-rw-r--r--src/test/run-pass/move-arg.rs2
-rw-r--r--src/test/run-pass/move-nullary-fn.rs4
-rw-r--r--src/test/run-pass/operator-overloading.rs2
-rw-r--r--src/test/run-pass/option-unwrap.rs2
-rw-r--r--src/test/run-pass/pass-by-copy.rs4
-rw-r--r--src/test/run-pass/pipe-bank-proto.rs10
-rw-r--r--src/test/run-pass/pipe-peek.rs6
-rw-r--r--src/test/run-pass/pipe-pingpong-bounded.rs22
-rw-r--r--src/test/run-pass/pipe-pingpong-proto.rs4
-rw-r--r--src/test/run-pass/pipe-presentation-examples.rs4
-rw-r--r--src/test/run-pass/platform_thread.rs10
-rw-r--r--src/test/run-pass/reflect-visit-data.rs2
-rw-r--r--src/test/run-pass/regions-copy-closure.rs2
-rw-r--r--src/test/run-pass/regions-static-closure.rs2
-rw-r--r--src/test/run-pass/sendfn-spawn-with-fn-arg.rs2
-rw-r--r--src/test/run-pass/simd-type.rs9
-rw-r--r--src/test/run-pass/spawn.rs2
-rw-r--r--src/test/run-pass/spawn2.rs2
-rw-r--r--src/test/run-pass/static-method-test.rs14
-rw-r--r--src/test/run-pass/struct-return.rs4
-rw-r--r--src/test/run-pass/task-comm-12.rs6
-rw-r--r--src/test/run-pass/task-comm-3.rs6
-rw-r--r--src/test/run-pass/task-comm-9.rs5
-rw-r--r--src/test/run-pass/task-life-0.rs2
-rw-r--r--src/test/run-pass/threads.rs2
-rw-r--r--src/test/run-pass/unique-fn-arg-move.rs2
-rw-r--r--src/test/run-pass/yield.rs4
-rw-r--r--src/test/run-pass/yield1.rs4
240 files changed, 3577 insertions, 2503 deletions
diff --git a/Makefile.in b/Makefile.in
index d531b9879a9..8ab704ebe17 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -101,7 +101,7 @@ endif
 
 ifdef CFG_ENABLE_DEBUG
   $(info cfg: enabling more debugging (CFG_ENABLE_DEBUG))
-  CFG_RUSTC_FLAGS +=
+  CFG_RUSTC_FLAGS += --cfg debug
   CFG_GCCISH_CFLAGS += -DRUST_DEBUG
 else
   CFG_GCCISH_CFLAGS += -DRUST_NDEBUG
diff --git a/doc/tutorial-ffi.md b/doc/tutorial-ffi.md
index b806df5dd20..2a3d8dc1481 100644
--- a/doc/tutorial-ffi.md
+++ b/doc/tutorial-ffi.md
@@ -157,7 +157,7 @@ pub struct Unique<T> {
     priv ptr: *mut T
 }
 
-pub impl<'self, T: Owned> Unique<T> {
+pub impl<T: Owned> Unique<T> {
     fn new(value: T) -> Unique<T> {
         unsafe {
             let ptr = malloc(core::sys::size_of::<T>() as size_t) as *mut T;
@@ -168,14 +168,14 @@ pub impl<'self, T: Owned> Unique<T> {
         }
     }
 
-    // the 'self lifetime results in the same semantics as `&*x` with ~T
-    fn borrow(&self) -> &'self T {
-        unsafe { cast::transmute(self.ptr) }
+    // the 'r lifetime results in the same semantics as `&*x` with ~T
+    fn borrow<'r>(&'r self) -> &'r T {
+        unsafe { cast::copy_lifetime(self, &*self.ptr) }
     }
 
-    // the 'self lifetime results in the same semantics as `&mut *x` with ~T
-    fn borrow_mut(&mut self) -> &'self mut T {
-        unsafe { cast::transmute(self.ptr) }
+    // the 'r lifetime results in the same semantics as `&mut *x` with ~T
+    fn borrow_mut<'r>(&'r mut self) -> &'r mut T {
+        unsafe { cast::copy_mut_lifetime(self, &mut *self.ptr) }
     }
 }
 
diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs
index b03a1404f8e..a3981dd8491 100644
--- a/src/libcore/at_vec.rs
+++ b/src/libcore/at_vec.rs
@@ -29,9 +29,9 @@ pub mod rustrt {
     #[abi = "cdecl"]
     #[link_name = "rustrt"]
     pub extern {
-        pub unsafe fn vec_reserve_shared_actual(++t: *sys::TypeDesc,
-                                                ++v: **vec::raw::VecRepr,
-                                                ++n: libc::size_t);
+        pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc,
+                                                v: **vec::raw::VecRepr,
+                                                n: libc::size_t);
     }
 }
 
@@ -60,7 +60,7 @@ pub fn capacity<T>(v: @[T]) -> uint {
 pub fn build_sized<A>(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] {
     let mut vec: @[A] = @[];
     unsafe { raw::reserve(&mut vec, size); }
-    builder(|+x| unsafe { raw::push(&mut vec, x) });
+    builder(|x| unsafe { raw::push(&mut vec, x) });
     return unsafe { transmute(vec) };
 }
 
@@ -102,7 +102,7 @@ pub fn build_sized_opt<A>(size: Option<uint>,
 #[inline(always)]
 pub fn append<T:Copy>(lhs: @[T], rhs: &const [T]) -> @[T] {
     do build_sized(lhs.len() + rhs.len()) |push| {
-        for vec::each(lhs) |x| { push(*x); }
+        for lhs.each |x| { push(*x); }
         for uint::range(0, rhs.len()) |i| { push(rhs[i]); }
     }
 }
@@ -111,7 +111,7 @@ pub fn append<T:Copy>(lhs: @[T], rhs: &const [T]) -> @[T] {
 /// Apply a function to each element of a vector and return the results
 pub fn map<T, U>(v: &[T], f: &fn(x: &T) -> U) -> @[U] {
     do build_sized(v.len()) |push| {
-        for vec::each(v) |elem| {
+        for v.each |elem| {
             push(f(elem));
         }
     }
@@ -166,7 +166,7 @@ pub fn from_slice<T:Copy>(v: &[T]) -> @[T] {
     from_fn(v.len(), |i| v[i])
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 pub mod traits {
     use at_vec::append;
     use kinds::Copy;
diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs
index 1b4b81dca26..76a8f456cd5 100644
--- a/src/libcore/bool.rs
+++ b/src/libcore/bool.rs
@@ -10,7 +10,7 @@
 
 //! Boolean logic
 
-#[cfg(notest)]
+#[cfg(not(test))]
 use cmp::{Eq, Ord, TotalOrd, Ordering};
 use option::{None, Option, Some};
 use from_str::FromStr;
@@ -75,7 +75,7 @@ pub fn all_values(blk: &fn(v: bool)) {
 #[inline(always)]
 pub fn to_bit(v: bool) -> u8 { if v { 1u8 } else { 0u8 } }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Ord for bool {
     #[inline(always)]
     fn lt(&self, other: &bool) -> bool { to_bit(*self) < to_bit(*other) }
@@ -87,13 +87,13 @@ impl Ord for bool {
     fn ge(&self, other: &bool) -> bool { to_bit(*self) >= to_bit(*other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl TotalOrd for bool {
     #[inline(always)]
     fn cmp(&self, other: &bool) -> Ordering { to_bit(*self).cmp(&to_bit(*other)) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Eq for bool {
     #[inline(always)]
     fn eq(&self, other: &bool) -> bool { (*self) == (*other) }
diff --git a/src/libcore/cast.rs b/src/libcore/cast.rs
index 96e1c3bd124..5e6d2f8b910 100644
--- a/src/libcore/cast.rs
+++ b/src/libcore/cast.rs
@@ -17,7 +17,7 @@ pub mod rusti {
     #[abi = "rust-intrinsic"]
     #[link_name = "rusti"]
     pub extern "rust-intrinsic" {
-        fn forget<T>(+x: T);
+        fn forget<T>(x: T);
 
         fn transmute<T,U>(e: T) -> U;
     }
@@ -110,6 +110,12 @@ pub unsafe fn copy_lifetime<'a,S,T>(_ptr: &'a S, ptr: &T) -> &'a T {
 
 /// Transforms lifetime of the second pointer to match the first.
 #[inline(always)]
+pub unsafe fn copy_mut_lifetime<'a,S,T>(_ptr: &'a mut S, ptr: &mut T) -> &'a mut T {
+    transmute_mut_region(ptr)
+}
+
+/// Transforms lifetime of the second pointer to match the first.
+#[inline(always)]
 pub unsafe fn copy_lifetime_vec<'a,S,T>(_ptr: &'a [S], ptr: &T) -> &'a T {
     transmute_region(ptr)
 }
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index a96f1a2ff81..a9c46b81f86 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -10,7 +10,7 @@
 
 //! Utilities for manipulating the char type
 
-#[cfg(notest)]
+#[cfg(not(test))]
 use cmp::Ord;
 use option::{None, Option, Some};
 use str;
@@ -18,7 +18,7 @@ use u32;
 use uint;
 use unicode::{derived_property, general_category};
 
-#[cfg(notest)] use cmp::Eq;
+#[cfg(not(test))] use cmp::Eq;
 
 /*
     Lu  Uppercase_Letter    an uppercase letter
@@ -244,7 +244,7 @@ pub fn len_utf8_bytes(c: char) -> uint {
     else { fail!(~"invalid character!") }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Eq for char {
     #[inline(always)]
     fn eq(&self, other: &char) -> bool { (*self) == (*other) }
@@ -252,7 +252,7 @@ impl Eq for char {
     fn ne(&self, other: &char) -> bool { (*self) != (*other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Ord for char {
     #[inline(always)]
     fn lt(&self, other: &char) -> bool { *self < *other }
diff --git a/src/libcore/cleanup.rs b/src/libcore/cleanup.rs
index 424cc348309..912f965db7c 100644
--- a/src/libcore/cleanup.rs
+++ b/src/libcore/cleanup.rs
@@ -15,9 +15,9 @@ use ptr::mut_null;
 use repr::BoxRepr;
 use sys::TypeDesc;
 use cast::transmute;
-#[cfg(notest)] use unstable::lang::clear_task_borrow_list;
+#[cfg(not(test))] use unstable::lang::clear_task_borrow_list;
 
-#[cfg(notest)] use ptr::to_unsafe_ptr;
+#[cfg(not(test))] use ptr::to_unsafe_ptr;
 
 /**
  * Runtime structures
@@ -164,7 +164,7 @@ fn debug_mem() -> bool {
 }
 
 /// Destroys all managed memory (i.e. @ boxes) held by the current task.
-#[cfg(notest)]
+#[cfg(not(test))]
 #[lang="annihilate"]
 pub unsafe fn annihilate() {
     use unstable::lang::local_free;
diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs
index d075ff08bb7..7eaa8535493 100644
--- a/src/libcore/comm.rs
+++ b/src/libcore/comm.rs
@@ -12,6 +12,7 @@
 Message passing
 */
 
+use cast::{transmute, transmute_mut};
 use cast;
 use either::{Either, Left, Right};
 use kinds::Owned;
@@ -118,13 +119,15 @@ pub mod streamp {
 }
 
 /// An endpoint that can send many messages.
+#[unsafe_mut_field(endp)]
 pub struct Chan<T> {
-    mut endp: Option<streamp::client::Open<T>>
+    endp: Option<streamp::client::Open<T>>
 }
 
 /// An endpoint that can receive many messages.
+#[unsafe_mut_field(endp)]
 pub struct Port<T> {
-    mut endp: Option<streamp::server::Open<T>>,
+    endp: Option<streamp::server::Open<T>>,
 }
 
 /** Creates a `(Port, Chan)` pair.
@@ -135,30 +138,39 @@ These allow sending or receiving an unlimited number of messages.
 pub fn stream<T:Owned>() -> (Port<T>, Chan<T>) {
     let (c, s) = streamp::init();
 
-    (Port { endp: Some(s) }, Chan { endp: Some(c) })
+    (Port {
+        endp: Some(s)
+    }, Chan {
+        endp: Some(c)
+    })
 }
 
 impl<T: Owned> GenericChan<T> for Chan<T> {
     #[inline(always)]
     fn send(&self, x: T) {
-        let mut endp = None;
-        endp <-> self.endp;
-        self.endp = Some(
-            streamp::client::data(endp.unwrap(), x))
+        unsafe {
+            let mut endp = None;
+            let mut self_endp = transmute_mut(&self.endp);
+            endp <-> *self_endp;
+            *self_endp = Some(streamp::client::data(endp.unwrap(), x))
+        }
     }
 }
 
 impl<T: Owned> GenericSmartChan<T> for Chan<T> {
     #[inline(always)]
     fn try_send(&self, x: T) -> bool {
-        let mut endp = None;
-        endp <-> self.endp;
-        match streamp::client::try_data(endp.unwrap(), x) {
-            Some(next) => {
-                self.endp = Some(next);
-                true
+        unsafe {
+            let mut endp = None;
+            let mut self_endp = transmute_mut(&self.endp);
+            endp <-> *self_endp;
+            match streamp::client::try_data(endp.unwrap(), x) {
+                Some(next) => {
+                    *self_endp = Some(next);
+                    true
+                }
+                None => false
             }
-            None => false
         }
     }
 }
@@ -166,23 +178,29 @@ impl<T: Owned> GenericSmartChan<T> for Chan<T> {
 impl<T: Owned> GenericPort<T> for Port<T> {
     #[inline(always)]
     fn recv(&self) -> T {
-        let mut endp = None;
-        endp <-> self.endp;
-        let streamp::data(x, endp) = recv(endp.unwrap());
-        self.endp = Some(endp);
-        x
+        unsafe {
+            let mut endp = None;
+            let mut self_endp = transmute_mut(&self.endp);
+            endp <-> *self_endp;
+            let streamp::data(x, endp) = recv(endp.unwrap());
+            *self_endp = Some(endp);
+            x
+        }
     }
 
     #[inline(always)]
     fn try_recv(&self) -> Option<T> {
-        let mut endp = None;
-        endp <-> self.endp;
-        match try_recv(endp.unwrap()) {
-            Some(streamp::data(x, endp)) => {
-                self.endp = Some(endp);
-                Some(x)
+        unsafe {
+            let mut endp = None;
+            let mut self_endp = transmute_mut(&self.endp);
+            endp <-> *self_endp;
+            match try_recv(endp.unwrap()) {
+                Some(streamp::data(x, endp)) => {
+                    *self_endp = Some(endp);
+                    Some(x)
+                }
+                None => None
             }
-            None => None
         }
     }
 }
@@ -190,22 +208,25 @@ impl<T: Owned> GenericPort<T> for Port<T> {
 impl<T: Owned> Peekable<T> for Port<T> {
     #[inline(always)]
     fn peek(&self) -> bool {
-        let mut endp = None;
-        endp <-> self.endp;
-        let peek = match &endp {
-            &Some(ref endp) => peek(endp),
-            &None => fail!(~"peeking empty stream")
-        };
-        self.endp <-> endp;
-        peek
+        unsafe {
+            let mut endp = None;
+            let mut self_endp = transmute_mut(&self.endp);
+            endp <-> *self_endp;
+            let peek = match endp {
+                Some(ref mut endp) => peek(endp),
+                None => fail!(~"peeking empty stream")
+            };
+            *self_endp <-> endp;
+            peek
+        }
     }
 }
 
 impl<T: Owned> Selectable for Port<T> {
-    fn header(&self) -> *PacketHeader {
+    fn header(&mut self) -> *mut PacketHeader {
         unsafe {
             match self.endp {
-                Some(ref endp) => endp.header(),
+                Some(ref mut endp) => endp.header(),
                 None => fail!(~"peeking empty stream")
             }
         }
@@ -213,12 +234,12 @@ impl<T: Owned> Selectable for Port<T> {
 }
 
 /// Treat many ports as one.
+#[unsafe_mut_field(ports)]
 pub struct PortSet<T> {
-    mut ports: ~[Port<T>],
+    ports: ~[Port<T>],
 }
 
 pub impl<T: Owned> PortSet<T> {
-
     fn new() -> PortSet<T> {
         PortSet {
             ports: ~[]
@@ -226,7 +247,10 @@ pub impl<T: Owned> PortSet<T> {
     }
 
     fn add(&self, port: Port<T>) {
-        self.ports.push(port)
+        unsafe {
+            let self_ports = transmute_mut(&self.ports);
+            self_ports.push(port)
+        }
     }
 
     fn chan(&self) -> Chan<T> {
@@ -238,25 +262,28 @@ pub impl<T: Owned> PortSet<T> {
 
 impl<T:Owned> GenericPort<T> for PortSet<T> {
     fn try_recv(&self) -> Option<T> {
-        let mut result = None;
-        // we have to swap the ports array so we aren't borrowing
-        // aliasable mutable memory.
-        let mut ports = ~[];
-        ports <-> self.ports;
-        while result.is_none() && ports.len() > 0 {
-            let i = wait_many(ports);
-            match ports[i].try_recv() {
-                Some(m) => {
-                    result = Some(m);
-                }
-                None => {
-                    // Remove this port.
-                    let _ = ports.swap_remove(i);
+        unsafe {
+            let mut self_ports = transmute_mut(&self.ports);
+            let mut result = None;
+            // we have to swap the ports array so we aren't borrowing
+            // aliasable mutable memory.
+            let mut ports = ~[];
+            ports <-> *self_ports;
+            while result.is_none() && ports.len() > 0 {
+                let i = wait_many(ports);
+                match ports[i].try_recv() {
+                    Some(m) => {
+                        result = Some(m);
+                    }
+                    None => {
+                        // Remove this port.
+                        let _ = ports.swap_remove(i);
+                    }
                 }
             }
+            ports <-> *self_ports;
+            result
         }
-        ports <-> self.ports;
-        result
     }
     fn recv(&self) -> T {
         self.try_recv().expect("port_set: endpoints closed")
@@ -268,10 +295,9 @@ impl<T: Owned> Peekable<T> for PortSet<T> {
         // It'd be nice to use self.port.each, but that version isn't
         // pure.
         for uint::range(0, vec::uniq_len(&const self.ports)) |i| {
-            // XXX: Botch pending demuting.
-            unsafe {
-                let port: &Port<T> = cast::transmute(&mut self.ports[i]);
-                if port.peek() { return true }
+            let port: &Port<T> = &self.ports[i];
+            if port.peek() {
+                return true;
             }
         }
         false
@@ -327,23 +353,20 @@ impl<T: Owned> ::clone::Clone for SharedChan<T> {
 #[allow(non_camel_case_types)]
 pub mod oneshot {
     priv use core::kinds::Owned;
-    use ptr::to_unsafe_ptr;
+    use ptr::to_mut_unsafe_ptr;
 
     pub fn init<T: Owned>() -> (client::Oneshot<T>, server::Oneshot<T>) {
         pub use core::pipes::HasBuffer;
 
-        let buffer =
-            ~::core::pipes::Buffer{
+        let mut buffer = ~::core::pipes::Buffer {
             header: ::core::pipes::BufferHeader(),
-            data: __Buffer{
+            data: __Buffer {
                 Oneshot: ::core::pipes::mk_packet::<Oneshot<T>>()
             },
         };
         do ::core::pipes::entangle_buffer(buffer) |buffer, data| {
-            {
-                data.Oneshot.set_buffer(buffer);
-                to_unsafe_ptr(&data.Oneshot)
-            }
+            data.Oneshot.set_buffer(buffer);
+            to_mut_unsafe_ptr(&mut data.Oneshot)
         }
     }
     #[allow(non_camel_case_types)]
@@ -497,48 +520,66 @@ pub fn try_send_one<T: Owned>(chan: ChanOne<T>, data: T) -> bool {
 
 
 /// Returns the index of an endpoint that is ready to receive.
-pub fn selecti<T: Selectable>(endpoints: &[T]) -> uint {
+pub fn selecti<T: Selectable>(endpoints: &mut [T]) -> uint {
     wait_many(endpoints)
 }
 
 /// Returns 0 or 1 depending on which endpoint is ready to receive
-pub fn select2i<A: Selectable, B: Selectable>(a: &A, b: &B) ->
-        Either<(), ()> {
-    match wait_many([a.header(), b.header()]) {
-      0 => Left(()),
-      1 => Right(()),
-      _ => fail!(~"wait returned unexpected index")
+pub fn select2i<A:Selectable, B:Selectable>(a: &mut A, b: &mut B)
+                                            -> Either<(), ()> {
+    let mut endpoints = [ a.header(), b.header() ];
+    match wait_many(endpoints) {
+        0 => Left(()),
+        1 => Right(()),
+        _ => fail!(~"wait returned unexpected index"),
     }
 }
 
 /// Receive a message from one of two endpoints.
 pub trait Select2<T: Owned, U: Owned> {
     /// Receive a message or return `None` if a connection closes.
-    fn try_select(&self) -> Either<Option<T>, Option<U>>;
+    fn try_select(&mut self) -> Either<Option<T>, Option<U>>;
     /// Receive a message or fail if a connection closes.
-    fn select(&self) -> Either<T, U>;
+    fn select(&mut self) -> Either<T, U>;
 }
 
-impl<T: Owned, U: Owned,
-     Left: Selectable + GenericPort<T>,
-     Right: Selectable + GenericPort<U>>
-    Select2<T, U> for (Left, Right) {
-
-    fn select(&self) -> Either<T, U> {
-        match *self {
-          (ref lp, ref rp) => match select2i(lp, rp) {
-            Left(()) => Left (lp.recv()),
-            Right(()) => Right(rp.recv())
-          }
+impl<T:Owned,
+     U:Owned,
+     Left:Selectable + GenericPort<T>,
+     Right:Selectable + GenericPort<U>>
+     Select2<T, U>
+     for (Left, Right) {
+    fn select(&mut self) -> Either<T, U> {
+        // XXX: Bad borrow check workaround.
+        unsafe {
+            let this: &(Left, Right) = transmute(self);
+            match *this {
+                (ref lp, ref rp) => {
+                    let lp: &mut Left = transmute(lp);
+                    let rp: &mut Right = transmute(rp);
+                    match select2i(lp, rp) {
+                        Left(()) => Left(lp.recv()),
+                        Right(()) => Right(rp.recv()),
+                    }
+                }
+            }
         }
     }
 
-    fn try_select(&self) -> Either<Option<T>, Option<U>> {
-        match *self {
-          (ref lp, ref rp) => match select2i(lp, rp) {
-            Left(()) => Left (lp.try_recv()),
-            Right(()) => Right(rp.try_recv())
-          }
+    fn try_select(&mut self) -> Either<Option<T>, Option<U>> {
+        // XXX: Bad borrow check workaround.
+        unsafe {
+            let this: &(Left, Right) = transmute(self);
+            match *this {
+                (ref lp, ref rp) => {
+                    let lp: &mut Left = transmute(lp);
+                    let rp: &mut Right = transmute(rp);
+                    match select2i(lp, rp) {
+                        Left(()) => Left (lp.try_recv()),
+                        Right(()) => Right(rp.try_recv()),
+                    }
+                }
+            }
         }
     }
 }
@@ -555,9 +596,10 @@ mod test {
 
         c1.send(~"abc");
 
-        match (p1, p2).select() {
-          Right(_) => fail!(),
-          _ => ()
+        let mut tuple = (p1, p2);
+        match tuple.select() {
+            Right(_) => fail!(),
+            _ => (),
         }
 
         c2.send(123);
diff --git a/src/libcore/core.rc b/src/libcore/core.rc
index 15b0be7b4bc..3ab81fd7161 100644
--- a/src/libcore/core.rc
+++ b/src/libcore/core.rc
@@ -179,9 +179,9 @@ pub mod managed;
 
 /* Core language traits */
 
-#[cfg(notest)] pub mod kinds;
-#[cfg(notest)] pub mod ops;
-#[cfg(notest)] pub mod cmp;
+#[cfg(not(test))] pub mod kinds;
+#[cfg(not(test))] pub mod ops;
+#[cfg(not(test))] pub mod cmp;
 
 
 /* Common traits */
diff --git a/src/libcore/either.rs b/src/libcore/either.rs
index 33b7e81ee85..957e848b5e7 100644
--- a/src/libcore/either.rs
+++ b/src/libcore/either.rs
@@ -44,7 +44,7 @@ pub fn lefts<T:Copy,U>(eithers: &[Either<T, U>]) -> ~[T] {
     //! Extracts from a vector of either all the left values
 
     do vec::build_sized(eithers.len()) |push| {
-        for vec::each(eithers) |elt| {
+        for eithers.each |elt| {
             match *elt {
                 Left(ref l) => { push(*l); }
                 _ => { /* fallthrough */ }
@@ -57,7 +57,7 @@ pub fn rights<T, U: Copy>(eithers: &[Either<T, U>]) -> ~[U] {
     //! Extracts from a vector of either all the right values
 
     do vec::build_sized(eithers.len()) |push| {
-        for vec::each(eithers) |elt| {
+        for eithers.each |elt| {
             match *elt {
                 Right(ref r) => { push(*r); }
                 _ => { /* fallthrough */ }
diff --git a/src/libcore/flate.rs b/src/libcore/flate.rs
index ba10f97e626..29d0eb422d5 100644
--- a/src/libcore/flate.rs
+++ b/src/libcore/flate.rs
@@ -84,10 +84,11 @@ pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] {
 #[test]
 #[allow(non_implicitly_copyable_typarams)]
 fn test_flate_round_trip() {
-    let r = rand::rng();
+    let mut r = rand::rng();
     let mut words = ~[];
     for 20.times {
-        words.push(r.gen_bytes(r.gen_uint_range(1, 10)));
+        let range = r.gen_uint_range(1, 10);
+        words.push(r.gen_bytes(range));
     }
     for 20.times {
         let mut in = ~[];
diff --git a/src/libcore/hash.rs b/src/libcore/hash.rs
index ba1f8cebdb0..75b3b6bb566 100644
--- a/src/libcore/hash.rs
+++ b/src/libcore/hash.rs
@@ -19,11 +19,14 @@
  * CPRNG like rand::rng.
  */
 
-use io;
-use io::Writer;
+#[cfg(stage0)]
+use cast;
+use rt::io::Writer;
 use to_bytes::IterBytes;
 use uint;
-use vec;
+
+// Alias `SipState` to `State`.
+pub use State = hash::SipState;
 
 /**
  * Types that can meaningfully be hashed should implement this.
@@ -65,20 +68,32 @@ impl<A:Hash> HashUtil for A {
 
 /// Streaming hash-functions should implement this.
 pub trait Streaming {
-    fn input(&self, (&const [u8]));
+    fn input(&mut self, &[u8]);
     // These can be refactored some when we have default methods.
-    fn result_bytes(&self) -> ~[u8];
-    fn result_str(&self) -> ~str;
-    fn result_u64(&self) -> u64;
-    fn reset(&self);
+    fn result_bytes(&mut self) -> ~[u8];
+    fn result_str(&mut self) -> ~str;
+    fn result_u64(&mut self) -> u64;
+    fn reset(&mut self);
+}
+
+// XXX: Ugly workaround for bootstrapping.
+#[cfg(stage0)]
+fn transmute_for_stage0<'a>(bytes: &'a [const u8]) -> &'a [u8] {
+    unsafe {
+        cast::transmute(bytes)
+    }
+}
+#[cfg(not(stage0))]
+fn transmute_for_stage0<'a>(bytes: &'a [u8]) -> &'a [u8] {
+    bytes
 }
 
 impl<A:IterBytes> Hash for A {
     #[inline(always)]
     fn hash_keyed(&self, k0: u64, k1: u64) -> u64 {
-        let s = &State(k0, k1);
+        let mut s = State::new(k0, k1);
         for self.iter_bytes(true) |bytes| {
-            s.input(bytes);
+            s.input(transmute_for_stage0(bytes));
         }
         s.result_u64()
     }
@@ -86,32 +101,56 @@ impl<A:IterBytes> Hash for A {
 
 fn hash_keyed_2<A: IterBytes,
                 B: IterBytes>(a: &A, b: &B, k0: u64, k1: u64) -> u64 {
-    let s = &State(k0, k1);
-    for a.iter_bytes(true) |bytes| { s.input(bytes); }
-    for b.iter_bytes(true) |bytes| { s.input(bytes); }
+    let mut s = State::new(k0, k1);
+    for a.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for b.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
     s.result_u64()
 }
 
 fn hash_keyed_3<A: IterBytes,
                 B: IterBytes,
                 C: IterBytes>(a: &A, b: &B, c: &C, k0: u64, k1: u64) -> u64 {
-    let s = &State(k0, k1);
-    for a.iter_bytes(true) |bytes| { s.input(bytes); }
-    for b.iter_bytes(true) |bytes| { s.input(bytes); }
-    for c.iter_bytes(true) |bytes| { s.input(bytes); }
+    let mut s = State::new(k0, k1);
+    for a.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for b.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for c.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
     s.result_u64()
 }
 
 fn hash_keyed_4<A: IterBytes,
                 B: IterBytes,
                 C: IterBytes,
-                D: IterBytes>(a: &A, b: &B, c: &C, d: &D, k0: u64, k1: u64)
-                           -> u64 {
-    let s = &State(k0, k1);
-    for a.iter_bytes(true) |bytes| { s.input(bytes); }
-    for b.iter_bytes(true) |bytes| { s.input(bytes); }
-    for c.iter_bytes(true) |bytes| { s.input(bytes); }
-    for d.iter_bytes(true) |bytes| { s.input(bytes); }
+                D: IterBytes>(
+                a: &A,
+                b: &B,
+                c: &C,
+                d: &D,
+                k0: u64,
+                k1: u64)
+                -> u64 {
+    let mut s = State::new(k0, k1);
+    for a.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for b.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for c.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for d.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
     s.result_u64()
 }
 
@@ -119,58 +158,68 @@ fn hash_keyed_5<A: IterBytes,
                 B: IterBytes,
                 C: IterBytes,
                 D: IterBytes,
-                E: IterBytes>(a: &A, b: &B, c: &C, d: &D, e: &E,
-                              k0: u64, k1: u64) -> u64 {
-    let s = &State(k0, k1);
-    for a.iter_bytes(true) |bytes| { s.input(bytes); }
-    for b.iter_bytes(true) |bytes| { s.input(bytes); }
-    for c.iter_bytes(true) |bytes| { s.input(bytes); }
-    for d.iter_bytes(true) |bytes| { s.input(bytes); }
-    for e.iter_bytes(true) |bytes| { s.input(bytes); }
+                E: IterBytes>(
+                a: &A,
+                b: &B,
+                c: &C,
+                d: &D,
+                e: &E,
+                k0: u64,
+                k1: u64)
+                -> u64 {
+    let mut s = State::new(k0, k1);
+    for a.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for b.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for c.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for d.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
+    for e.iter_bytes(true) |bytes| {
+        s.input(transmute_for_stage0(bytes));
+    }
     s.result_u64()
 }
 
-// Implement State as SipState
-
-pub type State = SipState;
-
-#[inline(always)]
-pub fn State(k0: u64, k1: u64) -> State {
-    SipState(k0, k1)
-}
-
 #[inline(always)]
 pub fn default_state() -> State {
-    State(0,0)
+    State::new(0, 0)
 }
 
 struct SipState {
     k0: u64,
     k1: u64,
-    mut length: uint, // how many bytes we've processed
-    mut v0: u64,      // hash state
-    mut v1: u64,
-    mut v2: u64,
-    mut v3: u64,
-    mut tail: [u8, ..8], // unprocessed bytes
-    mut ntail: uint,  // how many bytes in tail are valid
+    length: uint, // how many bytes we've processed
+    v0: u64,      // hash state
+    v1: u64,
+    v2: u64,
+    v3: u64,
+    tail: [u8, ..8], // unprocessed bytes
+    ntail: uint,  // how many bytes in tail are valid
 }
 
-#[inline(always)]
-fn SipState(key0: u64, key1: u64) -> SipState {
-    let state = SipState {
-        k0 : key0,
-        k1 : key1,
-        mut length : 0u,
-        mut v0 : 0u64,
-        mut v1 : 0u64,
-        mut v2 : 0u64,
-        mut v3 : 0u64,
-        mut tail : [0u8,0,0,0,0,0,0,0],
-        mut ntail : 0u,
-    };
-    (&state).reset();
-    state
+impl SipState {
+    #[inline(always)]
+    fn new(key0: u64, key1: u64) -> SipState {
+        let mut state = SipState {
+            k0: key0,
+            k1: key1,
+            length: 0,
+            v0: 0,
+            v1: 0,
+            v2: 0,
+            v3: 0,
+            tail: [ 0, 0, 0, 0, 0, 0, 0, 0 ],
+            ntail: 0,
+        };
+        state.reset();
+        state
+    }
 }
 
 // sadly, these macro definitions can't appear later,
@@ -207,12 +256,10 @@ macro_rules! compress (
 )
 
 
-impl io::Writer for SipState {
-
+impl Writer for SipState {
     // Methods for io::writer
     #[inline(always)]
-    fn write(&self, msg: &const [u8]) {
-
+    fn write(&mut self, msg: &[u8]) {
         let length = msg.len();
         self.length += length;
 
@@ -272,29 +319,19 @@ impl io::Writer for SipState {
         self.ntail = left;
     }
 
-    fn seek(&self, _x: int, _s: io::SeekStyle) {
-        fail!();
-    }
-    fn tell(&self) -> uint {
-        self.length
-    }
-    fn flush(&self) -> int {
-        0
-    }
-    fn get_type(&self) -> io::WriterType {
-        io::File
+    fn flush(&mut self) {
+        // No-op
     }
 }
 
 impl Streaming for SipState {
-
     #[inline(always)]
-    fn input(&self, buf: &const [u8]) {
+    fn input(&mut self, buf: &[u8]) {
         self.write(buf);
     }
 
     #[inline(always)]
-    fn result_u64(&self) -> u64 {
+    fn result_u64(&mut self) -> u64 {
         let mut v0 = self.v0;
         let mut v1 = self.v1;
         let mut v2 = self.v2;
@@ -324,7 +361,7 @@ impl Streaming for SipState {
         return (v0 ^ v1 ^ v2 ^ v3);
     }
 
-    fn result_bytes(&self) -> ~[u8] {
+    fn result_bytes(&mut self) -> ~[u8] {
         let h = self.result_u64();
         ~[(h >> 0) as u8,
           (h >> 8) as u8,
@@ -337,17 +374,17 @@ impl Streaming for SipState {
         ]
     }
 
-    fn result_str(&self) -> ~str {
+    fn result_str(&mut self) -> ~str {
         let r = self.result_bytes();
         let mut s = ~"";
-        for vec::each(r) |b| {
+        for r.each |b| {
             s += uint::to_str_radix(*b as uint, 16u);
         }
         s
     }
 
     #[inline(always)]
-    fn reset(&self) {
+    fn reset(&mut self) {
         self.length = 0;
         self.v0 = self.k0 ^ 0x736f6d6570736575;
         self.v1 = self.k1 ^ 0x646f72616e646f6d;
@@ -435,12 +472,12 @@ mod tests {
         let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08_u64;
         let mut buf : ~[u8] = ~[];
         let mut t = 0;
-        let stream_inc = &State(k0,k1);
-        let stream_full = &State(k0,k1);
+        let mut stream_inc = SipState::new(k0, k1);
+        let mut stream_full = SipState::new(k0, k1);
 
-        fn to_hex_str(r:  &[u8, ..8]) -> ~str {
+        fn to_hex_str(r: &[u8, ..8]) -> ~str {
             let mut s = ~"";
-            for vec::each(*r) |b| {
+            for (*r).each |b| {
                 s += uint::to_str_radix(*b as uint, 16u);
             }
             s
@@ -529,4 +566,4 @@ mod tests {
             val & !(0xff << (byte * 8))
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/libcore/hashmap.rs b/src/libcore/hashmap.rs
index b764fccf64c..8e0a185248e 100644
--- a/src/libcore/hashmap.rs
+++ b/src/libcore/hashmap.rs
@@ -56,7 +56,7 @@ fn resize_at(capacity: uint) -> uint {
 
 pub fn linear_map_with_capacity<K:Eq + Hash,V>(
     initial_capacity: uint) -> HashMap<K, V> {
-    let r = rand::task_rng();
+    let mut r = rand::task_rng();
     linear_map_with_capacity_and_keys(r.gen(), r.gen(),
                                       initial_capacity)
 }
diff --git a/src/libcore/io.rs b/src/libcore/io.rs
index 64b69a7928b..7fc2c2559c2 100644
--- a/src/libcore/io.rs
+++ b/src/libcore/io.rs
@@ -983,36 +983,50 @@ pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
 // Byte readers
 pub struct BytesReader<'self> {
     bytes: &'self [u8],
-    mut pos: uint
+    pos: @mut uint
 }
 
 impl<'self> Reader for BytesReader<'self> {
     fn read(&self, bytes: &mut [u8], len: uint) -> uint {
-        let count = uint::min(len, self.bytes.len() - self.pos);
+        let count = uint::min(len, self.bytes.len() - *self.pos);
 
-        let view = vec::slice(self.bytes, self.pos, self.bytes.len());
+        let view = vec::slice(self.bytes, *self.pos, self.bytes.len());
         vec::bytes::copy_memory(bytes, view, count);
 
-        self.pos += count;
+        *self.pos += count;
 
         count
     }
+
     fn read_byte(&self) -> int {
-        if self.pos == self.bytes.len() { return -1; }
-        let b = self.bytes[self.pos];
-        self.pos += 1u;
-        return b as int;
+        if *self.pos == self.bytes.len() {
+            return -1;
+        }
+
+        let b = self.bytes[*self.pos];
+        *self.pos += 1u;
+        b as int
+    }
+
+    fn eof(&self) -> bool {
+        *self.pos == self.bytes.len()
     }
-    fn eof(&self) -> bool { self.pos == self.bytes.len() }
+
     fn seek(&self, offset: int, whence: SeekStyle) {
-        let pos = self.pos;
-        self.pos = seek_in_buf(offset, pos, self.bytes.len(), whence);
+        let pos = *self.pos;
+        *self.pos = seek_in_buf(offset, pos, self.bytes.len(), whence);
+    }
+
+    fn tell(&self) -> uint {
+        *self.pos
     }
-    fn tell(&self) -> uint { self.pos }
 }
 
-pub fn with_bytes_reader<t>(bytes: &[u8], f: &fn(@Reader) -> t) -> t {
-    f(@BytesReader { bytes: bytes, pos: 0u } as @Reader)
+pub fn with_bytes_reader<T>(bytes: &[u8], f: &fn(@Reader) -> T) -> T {
+    f(@BytesReader {
+        bytes: bytes,
+        pos: @mut 0
+    } as @Reader)
 }
 
 pub fn with_str_reader<T>(s: &str, f: &fn(@Reader) -> T) -> T {
@@ -1186,7 +1200,7 @@ pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
     fn wb() -> c_int { O_WRONLY as c_int }
 
     let mut fflags: c_int = wb();
-    for vec::each(flags) |f| {
+    for flags.each |f| {
         match *f {
           Append => fflags |= O_APPEND as c_int,
           Create => fflags |= O_CREAT as c_int,
@@ -1498,49 +1512,70 @@ pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> {
 pub fn stdout() -> @Writer { fd_writer(libc::STDOUT_FILENO as c_int, false) }
 pub fn stderr() -> @Writer { fd_writer(libc::STDERR_FILENO as c_int, false) }
 
-pub fn print(s: &str) { stdout().write_str(s); }
-pub fn println(s: &str) { stdout().write_line(s); }
+pub fn print(s: &str) {
+    stdout().write_str(s);
+}
+
+pub fn println(s: &str) {
+    stdout().write_line(s);
+}
 
 pub struct BytesWriter {
-    mut bytes: ~[u8],
-    mut pos: uint,
+    bytes: @mut ~[u8],
+    pos: @mut uint,
 }
 
 impl Writer for BytesWriter {
     fn write(&self, v: &[u8]) {
         let v_len = v.len();
-        let bytes_len = vec::uniq_len(&const self.bytes);
 
-        let count = uint::max(bytes_len, self.pos + v_len);
-        vec::reserve(&mut self.bytes, count);
+        let bytes = &mut *self.bytes;
+        let count = uint::max(bytes.len(), *self.pos + v_len);
+        vec::reserve(bytes, count);
 
         unsafe {
-            vec::raw::set_len(&mut self.bytes, count);
-            let view = vec::mut_slice(self.bytes, self.pos, count);
+            // Silly stage0 borrow check workaround...
+            let casted: &mut ~[u8] = cast::transmute_copy(&bytes);
+            vec::raw::set_len(casted, count);
+
+            let view = vec::mut_slice(*bytes, *self.pos, count);
             vec::bytes::copy_memory(view, v, v_len);
         }
 
-        self.pos += v_len;
+        *self.pos += v_len;
     }
+
     fn seek(&self, offset: int, whence: SeekStyle) {
-        let pos = self.pos;
-        let len = vec::uniq_len(&const self.bytes);
-        self.pos = seek_in_buf(offset, pos, len, whence);
+        let pos = *self.pos;
+        let len = vec::uniq_len(&const *self.bytes);
+        *self.pos = seek_in_buf(offset, pos, len, whence);
+    }
+
+    fn tell(&self) -> uint {
+        *self.pos
+    }
+
+    fn flush(&self) -> int {
+        0
+    }
+
+    fn get_type(&self) -> WriterType {
+        File
     }
-    fn tell(&self) -> uint { self.pos }
-    fn flush(&self) -> int { 0 }
-    fn get_type(&self) -> WriterType { File }
 }
 
 pub fn BytesWriter() -> BytesWriter {
-    BytesWriter { bytes: ~[], mut pos: 0u }
+    BytesWriter {
+        bytes: @mut ~[],
+        pos: @mut 0
+    }
 }
 
 pub fn with_bytes_writer(f: &fn(@Writer)) -> ~[u8] {
     let wr = @BytesWriter();
     f(wr as @Writer);
-    let @BytesWriter{bytes, _} = wr;
-    return bytes;
+    let @BytesWriter { bytes, _ } = wr;
+    copy *bytes
 }
 
 pub fn with_str_writer(f: &fn(@Writer)) -> ~str {
@@ -1550,7 +1585,9 @@ pub fn with_str_writer(f: &fn(@Writer)) -> ~str {
     v.push(0);
     assert!(str::is_utf8(v));
 
-    unsafe { ::cast::transmute(v) }
+    unsafe {
+        ::cast::transmute(v)
+    }
 }
 
 // Utility functions
@@ -1849,15 +1886,15 @@ mod tests {
     fn bytes_buffer_overwrite() {
         let wr = BytesWriter();
         wr.write(~[0u8, 1u8, 2u8, 3u8]);
-        assert!(wr.bytes == ~[0u8, 1u8, 2u8, 3u8]);
+        assert!(*wr.bytes == ~[0u8, 1u8, 2u8, 3u8]);
         wr.seek(-2, SeekCur);
         wr.write(~[4u8, 5u8, 6u8, 7u8]);
-        assert!(wr.bytes == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]);
+        assert!(*wr.bytes == ~[0u8, 1u8, 4u8, 5u8, 6u8, 7u8]);
         wr.seek(-2, SeekEnd);
         wr.write(~[8u8]);
         wr.seek(1, SeekSet);
         wr.write(~[9u8]);
-        assert!(wr.bytes == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]);
+        assert!(*wr.bytes == ~[0u8, 9u8, 4u8, 5u8, 8u8, 7u8]);
     }
 
     #[test]
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 8fc2db6d6f1..b68d1158334 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -17,8 +17,7 @@ breaking out of iteration. The adaptors in the module work with any such iterato
 tied to specific traits. For example:
 
 ~~~~
-use core::iter::iter_to_vec;
-println(iter_to_vec(|f| uint::range(0, 20, f)).to_str());
+println(iter::to_vec(|f| uint::range(0, 20, f)).to_str());
 ~~~~
 
 An external iterator object implementing the interface in the `iterator` module can be used as an
@@ -55,12 +54,12 @@ pub trait Times {
  *
  * ~~~
  * let xs = ~[1, 2, 3];
- * let ys = do iter_to_vec |f| { xs.each(|x| f(*x)) };
+ * let ys = do iter::to_vec |f| { xs.each(|x| f(*x)) };
  * assert_eq!(xs, ys);
  * ~~~
  */
 #[inline(always)]
-pub fn iter_to_vec<T>(iter: &fn(f: &fn(T) -> bool)) -> ~[T] {
+pub fn to_vec<T>(iter: &fn(f: &fn(T) -> bool)) -> ~[T] {
     let mut v = ~[];
     for iter |x| { v.push(x) }
     v
@@ -185,9 +184,9 @@ mod tests {
     use prelude::*;
 
     #[test]
-    fn test_iter_to_vec() {
+    fn test_to_vec() {
         let xs = ~[1, 2, 3];
-        let ys = do iter_to_vec |f| { xs.each(|x| f(*x)) };
+        let ys = do to_vec |f| { xs.each(|x| f(*x)) };
         assert_eq!(xs, ys);
     }
 
diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs
index 5e95485b273..29dd4538aa2 100644
--- a/src/libcore/iterator.rs
+++ b/src/libcore/iterator.rs
@@ -378,7 +378,7 @@ mod tests {
     #[test]
     fn test_counter_to_vec() {
         let mut it = Counter::new(0, 5).take(10);
-        let xs = iter::iter_to_vec(|f| it.advance(f));
+        let xs = iter::to_vec(|f| it.advance(f));
         assert_eq!(xs, ~[0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
     }
 
diff --git a/src/libcore/logging.rs b/src/libcore/logging.rs
index afe8338f2ce..69ecad56a8f 100644
--- a/src/libcore/logging.rs
+++ b/src/libcore/logging.rs
@@ -42,7 +42,7 @@ pub fn console_off() {
     }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 #[lang="log_type"]
 pub fn log_type<T>(level: u32, object: &T) {
     use cast::transmute;
diff --git a/src/libcore/managed.rs b/src/libcore/managed.rs
index debca1ead82..d2bb88ca302 100644
--- a/src/libcore/managed.rs
+++ b/src/libcore/managed.rs
@@ -12,7 +12,7 @@
 
 use ptr::to_unsafe_ptr;
 
-#[cfg(notest)] use cmp::{Eq, Ord};
+#[cfg(not(test))] use cmp::{Eq, Ord};
 
 pub mod raw {
     use intrinsic::TyDesc;
@@ -49,7 +49,7 @@ pub fn mut_ptr_eq<T>(a: @mut T, b: @mut T) -> bool {
     a_ptr == b_ptr
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T:Eq> Eq for @T {
     #[inline(always)]
     fn eq(&self, other: &@T) -> bool { *(*self) == *(*other) }
@@ -57,7 +57,7 @@ impl<T:Eq> Eq for @T {
     fn ne(&self, other: &@T) -> bool { *(*self) != *(*other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T:Eq> Eq for @mut T {
     #[inline(always)]
     fn eq(&self, other: &@mut T) -> bool { *(*self) == *(*other) }
@@ -65,7 +65,7 @@ impl<T:Eq> Eq for @mut T {
     fn ne(&self, other: &@mut T) -> bool { *(*self) != *(*other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T:Ord> Ord for @T {
     #[inline(always)]
     fn lt(&self, other: &@T) -> bool { *(*self) < *(*other) }
@@ -77,7 +77,7 @@ impl<T:Ord> Ord for @T {
     fn gt(&self, other: &@T) -> bool { *(*self) > *(*other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T:Ord> Ord for @mut T {
     #[inline(always)]
     fn lt(&self, other: &@mut T) -> bool { *(*self) < *(*other) }
diff --git a/src/libcore/nil.rs b/src/libcore/nil.rs
index 6b8c390fc25..833bd3459ce 100644
--- a/src/libcore/nil.rs
+++ b/src/libcore/nil.rs
@@ -14,10 +14,10 @@ Functions for the unit type.
 
 */
 
-#[cfg(notest)]
+#[cfg(not(test))]
 use prelude::*;
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Eq for () {
     #[inline(always)]
     fn eq(&self, _other: &()) -> bool { true }
@@ -25,7 +25,7 @@ impl Eq for () {
     fn ne(&self, _other: &()) -> bool { false }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Ord for () {
     #[inline(always)]
     fn lt(&self, _other: &()) -> bool { false }
@@ -37,13 +37,13 @@ impl Ord for () {
     fn gt(&self, _other: &()) -> bool { false }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl TotalOrd for () {
     #[inline(always)]
     fn cmp(&self, _other: &()) -> Ordering { Equal }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl TotalEq for () {
     #[inline(always)]
     fn equals(&self, _other: &()) -> bool { true }
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 3c4faa95dd1..93e881c50e8 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -198,7 +198,7 @@ pub mod consts {
 
 impl Num for f32 {}
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Eq for f32 {
     #[inline(always)]
     fn eq(&self, other: &f32) -> bool { (*self) == (*other) }
@@ -206,7 +206,7 @@ impl Eq for f32 {
     fn ne(&self, other: &f32) -> bool { (*self) != (*other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl ApproxEq<f32> for f32 {
     #[inline(always)]
     fn approx_epsilon() -> f32 { 1.0e-6 }
@@ -222,7 +222,7 @@ impl ApproxEq<f32> for f32 {
     }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Ord for f32 {
     #[inline(always)]
     fn lt(&self, other: &f32) -> bool { (*self) < (*other) }
@@ -272,37 +272,37 @@ impl One for f32 {
     fn one() -> f32 { 1.0 }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Add<f32,f32> for f32 {
     #[inline(always)]
     fn add(&self, other: &f32) -> f32 { *self + *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Sub<f32,f32> for f32 {
     #[inline(always)]
     fn sub(&self, other: &f32) -> f32 { *self - *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Mul<f32,f32> for f32 {
     #[inline(always)]
     fn mul(&self, other: &f32) -> f32 { *self * *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Div<f32,f32> for f32 {
     #[inline(always)]
     fn div(&self, other: &f32) -> f32 { *self / *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Rem<f32,f32> for f32 {
     #[inline(always)]
     fn rem(&self, other: &f32) -> f32 { *self % *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Neg<f32> for f32 {
     #[inline(always)]
     fn neg(&self) -> f32 { -*self }
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 30c101fe8a9..096206d7183 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -221,7 +221,7 @@ pub mod consts {
 
 impl Num for f64 {}
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Eq for f64 {
     #[inline(always)]
     fn eq(&self, other: &f64) -> bool { (*self) == (*other) }
@@ -229,7 +229,7 @@ impl Eq for f64 {
     fn ne(&self, other: &f64) -> bool { (*self) != (*other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl ApproxEq<f64> for f64 {
     #[inline(always)]
     fn approx_epsilon() -> f64 { 1.0e-6 }
@@ -245,7 +245,7 @@ impl ApproxEq<f64> for f64 {
     }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Ord for f64 {
     #[inline(always)]
     fn lt(&self, other: &f64) -> bool { (*self) < (*other) }
@@ -295,28 +295,28 @@ impl One for f64 {
     fn one() -> f64 { 1.0 }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Add<f64,f64> for f64 {
     fn add(&self, other: &f64) -> f64 { *self + *other }
 }
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Sub<f64,f64> for f64 {
     fn sub(&self, other: &f64) -> f64 { *self - *other }
 }
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Mul<f64,f64> for f64 {
     fn mul(&self, other: &f64) -> f64 { *self * *other }
 }
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Div<f64,f64> for f64 {
     fn div(&self, other: &f64) -> f64 { *self / *other }
 }
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Rem<f64,f64> for f64 {
     #[inline(always)]
     fn rem(&self, other: &f64) -> f64 { *self % *other }
 }
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Neg<f64> for f64 {
     fn neg(&self) -> f64 { -*self }
 }
diff --git a/src/libcore/num/float.rs b/src/libcore/num/float.rs
index 9c3d30be0d4..e6a2ed7ea97 100644
--- a/src/libcore/num/float.rs
+++ b/src/libcore/num/float.rs
@@ -363,7 +363,7 @@ pub fn tan(x: float) -> float {
 
 impl Num for float {}
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Eq for float {
     #[inline(always)]
     fn eq(&self, other: &float) -> bool { (*self) == (*other) }
@@ -371,7 +371,7 @@ impl Eq for float {
     fn ne(&self, other: &float) -> bool { (*self) != (*other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl ApproxEq<float> for float {
     #[inline(always)]
     fn approx_epsilon() -> float { 1.0e-6 }
@@ -387,7 +387,7 @@ impl ApproxEq<float> for float {
     }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Ord for float {
     #[inline(always)]
     fn lt(&self, other: &float) -> bool { (*self) < (*other) }
@@ -695,36 +695,36 @@ impl RealExt for float {
     fn yn(&self, n: int) -> float { yn(n as c_int, *self as f64) as float }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Add<float,float> for float {
     #[inline(always)]
     fn add(&self, other: &float) -> float { *self + *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Sub<float,float> for float {
     #[inline(always)]
     fn sub(&self, other: &float) -> float { *self - *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Mul<float,float> for float {
     #[inline(always)]
     fn mul(&self, other: &float) -> float { *self * *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Div<float,float> for float {
     #[inline(always)]
     fn div(&self, other: &float) -> float { *self / *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Rem<float,float> for float {
     #[inline(always)]
     fn rem(&self, other: &float) -> float { *self % *other }
 }
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Neg<float> for float {
     #[inline(always)]
     fn neg(&self) -> float { -*self }
diff --git a/src/libcore/num/int-template.rs b/src/libcore/num/int-template.rs
index 06a9a0b4562..9ee5ba4753d 100644
--- a/src/libcore/num/int-template.rs
+++ b/src/libcore/num/int-template.rs
@@ -131,7 +131,7 @@ pub fn abs(i: T) -> T { i.abs() }
 
 impl Num for T {}
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Ord for T {
     #[inline(always)]
     fn lt(&self, other: &T) -> bool { return (*self) < (*other); }
@@ -143,7 +143,7 @@ impl Ord for T {
     fn gt(&self, other: &T) -> bool { return (*self) > (*other); }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Eq for T {
     #[inline(always)]
     fn eq(&self, other: &T) -> bool { return (*self) == (*other); }
@@ -182,25 +182,25 @@ impl One for T {
     fn one() -> T { 1 }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Add<T,T> for T {
     #[inline(always)]
     fn add(&self, other: &T) -> T { *self + *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Sub<T,T> for T {
     #[inline(always)]
     fn sub(&self, other: &T) -> T { *self - *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Mul<T,T> for T {
     #[inline(always)]
     fn mul(&self, other: &T) -> T { *self * *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Div<T,T> for T {
     ///
     /// Integer division, truncated towards 0. As this behaviour reflects the underlying
@@ -224,7 +224,7 @@ impl Div<T,T> for T {
     fn div(&self, other: &T) -> T { *self / *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Rem<T,T> for T {
     ///
     /// Returns the integer remainder after division, satisfying:
@@ -251,7 +251,7 @@ impl Rem<T,T> for T {
     fn rem(&self, other: &T) -> T { *self % *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Neg<T> for T {
     #[inline(always)]
     fn neg(&self) -> T { -*self }
@@ -417,37 +417,37 @@ impl Integer for T {
 
 impl Bitwise for T {}
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl BitOr<T,T> for T {
     #[inline(always)]
     fn bitor(&self, other: &T) -> T { *self | *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl BitAnd<T,T> for T {
     #[inline(always)]
     fn bitand(&self, other: &T) -> T { *self & *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl BitXor<T,T> for T {
     #[inline(always)]
     fn bitxor(&self, other: &T) -> T { *self ^ *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Shl<T,T> for T {
     #[inline(always)]
     fn shl(&self, other: &T) -> T { *self << *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Shr<T,T> for T {
     #[inline(always)]
     fn shr(&self, other: &T) -> T { *self >> *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Not<T> for T {
     #[inline(always)]
     fn not(&self) -> T { !*self }
diff --git a/src/libcore/num/uint-template.rs b/src/libcore/num/uint-template.rs
index 6d0f1fe1fc7..dcb0865cb9b 100644
--- a/src/libcore/num/uint-template.rs
+++ b/src/libcore/num/uint-template.rs
@@ -96,7 +96,7 @@ pub fn compl(i: T) -> T {
 
 impl Num for T {}
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Ord for T {
     #[inline(always)]
     fn lt(&self, other: &T) -> bool { (*self) < (*other) }
@@ -108,7 +108,7 @@ impl Ord for T {
     fn gt(&self, other: &T) -> bool { (*self) > (*other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Eq for T {
     #[inline(always)]
     fn eq(&self, other: &T) -> bool { return (*self) == (*other); }
@@ -147,37 +147,37 @@ impl One for T {
     fn one() -> T { 1 }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Add<T,T> for T {
     #[inline(always)]
     fn add(&self, other: &T) -> T { *self + *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Sub<T,T> for T {
     #[inline(always)]
     fn sub(&self, other: &T) -> T { *self - *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Mul<T,T> for T {
     #[inline(always)]
     fn mul(&self, other: &T) -> T { *self * *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Div<T,T> for T {
     #[inline(always)]
     fn div(&self, other: &T) -> T { *self / *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Rem<T,T> for T {
     #[inline(always)]
     fn rem(&self, other: &T) -> T { *self % *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Neg<T> for T {
     #[inline(always)]
     fn neg(&self) -> T { -*self }
@@ -240,37 +240,37 @@ impl Integer for T {
 
 impl Bitwise for T {}
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl BitOr<T,T> for T {
     #[inline(always)]
     fn bitor(&self, other: &T) -> T { *self | *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl BitAnd<T,T> for T {
     #[inline(always)]
     fn bitand(&self, other: &T) -> T { *self & *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl BitXor<T,T> for T {
     #[inline(always)]
     fn bitxor(&self, other: &T) -> T { *self ^ *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Shl<T,T> for T {
     #[inline(always)]
     fn shl(&self, other: &T) -> T { *self << *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Shr<T,T> for T {
     #[inline(always)]
     fn shr(&self, other: &T) -> T { *self >> *other }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Not<T> for T {
     #[inline(always)]
     fn not(&self) -> T { !*self }
diff --git a/src/libcore/os.rs b/src/libcore/os.rs
index 42c77a687e5..574618026d9 100644
--- a/src/libcore/os.rs
+++ b/src/libcore/os.rs
@@ -352,7 +352,10 @@ pub fn fsync_fd(fd: c_int, _l: io::fsync::Level) -> c_int {
     }
 }
 
-pub struct Pipe { in: c_int, out: c_int }
+pub struct Pipe {
+    in: c_int,
+    out: c_int
+}
 
 #[cfg(unix)]
 pub fn pipe() -> Pipe {
@@ -1432,7 +1435,7 @@ mod tests {
     }
 
     fn make_rand_name() -> ~str {
-        let rng = rand::rng();
+        let mut rng = rand::rng();
         let n = ~"TEST" + rng.gen_str(10u);
         assert!(getenv(n).is_none());
         n
@@ -1488,7 +1491,7 @@ mod tests {
     fn test_env_getenv() {
         let e = env();
         assert!(vec::len(e) > 0u);
-        for vec::each(e) |p| {
+        for e.each |p| {
             let (n, v) = copy *p;
             debug!(copy n);
             let v2 = getenv(n);
@@ -1580,7 +1583,7 @@ mod tests {
         // Just assuming that we've got some contents in the current directory
         assert!((vec::len(dirs) > 0u));
 
-        for vec::each(dirs) |dir| {
+        for dirs.each |dir| {
             debug!(copy *dir);
         }
     }
diff --git a/src/libcore/owned.rs b/src/libcore/owned.rs
index 599591e2f6d..3262fb4afdc 100644
--- a/src/libcore/owned.rs
+++ b/src/libcore/owned.rs
@@ -10,9 +10,9 @@
 
 //! Operations on unique pointer types
 
-#[cfg(notest)] use cmp::{Eq, Ord};
+#[cfg(not(test))] use cmp::{Eq, Ord};
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T:Eq> Eq for ~T {
     #[inline(always)]
     fn eq(&self, other: &~T) -> bool { *(*self) == *(*other) }
@@ -20,7 +20,7 @@ impl<T:Eq> Eq for ~T {
     fn ne(&self, other: &~T) -> bool { *(*self) != *(*other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T:Ord> Ord for ~T {
     #[inline(always)]
     fn lt(&self, other: &~T) -> bool { *(*self) < *(*other) }
diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs
index 19674900f90..8301254fbdd 100644
--- a/src/libcore/pipes.rs
+++ b/src/libcore/pipes.rs
@@ -111,7 +111,7 @@ enum State {
 pub struct BufferHeader {
     // Tracks whether this buffer needs to be freed. We can probably
     // get away with restricting it to 0 or 1, if we're careful.
-    mut ref_count: int,
+    ref_count: int,
 
     // We may want a drop, and to be careful about stringing this
     // thing along.
@@ -130,12 +130,12 @@ pub struct Buffer<T> {
 }
 
 pub struct PacketHeader {
-    mut state: State,
-    mut blocked_task: *rust_task,
+    state: State,
+    blocked_task: *rust_task,
 
     // This is a transmute_copy of a ~buffer, that can also be cast
     // to a buffer_header if need be.
-    mut buffer: *libc::c_void,
+    buffer: *libc::c_void,
 }
 
 pub fn PacketHeader() -> PacketHeader {
@@ -148,14 +148,14 @@ pub fn PacketHeader() -> PacketHeader {
 
 pub impl PacketHeader {
     // Returns the old state.
-    unsafe fn mark_blocked(&self, this: *rust_task) -> State {
+    unsafe fn mark_blocked(&mut self, this: *rust_task) -> State {
         rustrt::rust_task_ref(this);
         let old_task = swap_task(&mut self.blocked_task, this);
         assert!(old_task.is_null());
         swap_state_acq(&mut self.state, Blocked)
     }
 
-    unsafe fn unblock(&self) {
+    unsafe fn unblock(&mut self) {
         let old_task = swap_task(&mut self.blocked_task, ptr::null());
         if !old_task.is_null() {
             rustrt::rust_task_deref(old_task)
@@ -169,13 +169,13 @@ pub impl PacketHeader {
 
     // unsafe because this can do weird things to the space/time
     // continuum. It ends making multiple unique pointers to the same
-    // thing. You'll proobably want to forget them when you're done.
-    unsafe fn buf_header(&self) -> ~BufferHeader {
+    // thing. You'll probably want to forget them when you're done.
+    unsafe fn buf_header(&mut self) -> ~BufferHeader {
         assert!(self.buffer.is_not_null());
         transmute_copy(&self.buffer)
     }
 
-    fn set_buffer<T:Owned>(&self, b: ~Buffer<T>) {
+    fn set_buffer<T:Owned>(&mut self, b: ~Buffer<T>) {
         unsafe {
             self.buffer = transmute_copy(&b);
         }
@@ -184,15 +184,15 @@ pub impl PacketHeader {
 
 pub struct Packet<T> {
     header: PacketHeader,
-    mut payload: Option<T>,
+    payload: Option<T>,
 }
 
 pub trait HasBuffer {
-    fn set_buffer(&self, b: *libc::c_void);
+    fn set_buffer(&mut self, b: *libc::c_void);
 }
 
 impl<T:Owned> HasBuffer for Packet<T> {
-    fn set_buffer(&self, b: *libc::c_void) {
+    fn set_buffer(&mut self, b: *libc::c_void) {
         self.header.buffer = b;
     }
 }
@@ -204,7 +204,7 @@ pub fn mk_packet<T:Owned>() -> Packet<T> {
     }
 }
 fn unibuffer<T>() -> ~Buffer<Packet<T>> {
-    let b = ~Buffer {
+    let mut b = ~Buffer {
         header: BufferHeader(),
         data: Packet {
             header: PacketHeader(),
@@ -218,22 +218,25 @@ fn unibuffer<T>() -> ~Buffer<Packet<T>> {
     b
 }
 
-pub fn packet<T>() -> *Packet<T> {
-    let b = unibuffer();
-    let p = ptr::to_unsafe_ptr(&(b.data));
+pub fn packet<T>() -> *mut Packet<T> {
+    let mut b = unibuffer();
+    let p = ptr::to_mut_unsafe_ptr(&mut b.data);
     // We'll take over memory management from here.
-    unsafe { forget(b) }
+    unsafe {
+        forget(b);
+    }
     p
 }
 
 pub fn entangle_buffer<T:Owned,Tstart:Owned>(
-    buffer: ~Buffer<T>,
-    init: &fn(*libc::c_void, x: &T) -> *Packet<Tstart>)
-    -> (SendPacketBuffered<Tstart, T>, RecvPacketBuffered<Tstart, T>)
-{
-    let p = init(unsafe { transmute_copy(&buffer) }, &buffer.data);
-    unsafe { forget(buffer) }
-    (SendPacketBuffered(p), RecvPacketBuffered(p))
+    mut buffer: ~Buffer<T>,
+    init: &fn(*libc::c_void, x: &mut T) -> *mut Packet<Tstart>)
+    -> (SendPacketBuffered<Tstart, T>, RecvPacketBuffered<Tstart, T>) {
+    unsafe {
+        let p = init(transmute_copy(&buffer), &mut buffer.data);
+        forget(buffer);
+        (SendPacketBuffered(p), RecvPacketBuffered(p))
+    }
 }
 
 pub fn swap_task(dst: &mut *rust_task, src: *rust_task) -> *rust_task {
@@ -292,7 +295,7 @@ fn swap_state_rel(dst: &mut State, src: State) -> State {
     }
 }
 
-pub unsafe fn get_buffer<T>(p: *PacketHeader) -> ~Buffer<T> {
+pub unsafe fn get_buffer<T>(p: *mut PacketHeader) -> ~Buffer<T> {
     transmute((*p).buf_header())
 }
 
@@ -306,10 +309,14 @@ struct BufferResource<T> {
 impl<T> Drop for BufferResource<T> {
     fn finalize(&self) {
         unsafe {
-            let b = move_it!(self.buffer);
+            let this: &mut BufferResource<T> = transmute(self);
+
+            let mut b = move_it!(this.buffer);
             //let p = ptr::to_unsafe_ptr(*b);
             //error!("drop %?", p);
-            let old_count = intrinsics::atomic_xsub_rel(&mut b.header.ref_count, 1);
+            let old_count = intrinsics::atomic_xsub_rel(
+                &mut b.header.ref_count,
+                1);
             //let old_count = atomic_xchng_rel(b.header.ref_count, 0);
             if old_count == 1 {
                 // The new count is 0.
@@ -323,10 +330,12 @@ impl<T> Drop for BufferResource<T> {
     }
 }
 
-fn BufferResource<T>(b: ~Buffer<T>) -> BufferResource<T> {
+fn BufferResource<T>(mut b: ~Buffer<T>) -> BufferResource<T> {
     //let p = ptr::to_unsafe_ptr(*b);
     //error!("take %?", p);
-    unsafe { intrinsics::atomic_xadd_acq(&mut b.header.ref_count, 1) };
+    unsafe {
+        intrinsics::atomic_xadd_acq(&mut b.header.ref_count, 1);
+    }
 
     BufferResource {
         // tjc: ????
@@ -334,10 +343,12 @@ fn BufferResource<T>(b: ~Buffer<T>) -> BufferResource<T> {
     }
 }
 
-pub fn send<T,Tbuffer>(p: SendPacketBuffered<T,Tbuffer>, payload: T) -> bool {
+pub fn send<T,Tbuffer>(mut p: SendPacketBuffered<T,Tbuffer>,
+                       payload: T)
+                       -> bool {
     let header = p.header();
-    let p_ = p.unwrap();
-    let p = unsafe { &*p_ };
+    let mut p_ = p.unwrap();
+    let p = unsafe { &mut *p_ };
     assert!(ptr::to_unsafe_ptr(&(p.header)) == header);
     assert!(p.payload.is_none());
     p.payload = Some(payload);
@@ -391,11 +402,12 @@ Returns `None` if the sender has closed the connection without sending
 a message, or `Some(T)` if a message was received.
 
 */
-pub fn try_recv<T:Owned,Tbuffer:Owned>(p: RecvPacketBuffered<T, Tbuffer>)
-    -> Option<T>
-{
-    let p_ = p.unwrap();
-    let p = unsafe { &*p_ };
+pub fn try_recv<T:Owned,Tbuffer:Owned>(mut p: RecvPacketBuffered<T, Tbuffer>)
+                                       -> Option<T> {
+    let mut p_ = p.unwrap();
+    let mut p = unsafe {
+        &mut *p_
+    };
 
     do (|| {
         try_recv_(p)
@@ -412,7 +424,7 @@ pub fn try_recv<T:Owned,Tbuffer:Owned>(p: RecvPacketBuffered<T, Tbuffer>)
     }
 }
 
-fn try_recv_<T:Owned>(p: &Packet<T>) -> Option<T> {
+fn try_recv_<T:Owned>(p: &mut Packet<T>) -> Option<T> {
     // optimistic path
     match p.header.state {
       Full => {
@@ -498,16 +510,20 @@ fn try_recv_<T:Owned>(p: &Packet<T>) -> Option<T> {
 }
 
 /// Returns true if messages are available.
-pub fn peek<T:Owned,Tb:Owned>(p: &RecvPacketBuffered<T, Tb>) -> bool {
-    match unsafe {(*p.header()).state} {
-      Empty | Terminated => false,
-      Blocked => fail!(~"peeking on blocked packet"),
-      Full => true
+pub fn peek<T:Owned,Tb:Owned>(p: &mut RecvPacketBuffered<T, Tb>) -> bool {
+    unsafe {
+        match (*p.header()).state {
+            Empty | Terminated => false,
+            Blocked => fail!(~"peeking on blocked packet"),
+            Full => true
+        }
     }
 }
 
-fn sender_terminate<T:Owned>(p: *Packet<T>) {
-    let p = unsafe { &*p };
+fn sender_terminate<T:Owned>(p: *mut Packet<T>) {
+    let p = unsafe {
+        &mut *p
+    };
     match swap_state_rel(&mut p.header.state, Terminated) {
       Empty => {
         // The receiver will eventually clean up.
@@ -536,8 +552,10 @@ fn sender_terminate<T:Owned>(p: *Packet<T>) {
     }
 }
 
-fn receiver_terminate<T:Owned>(p: *Packet<T>) {
-    let p = unsafe { &*p };
+fn receiver_terminate<T:Owned>(p: *mut Packet<T>) {
+    let p = unsafe {
+        &mut *p
+    };
     match swap_state_rel(&mut p.header.state, Terminated) {
       Empty => {
         assert!(p.header.blocked_task.is_null());
@@ -569,8 +587,10 @@ that vector. The index points to an endpoint that has either been
 closed by the sender or has a message waiting to be received.
 
 */
-pub fn wait_many<T: Selectable>(pkts: &[T]) -> uint {
-    let this = unsafe { rustrt::rust_get_task() };
+pub fn wait_many<T: Selectable>(pkts: &mut [T]) -> uint {
+    let this = unsafe {
+        rustrt::rust_get_task()
+    };
 
     unsafe {
         rustrt::task_clear_event_reject(this);
@@ -578,19 +598,19 @@ pub fn wait_many<T: Selectable>(pkts: &[T]) -> uint {
 
     let mut data_avail = false;
     let mut ready_packet = pkts.len();
-    for pkts.eachi |i, p| {
+    for vec::eachi_mut(pkts) |i, p| {
         unsafe {
-            let p = &*p.header();
+            let p = &mut *p.header();
             let old = p.mark_blocked(this);
             match old {
-              Full | Terminated => {
-                data_avail = true;
-                ready_packet = i;
-                (*p).state = old;
-                break;
-              }
-              Blocked => fail!(~"blocking on blocked packet"),
-              Empty => ()
+                Full | Terminated => {
+                    data_avail = true;
+                    ready_packet = i;
+                    (*p).state = old;
+                    break;
+                }
+                Blocked => fail!(~"blocking on blocked packet"),
+                Empty => ()
             }
         }
     }
@@ -598,7 +618,14 @@ pub fn wait_many<T: Selectable>(pkts: &[T]) -> uint {
     while !data_avail {
         debug!("sleeping on %? packets", pkts.len());
         let event = wait_event(this) as *PacketHeader;
-        let pos = vec::position(pkts, |p| p.header() == event);
+
+        let mut pos = None;
+        for vec::eachi_mut(pkts) |i, p| {
+            if p.header() == event {
+                pos = Some(i);
+                break;
+            }
+        };
 
         match pos {
           Some(i) => {
@@ -609,11 +636,15 @@ pub fn wait_many<T: Selectable>(pkts: &[T]) -> uint {
         }
     }
 
-    debug!("%?", pkts[ready_packet]);
+    debug!("%?", &mut pkts[ready_packet]);
 
-    for pkts.each |p| { unsafe{ (*p.header()).unblock()} }
+    for vec::each_mut(pkts) |p| {
+        unsafe {
+            (*p.header()).unblock()
+        }
+    }
 
-    debug!("%?, %?", ready_packet, pkts[ready_packet]);
+    debug!("%?, %?", ready_packet, &mut pkts[ready_packet]);
 
     unsafe {
         assert!((*pkts[ready_packet].header()).state == Full
@@ -629,65 +660,58 @@ message.
 */
 pub type SendPacket<T> = SendPacketBuffered<T, Packet<T>>;
 
-pub fn SendPacket<T>(p: *Packet<T>) -> SendPacket<T> {
+pub fn SendPacket<T>(p: *mut Packet<T>) -> SendPacket<T> {
     SendPacketBuffered(p)
 }
 
 pub struct SendPacketBuffered<T, Tbuffer> {
-    mut p: Option<*Packet<T>>,
-    mut buffer: Option<BufferResource<Tbuffer>>,
+    p: Option<*mut Packet<T>>,
+    buffer: Option<BufferResource<Tbuffer>>,
 }
 
 #[unsafe_destructor]
 impl<T:Owned,Tbuffer:Owned> Drop for SendPacketBuffered<T,Tbuffer> {
     fn finalize(&self) {
-        //if self.p != none {
-        //    debug!("drop send %?", option::get(self.p));
-        //}
-        if self.p != None {
-            let mut p = None;
-            p <-> self.p;
-            sender_terminate(p.unwrap())
+        unsafe {
+            let this: &mut SendPacketBuffered<T,Tbuffer> = transmute(self);
+            if this.p != None {
+                let mut p = None;
+                p <-> this.p;
+                sender_terminate(p.unwrap())
+            }
         }
-        //unsafe { error!("send_drop: %?",
-        //                if self.buffer == none {
-        //                    "none"
-        //                } else { "some" }); }
     }
 }
 
-pub fn SendPacketBuffered<T,Tbuffer>(p: *Packet<T>)
-    -> SendPacketBuffered<T, Tbuffer> {
-        //debug!("take send %?", p);
+pub fn SendPacketBuffered<T,Tbuffer>(p: *mut Packet<T>)
+                                     -> SendPacketBuffered<T,Tbuffer> {
     SendPacketBuffered {
         p: Some(p),
         buffer: unsafe {
-            Some(BufferResource(
-                get_buffer(ptr::to_unsafe_ptr(&((*p).header)))))
+            Some(BufferResource(get_buffer(&mut (*p).header)))
         }
     }
 }
 
 pub impl<T,Tbuffer> SendPacketBuffered<T,Tbuffer> {
-    fn unwrap(&self) -> *Packet<T> {
+    fn unwrap(&mut self) -> *mut Packet<T> {
         let mut p = None;
         p <-> self.p;
         p.unwrap()
     }
 
-    fn header(&self) -> *PacketHeader {
+    fn header(&mut self) -> *mut PacketHeader {
         match self.p {
-          Some(packet) => unsafe {
-            let packet = &*packet;
-            let header = ptr::to_unsafe_ptr(&(packet.header));
-            //forget(packet);
-            header
-          },
-          None => fail!(~"packet already consumed")
+            Some(packet) => unsafe {
+                let packet = &mut *packet;
+                let header = ptr::to_mut_unsafe_ptr(&mut packet.header);
+                header
+            },
+            None => fail!(~"packet already consumed")
         }
     }
 
-    fn reuse_buffer(&self) -> BufferResource<Tbuffer> {
+    fn reuse_buffer(&mut self) -> BufferResource<Tbuffer> {
         //error!("send reuse_buffer");
         let mut tmp = None;
         tmp <-> self.buffer;
@@ -699,41 +723,37 @@ pub impl<T,Tbuffer> SendPacketBuffered<T,Tbuffer> {
 /// message.
 pub type RecvPacket<T> = RecvPacketBuffered<T, Packet<T>>;
 
-pub fn RecvPacket<T>(p: *Packet<T>) -> RecvPacket<T> {
+pub fn RecvPacket<T>(p: *mut Packet<T>) -> RecvPacket<T> {
     RecvPacketBuffered(p)
 }
+
 pub struct RecvPacketBuffered<T, Tbuffer> {
-    mut p: Option<*Packet<T>>,
-    mut buffer: Option<BufferResource<Tbuffer>>,
+    p: Option<*mut Packet<T>>,
+    buffer: Option<BufferResource<Tbuffer>>,
 }
 
 #[unsafe_destructor]
 impl<T:Owned,Tbuffer:Owned> Drop for RecvPacketBuffered<T,Tbuffer> {
     fn finalize(&self) {
-        //if self.p != none {
-        //    debug!("drop recv %?", option::get(self.p));
-        //}
-        if self.p != None {
-            let mut p = None;
-            p <-> self.p;
-            receiver_terminate(p.unwrap())
+        unsafe {
+            let this: &mut RecvPacketBuffered<T,Tbuffer> = transmute(self);
+            if this.p != None {
+                let mut p = None;
+                p <-> this.p;
+                receiver_terminate(p.unwrap())
+            }
         }
-        //unsafe { error!("recv_drop: %?",
-        //                if self.buffer == none {
-        //                    "none"
-        //                } else { "some" }); }
     }
 }
 
 pub impl<T:Owned,Tbuffer:Owned> RecvPacketBuffered<T, Tbuffer> {
-    fn unwrap(&self) -> *Packet<T> {
+    fn unwrap(&mut self) -> *mut Packet<T> {
         let mut p = None;
         p <-> self.p;
         p.unwrap()
     }
 
-    fn reuse_buffer(&self) -> BufferResource<Tbuffer> {
-        //error!("recv reuse_buffer");
+    fn reuse_buffer(&mut self) -> BufferResource<Tbuffer> {
         let mut tmp = None;
         tmp <-> self.buffer;
         tmp.unwrap()
@@ -741,27 +761,24 @@ pub impl<T:Owned,Tbuffer:Owned> RecvPacketBuffered<T, Tbuffer> {
 }
 
 impl<T:Owned,Tbuffer:Owned> Selectable for RecvPacketBuffered<T, Tbuffer> {
-    fn header(&self) -> *PacketHeader {
+    fn header(&mut self) -> *mut PacketHeader {
         match self.p {
-          Some(packet) => unsafe {
-            let packet = &*packet;
-            let header = ptr::to_unsafe_ptr(&(packet.header));
-            //forget(packet);
-            header
-          },
-          None => fail!(~"packet already consumed")
+            Some(packet) => unsafe {
+                let packet = &mut *packet;
+                let header = ptr::to_mut_unsafe_ptr(&mut packet.header);
+                header
+            },
+            None => fail!(~"packet already consumed")
         }
     }
 }
 
-pub fn RecvPacketBuffered<T,Tbuffer>(p: *Packet<T>)
-    -> RecvPacketBuffered<T,Tbuffer> {
-    //debug!("take recv %?", p);
+pub fn RecvPacketBuffered<T,Tbuffer>(p: *mut Packet<T>)
+                                     -> RecvPacketBuffered<T,Tbuffer> {
     RecvPacketBuffered {
         p: Some(p),
         buffer: unsafe {
-            Some(BufferResource(
-                get_buffer(ptr::to_unsafe_ptr(&((*p).header)))))
+            Some(BufferResource(get_buffer(&mut (*p).header)))
         }
     }
 }
@@ -800,51 +817,55 @@ this case, `select2` may return either `left` or `right`.
 
 */
 pub fn select2<A:Owned,Ab:Owned,B:Owned,Bb:Owned>(
-    a: RecvPacketBuffered<A, Ab>,
-    b: RecvPacketBuffered<B, Bb>)
+    mut a: RecvPacketBuffered<A, Ab>,
+    mut b: RecvPacketBuffered<B, Bb>)
     -> Either<(Option<A>, RecvPacketBuffered<B, Bb>),
-              (RecvPacketBuffered<A, Ab>, Option<B>)>
-{
-    let i = wait_many([a.header(), b.header()]);
-
+              (RecvPacketBuffered<A, Ab>, Option<B>)> {
+    let mut endpoints = [ a.header(), b.header() ];
+    let i = wait_many(endpoints);
     match i {
-      0 => Left((try_recv(a), b)),
-      1 => Right((a, try_recv(b))),
-      _ => fail!(~"select2 return an invalid packet")
+        0 => Left((try_recv(a), b)),
+        1 => Right((a, try_recv(b))),
+        _ => fail!(~"select2 return an invalid packet")
     }
 }
 
 pub trait Selectable {
-    fn header(&self) -> *PacketHeader;
+    fn header(&mut self) -> *mut PacketHeader;
 }
 
-impl Selectable for *PacketHeader {
-    fn header(&self) -> *PacketHeader { *self }
+impl Selectable for *mut PacketHeader {
+    fn header(&mut self) -> *mut PacketHeader { *self }
 }
 
 /// Returns the index of an endpoint that is ready to receive.
-pub fn selecti<T:Selectable>(endpoints: &[T]) -> uint {
+pub fn selecti<T:Selectable>(endpoints: &mut [T]) -> uint {
     wait_many(endpoints)
 }
 
 /// Returns 0 or 1 depending on which endpoint is ready to receive
-pub fn select2i<A:Selectable,B:Selectable>(a: &A, b: &B) ->
-        Either<(), ()> {
-    match wait_many([a.header(), b.header()]) {
-      0 => Left(()),
-      1 => Right(()),
-      _ => fail!(~"wait returned unexpected index")
+pub fn select2i<A:Selectable,B:Selectable>(a: &mut A, b: &mut B)
+                                           -> Either<(), ()> {
+    let mut endpoints = [ a.header(), b.header() ];
+    match wait_many(endpoints) {
+        0 => Left(()),
+        1 => Right(()),
+        _ => fail!(~"wait returned unexpected index")
     }
 }
 
-/** Waits on a set of endpoints. Returns a message, its index, and a
- list of the remaining endpoints.
+/// Waits on a set of endpoints. Returns a message, its index, and a
+/// list of the remaining endpoints.
+pub fn select<T:Owned,Tb:Owned>(mut endpoints: ~[RecvPacketBuffered<T, Tb>])
+                                -> (uint,
+                                    Option<T>,
+                                    ~[RecvPacketBuffered<T, Tb>]) {
+    let mut endpoint_headers = ~[];
+    for vec::each_mut(endpoints) |endpoint| {
+        endpoint_headers.push(endpoint.header());
+    }
 
-*/
-pub fn select<T:Owned,Tb:Owned>(endpoints: ~[RecvPacketBuffered<T, Tb>])
-    -> (uint, Option<T>, ~[RecvPacketBuffered<T, Tb>])
-{
-    let ready = wait_many(endpoints.map(|p| p.header()));
+    let ready = wait_many(endpoint_headers);
     let mut remaining = endpoints;
     let port = remaining.swap_remove(ready);
     let result = try_recv(port);
@@ -873,9 +894,10 @@ mod test {
 
         c1.send(~"abc");
 
-        match (p1, p2).select() {
-          Right(_) => fail!(),
-          _ => ()
+        let mut tuple = (p1, p2);
+        match tuple.select() {
+            Right(_) => fail!(),
+            _ => (),
         }
 
         c2.send(123);
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index 85e46a0feff..77e4143d090 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -15,7 +15,7 @@ use libc;
 use libc::{c_void, size_t};
 use sys;
 
-#[cfg(notest)] use cmp::{Eq, Ord};
+#[cfg(not(test))] use cmp::{Eq, Ord};
 use uint;
 
 pub mod libc_ {
@@ -243,7 +243,7 @@ impl<T> Ptr<T> for *mut T {
 }
 
 // Equality for pointers
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T> Eq for *const T {
     #[inline(always)]
     fn eq(&self, other: &*const T) -> bool {
@@ -258,7 +258,7 @@ impl<T> Eq for *const T {
 }
 
 // Comparison for pointers
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T> Ord for *const T {
     #[inline(always)]
     fn lt(&self, other: &*const T) -> bool {
@@ -295,7 +295,7 @@ impl<T> Ord for *const T {
 }
 
 // Equality for region pointers
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<'self,T:Eq> Eq for &'self T {
     #[inline(always)]
     fn eq(&self, other: & &'self T) -> bool {
@@ -308,7 +308,7 @@ impl<'self,T:Eq> Eq for &'self T {
 }
 
 // Comparison for region pointers
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<'self,T:Ord> Ord for &'self T {
     #[inline(always)]
     fn lt(&self, other: & &'self T) -> bool {
@@ -336,7 +336,10 @@ pub mod ptr_tests {
     #[test]
     fn test() {
         unsafe {
-            struct Pair {mut fst: int, mut snd: int};
+            struct Pair {
+                fst: int,
+                snd: int
+            };
             let mut p = Pair {fst: 10, snd: 20};
             let pptr: *mut Pair = &mut p;
             let iptr: *mut int = cast::transmute(pptr);
diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs
index 80f69f067eb..f11840c95d5 100644
--- a/src/libcore/rand.rs
+++ b/src/libcore/rand.rs
@@ -55,12 +55,12 @@ pub mod distributions;
 
 /// A type that can be randomly generated using an Rng
 pub trait Rand {
-    fn rand<R: Rng>(rng: &R) -> Self;
+    fn rand<R: Rng>(rng: &mut R) -> Self;
 }
 
 impl Rand for int {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> int {
+    fn rand<R: Rng>(rng: &mut R) -> int {
         if int::bits == 32 {
             rng.next() as int
         } else {
@@ -71,35 +71,35 @@ impl Rand for int {
 
 impl Rand for i8 {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> i8 {
+    fn rand<R: Rng>(rng: &mut R) -> i8 {
         rng.next() as i8
     }
 }
 
 impl Rand for i16 {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> i16 {
+    fn rand<R: Rng>(rng: &mut R) -> i16 {
         rng.next() as i16
     }
 }
 
 impl Rand for i32 {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> i32 {
+    fn rand<R: Rng>(rng: &mut R) -> i32 {
         rng.next() as i32
     }
 }
 
 impl Rand for i64 {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> i64 {
+    fn rand<R: Rng>(rng: &mut R) -> i64 {
         (rng.next() as i64 << 32) | rng.next() as i64
     }
 }
 
 impl Rand for uint {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> uint {
+    fn rand<R: Rng>(rng: &mut R) -> uint {
         if uint::bits == 32 {
             rng.next() as uint
         } else {
@@ -110,42 +110,42 @@ impl Rand for uint {
 
 impl Rand for u8 {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> u8 {
+    fn rand<R: Rng>(rng: &mut R) -> u8 {
         rng.next() as u8
     }
 }
 
 impl Rand for u16 {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> u16 {
+    fn rand<R: Rng>(rng: &mut R) -> u16 {
         rng.next() as u16
     }
 }
 
 impl Rand for u32 {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> u32 {
+    fn rand<R: Rng>(rng: &mut R) -> u32 {
         rng.next()
     }
 }
 
 impl Rand for u64 {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> u64 {
+    fn rand<R: Rng>(rng: &mut R) -> u64 {
         (rng.next() as u64 << 32) | rng.next() as u64
     }
 }
 
 impl Rand for float {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> float {
+    fn rand<R: Rng>(rng: &mut R) -> float {
         rng.gen::<f64>() as float
     }
 }
 
 impl Rand for f32 {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> f32 {
+    fn rand<R: Rng>(rng: &mut R) -> f32 {
         rng.gen::<f64>() as f32
     }
 }
@@ -153,7 +153,7 @@ impl Rand for f32 {
 static scale : f64 = (u32::max_value as f64) + 1.0f64;
 impl Rand for f64 {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> f64 {
+    fn rand<R: Rng>(rng: &mut R) -> f64 {
         let u1 = rng.next() as f64;
         let u2 = rng.next() as f64;
         let u3 = rng.next() as f64;
@@ -164,14 +164,14 @@ impl Rand for f64 {
 
 impl Rand for char {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> char {
+    fn rand<R: Rng>(rng: &mut R) -> char {
         rng.next() as char
     }
 }
 
 impl Rand for bool {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> bool {
+    fn rand<R: Rng>(rng: &mut R) -> bool {
         rng.next() & 1u32 == 1u32
     }
 }
@@ -185,7 +185,7 @@ macro_rules! tuple_impl {
             > Rand for ( $( $tyvar ),* , ) {
 
             #[inline]
-            fn rand<R: Rng>(_rng: &R) -> ( $( $tyvar ),* , ) {
+            fn rand<R: Rng>(_rng: &mut R) -> ( $( $tyvar ),* , ) {
                 (
                     // use the $tyvar's to get the appropriate number of
                     // repeats (they're not actually needed)
@@ -201,7 +201,7 @@ macro_rules! tuple_impl {
 
 impl Rand for () {
     #[inline]
-    fn rand<R: Rng>(_: &R) -> () { () }
+    fn rand<R: Rng>(_: &mut R) -> () { () }
 }
 tuple_impl!{A}
 tuple_impl!{A, B}
@@ -216,7 +216,7 @@ tuple_impl!{A, B, C, D, E, F, G, H, I, J}
 
 impl<T:Rand> Rand for Option<T> {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> Option<T> {
+    fn rand<R: Rng>(rng: &mut R) -> Option<T> {
         if rng.gen() {
             Some(rng.gen())
         } else {
@@ -227,12 +227,12 @@ impl<T:Rand> Rand for Option<T> {
 
 impl<T: Rand> Rand for ~T {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> ~T { ~rng.gen() }
+    fn rand<R: Rng>(rng: &mut R) -> ~T { ~rng.gen() }
 }
 
 impl<T: Rand> Rand for @T {
     #[inline]
-    fn rand<R: Rng>(rng: &R) -> @T { @rng.gen() }
+    fn rand<R: Rng>(rng: &mut R) -> @T { @rng.gen() }
 }
 
 #[abi = "cdecl"]
@@ -248,7 +248,7 @@ pub mod rustrt {
 /// A random number generator
 pub trait Rng {
     /// Return the next random integer
-    pub fn next(&self) -> u32;
+    pub fn next(&mut self) -> u32;
 }
 
 /// A value with a particular weight compared to other values
@@ -259,21 +259,21 @@ pub struct Weighted<T> {
 
 pub trait RngUtil {
     /// Return a random value of a Rand type
-    fn gen<T:Rand>(&self) -> T;
+    fn gen<T:Rand>(&mut self) -> T;
     /**
      * Return a int randomly chosen from the range [start, end),
      * failing if start >= end
      */
-    fn gen_int_range(&self, start: int, end: int) -> int;
+    fn gen_int_range(&mut self, start: int, end: int) -> int;
     /**
      * Return a uint randomly chosen from the range [start, end),
      * failing if start >= end
      */
-    fn gen_uint_range(&self, start: uint, end: uint) -> uint;
+    fn gen_uint_range(&mut self, start: uint, end: uint) -> uint;
     /**
      * Return a char randomly chosen from chars, failing if chars is empty
      */
-    fn gen_char_from(&self, chars: &str) -> char;
+    fn gen_char_from(&mut self, chars: &str) -> char;
     /**
      * Return a bool with a 1 in n chance of true
      *
@@ -289,7 +289,7 @@ pub trait RngUtil {
      * }
      * ~~~
      */
-    fn gen_weighted_bool(&self, n: uint) -> bool;
+    fn gen_weighted_bool(&mut self, n: uint) -> bool;
     /**
      * Return a random string of the specified length composed of A-Z,a-z,0-9
      *
@@ -305,7 +305,7 @@ pub trait RngUtil {
      * }
      * ~~~
      */
-    fn gen_str(&self, len: uint) -> ~str;
+    fn gen_str(&mut self, len: uint) -> ~str;
     /**
      * Return a random byte string of the specified length
      *
@@ -321,7 +321,7 @@ pub trait RngUtil {
      * }
      * ~~~
      */
-    fn gen_bytes(&self, len: uint) -> ~[u8];
+    fn gen_bytes(&mut self, len: uint) -> ~[u8];
     /**
      * Choose an item randomly, failing if values is empty
      *
@@ -337,9 +337,9 @@ pub trait RngUtil {
      * }
      * ~~~
      */
-    fn choose<T:Copy>(&self, values: &[T]) -> T;
+    fn choose<T:Copy>(&mut self, values: &[T]) -> T;
     /// Choose Some(item) randomly, returning None if values is empty
-    fn choose_option<T:Copy>(&self, values: &[T]) -> Option<T>;
+    fn choose_option<T:Copy>(&mut self, values: &[T]) -> Option<T>;
     /**
      * Choose an item respecting the relative weights, failing if the sum of
      * the weights is 0
@@ -359,7 +359,7 @@ pub trait RngUtil {
      * }
      * ~~~
      */
-    fn choose_weighted<T:Copy>(&self, v : &[Weighted<T>]) -> T;
+    fn choose_weighted<T:Copy>(&mut self, v : &[Weighted<T>]) -> T;
     /**
      * Choose Some(item) respecting the relative weights, returning none if
      * the sum of the weights is 0
@@ -379,7 +379,8 @@ pub trait RngUtil {
      * }
      * ~~~
      */
-    fn choose_weighted_option<T:Copy>(&self, v: &[Weighted<T>]) -> Option<T>;
+    fn choose_weighted_option<T:Copy>(&mut self, v: &[Weighted<T>])
+                                     -> Option<T>;
     /**
      * Return a vec containing copies of the items, in order, where
      * the weight of the item determines how many copies there are
@@ -399,7 +400,7 @@ pub trait RngUtil {
      * }
      * ~~~
      */
-    fn weighted_vec<T:Copy>(&self, v: &[Weighted<T>]) -> ~[T];
+    fn weighted_vec<T:Copy>(&mut self, v: &[Weighted<T>]) -> ~[T];
     /**
      * Shuffle a vec
      *
@@ -415,7 +416,7 @@ pub trait RngUtil {
      * }
      * ~~~
      */
-    fn shuffle<T:Copy>(&self, values: &[T]) -> ~[T];
+    fn shuffle<T:Copy>(&mut self, values: &[T]) -> ~[T];
     /**
      * Shuffle a mutable vec in place
      *
@@ -435,14 +436,14 @@ pub trait RngUtil {
      * }
      * ~~~
      */
-    fn shuffle_mut<T>(&self, values: &mut [T]);
+    fn shuffle_mut<T>(&mut self, values: &mut [T]);
 }
 
 /// Extension methods for random number generators
 impl<R: Rng> RngUtil for R {
     /// Return a random value for a Rand type
     #[inline(always)]
-    fn gen<T: Rand>(&self) -> T {
+    fn gen<T: Rand>(&mut self) -> T {
         Rand::rand(self)
     }
 
@@ -450,7 +451,7 @@ impl<R: Rng> RngUtil for R {
      * Return an int randomly chosen from the range [start, end),
      * failing if start >= end
      */
-    fn gen_int_range(&self, start: int, end: int) -> int {
+    fn gen_int_range(&mut self, start: int, end: int) -> int {
         assert!(start < end);
         start + int::abs(self.gen::<int>() % (end - start))
     }
@@ -459,7 +460,7 @@ impl<R: Rng> RngUtil for R {
      * Return a uint randomly chosen from the range [start, end),
      * failing if start >= end
      */
-    fn gen_uint_range(&self, start: uint, end: uint) -> uint {
+    fn gen_uint_range(&mut self, start: uint, end: uint) -> uint {
         assert!(start < end);
         start + (self.gen::<uint>() % (end - start))
     }
@@ -467,7 +468,7 @@ impl<R: Rng> RngUtil for R {
     /**
      * Return a char randomly chosen from chars, failing if chars is empty
      */
-    fn gen_char_from(&self, chars: &str) -> char {
+    fn gen_char_from(&mut self, chars: &str) -> char {
         assert!(!chars.is_empty());
         let mut cs = ~[];
         for str::each_char(chars) |c| { cs.push(c) }
@@ -475,7 +476,7 @@ impl<R: Rng> RngUtil for R {
     }
 
     /// Return a bool with a 1-in-n chance of true
-    fn gen_weighted_bool(&self, n: uint) -> bool {
+    fn gen_weighted_bool(&mut self, n: uint) -> bool {
         if n == 0u {
             true
         } else {
@@ -486,7 +487,7 @@ impl<R: Rng> RngUtil for R {
     /**
      * Return a random string of the specified length composed of A-Z,a-z,0-9
      */
-    fn gen_str(&self, len: uint) -> ~str {
+    fn gen_str(&mut self, len: uint) -> ~str {
         let charset = ~"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
                        abcdefghijklmnopqrstuvwxyz\
                        0123456789";
@@ -500,19 +501,19 @@ impl<R: Rng> RngUtil for R {
     }
 
     /// Return a random byte string of the specified length
-    fn gen_bytes(&self, len: uint) -> ~[u8] {
+    fn gen_bytes(&mut self, len: uint) -> ~[u8] {
         do vec::from_fn(len) |_i| {
             self.gen()
         }
     }
 
     /// Choose an item randomly, failing if values is empty
-    fn choose<T:Copy>(&self, values: &[T]) -> T {
+    fn choose<T:Copy>(&mut self, values: &[T]) -> T {
         self.choose_option(values).get()
     }
 
     /// Choose Some(item) randomly, returning None if values is empty
-    fn choose_option<T:Copy>(&self, values: &[T]) -> Option<T> {
+    fn choose_option<T:Copy>(&mut self, values: &[T]) -> Option<T> {
         if values.is_empty() {
             None
         } else {
@@ -523,7 +524,7 @@ impl<R: Rng> RngUtil for R {
      * Choose an item respecting the relative weights, failing if the sum of
      * the weights is 0
      */
-    fn choose_weighted<T:Copy>(&self, v : &[Weighted<T>]) -> T {
+    fn choose_weighted<T:Copy>(&mut self, v: &[Weighted<T>]) -> T {
         self.choose_weighted_option(v).get()
     }
 
@@ -531,7 +532,8 @@ impl<R: Rng> RngUtil for R {
      * Choose Some(item) respecting the relative weights, returning none if
      * the sum of the weights is 0
      */
-    fn choose_weighted_option<T:Copy>(&self, v: &[Weighted<T>]) -> Option<T> {
+    fn choose_weighted_option<T:Copy>(&mut self, v: &[Weighted<T>])
+                                     -> Option<T> {
         let mut total = 0u;
         for v.each |item| {
             total += item.weight;
@@ -554,7 +556,7 @@ impl<R: Rng> RngUtil for R {
      * Return a vec containing copies of the items, in order, where
      * the weight of the item determines how many copies there are
      */
-    fn weighted_vec<T:Copy>(&self, v: &[Weighted<T>]) -> ~[T] {
+    fn weighted_vec<T:Copy>(&mut self, v: &[Weighted<T>]) -> ~[T] {
         let mut r = ~[];
         for v.each |item| {
             for uint::range(0u, item.weight) |_i| {
@@ -565,14 +567,14 @@ impl<R: Rng> RngUtil for R {
     }
 
     /// Shuffle a vec
-    fn shuffle<T:Copy>(&self, values: &[T]) -> ~[T] {
+    fn shuffle<T:Copy>(&mut self, values: &[T]) -> ~[T] {
         let mut m = vec::from_slice(values);
         self.shuffle_mut(m);
         m
     }
 
     /// Shuffle a mutable vec in place
-    fn shuffle_mut<T>(&self, values: &mut [T]) {
+    fn shuffle_mut<T>(&mut self, values: &mut [T]) {
         let mut i = values.len();
         while i >= 2u {
             // invariant: elements with index >= i have been locked in place.
@@ -594,12 +596,12 @@ static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
 /// A random number generator that uses the [ISAAC
 /// algorithm](http://en.wikipedia.org/wiki/ISAAC_%28cipher%29).
 pub struct IsaacRng {
-    priv mut cnt: u32,
-    priv mut rsl: [u32, .. RAND_SIZE],
-    priv mut mem: [u32, .. RAND_SIZE],
-    priv mut a: u32,
-    priv mut b: u32,
-    priv mut c: u32
+    priv cnt: u32,
+    priv rsl: [u32, .. RAND_SIZE],
+    priv mem: [u32, .. RAND_SIZE],
+    priv a: u32,
+    priv b: u32,
+    priv c: u32
 }
 
 pub impl IsaacRng {
@@ -647,7 +649,7 @@ pub impl IsaacRng {
     /// Initialises `self`. If `use_rsl` is true, then use the current value
     /// of `rsl` as a seed, otherwise construct one algorithmically (not
     /// randomly).
-    priv fn init(&self, use_rsl: bool) {
+    priv fn init(&mut self, use_rsl: bool) {
         macro_rules! init_mut_many (
             ($( $var:ident ),* = $val:expr ) => {
                 let mut $( $var = $val ),*;
@@ -705,16 +707,16 @@ pub impl IsaacRng {
 
     /// Refills the output buffer (`self.rsl`)
     #[inline]
-    priv fn isaac(&self) {
+    priv fn isaac(&mut self) {
         self.c += 1;
         // abbreviations
         let mut a = self.a, b = self.b + self.c;
-        let mem = &mut self.mem;
-        let rsl = &mut self.rsl;
 
         static midpoint: uint =  RAND_SIZE as uint / 2;
 
-        macro_rules! ind (($x:expr) => { mem[($x >> 2) & (RAND_SIZE - 1)] });
+        macro_rules! ind (($x:expr) => {
+            self.mem[($x >> 2) & (RAND_SIZE - 1)]
+        });
         macro_rules! rngstep(
             ($j:expr, $shift:expr) => {{
                 let base = base + $j;
@@ -724,13 +726,13 @@ pub impl IsaacRng {
                     a << $shift as uint
                 };
 
-                let x = mem[base  + mr_offset];
-                a = (a ^ mix) + mem[base + m2_offset];
+                let x = self.mem[base  + mr_offset];
+                a = (a ^ mix) + self.mem[base + m2_offset];
                 let y = ind!(x) + a + b;
-                mem[base + mr_offset] = y;
+                self.mem[base + mr_offset] = y;
 
                 b = ind!(y >> RAND_SIZE_LEN) + x;
-                rsl[base + mr_offset] = b;
+                self.rsl[base + mr_offset] = b;
             }}
         );
 
@@ -751,7 +753,7 @@ pub impl IsaacRng {
 
 impl Rng for IsaacRng {
     #[inline(always)]
-    fn next(&self) -> u32 {
+    fn next(&mut self) -> u32 {
         if self.cnt == 0 {
             // make some more numbers
             self.isaac();
@@ -765,15 +767,15 @@ impl Rng for IsaacRng {
 /// generator](http://en.wikipedia.org/wiki/Xorshift). Not suitable for
 /// cryptographic purposes.
 pub struct XorShiftRng {
-    priv mut x: u32,
-    priv mut y: u32,
-    priv mut z: u32,
-    priv mut w: u32,
+    priv x: u32,
+    priv y: u32,
+    priv z: u32,
+    priv w: u32,
 }
 
 impl Rng for XorShiftRng {
     #[inline]
-    pub fn next(&self) -> u32 {
+    pub fn next(&mut self) -> u32 {
         let x = self.x;
         let t = x ^ (x << 11);
         self.x = self.y;
@@ -789,7 +791,10 @@ pub impl XorShiftRng {
     /// Create an xor shift random number generator with a default seed.
     fn new() -> XorShiftRng {
         // constants taken from http://en.wikipedia.org/wiki/Xorshift
-        XorShiftRng::new_seeded(123456789u32, 362436069u32, 521288629u32, 88675123u32)
+        XorShiftRng::new_seeded(123456789u32,
+                                362436069u32,
+                                521288629u32,
+                                88675123u32)
     }
 
     /**
@@ -798,7 +803,12 @@ pub impl XorShiftRng {
      * all other generators constructed with the same seed.
      */
     fn new_seeded(x: u32, y: u32, z: u32, w: u32) -> XorShiftRng {
-        XorShiftRng { x: x, y: y, z: z, w: w }
+        XorShiftRng {
+            x: x,
+            y: y,
+            z: z,
+            w: w,
+        }
     }
 }
 
@@ -815,7 +825,7 @@ pub fn seed() -> ~[u8] {
 }
 
 // used to make space in TLS for a random number generator
-fn tls_rng_state(_v: @IsaacRng) {}
+fn tls_rng_state(_v: @@mut IsaacRng) {}
 
 /**
  * Gives back a lazily initialized task-local random number generator,
@@ -823,15 +833,15 @@ fn tls_rng_state(_v: @IsaacRng) {}
  * `task_rng().gen::<int>()`.
  */
 #[inline]
-pub fn task_rng() -> @IsaacRng {
-    let r : Option<@IsaacRng>;
+pub fn task_rng() -> @@mut IsaacRng {
+    let r : Option<@@mut IsaacRng>;
     unsafe {
         r = task::local_data::local_data_get(tls_rng_state);
     }
     match r {
         None => {
             unsafe {
-                let rng = @IsaacRng::new_seeded(seed());
+                let rng = @@mut IsaacRng::new_seeded(seed());
                 task::local_data::local_data_set(tls_rng_state, rng);
                 rng
             }
@@ -841,9 +851,13 @@ pub fn task_rng() -> @IsaacRng {
 }
 
 // Allow direct chaining with `task_rng`
-impl<R: Rng> Rng for @R {
+impl<R: Rng> Rng for @@mut R {
     #[inline(always)]
-    fn next(&self) -> u32 { (**self).next() }
+    fn next(&mut self) -> u32 {
+        match *self {
+            @@ref mut r => r.next()
+        }
+    }
 }
 
 /**
@@ -852,7 +866,9 @@ impl<R: Rng> Rng for @R {
  */
 #[inline]
 pub fn random<T: Rand>() -> T {
-    (*task_rng()).gen()
+    match *task_rng() {
+        @ref mut r => r.gen()
+    }
 }
 
 #[cfg(test)]
@@ -863,8 +879,8 @@ mod tests {
     #[test]
     fn test_rng_seeded() {
         let seed = seed();
-        let ra = IsaacRng::new_seeded(seed);
-        let rb = IsaacRng::new_seeded(seed);
+        let mut ra = IsaacRng::new_seeded(seed);
+        let mut rb = IsaacRng::new_seeded(seed);
         assert!(ra.gen_str(100u) == rb.gen_str(100u));
     }
 
@@ -872,15 +888,15 @@ mod tests {
     fn test_rng_seeded_custom_seed() {
         // much shorter than generated seeds which are 1024 bytes
         let seed = [2u8, 32u8, 4u8, 32u8, 51u8];
-        let ra = IsaacRng::new_seeded(seed);
-        let rb = IsaacRng::new_seeded(seed);
+        let mut ra = IsaacRng::new_seeded(seed);
+        let mut rb = IsaacRng::new_seeded(seed);
         assert!(ra.gen_str(100u) == rb.gen_str(100u));
     }
 
     #[test]
     fn test_rng_seeded_custom_seed2() {
         let seed = [2u8, 32u8, 4u8, 32u8, 51u8];
-        let ra = IsaacRng::new_seeded(seed);
+        let mut ra = IsaacRng::new_seeded(seed);
         // Regression test that isaac is actually using the above vector
         let r = ra.next();
         error!("%?", r);
@@ -890,7 +906,7 @@ mod tests {
 
     #[test]
     fn test_gen_int_range() {
-        let r = rng();
+        let mut r = rng();
         let a = r.gen_int_range(-3, 42);
         assert!(a >= -3 && a < 42);
         assert!(r.gen_int_range(0, 1) == 0);
@@ -901,12 +917,13 @@ mod tests {
     #[should_fail]
     #[ignore(cfg(windows))]
     fn test_gen_int_from_fail() {
-        rng().gen_int_range(5, -2);
+        let mut r = rng();
+        r.gen_int_range(5, -2);
     }
 
     #[test]
     fn test_gen_uint_range() {
-        let r = rng();
+        let mut r = rng();
         let a = r.gen_uint_range(3u, 42u);
         assert!(a >= 3u && a < 42u);
         assert!(r.gen_uint_range(0u, 1u) == 0u);
@@ -917,12 +934,13 @@ mod tests {
     #[should_fail]
     #[ignore(cfg(windows))]
     fn test_gen_uint_range_fail() {
-        rng().gen_uint_range(5u, 2u);
+        let mut r = rng();
+        r.gen_uint_range(5u, 2u);
     }
 
     #[test]
     fn test_gen_float() {
-        let r = rng();
+        let mut r = rng();
         let a = r.gen::<float>();
         let b = r.gen::<float>();
         debug!((a, b));
@@ -930,14 +948,14 @@ mod tests {
 
     #[test]
     fn test_gen_weighted_bool() {
-        let r = rng();
+        let mut r = rng();
         assert!(r.gen_weighted_bool(0u) == true);
         assert!(r.gen_weighted_bool(1u) == true);
     }
 
     #[test]
     fn test_gen_str() {
-        let r = rng();
+        let mut r = rng();
         debug!(r.gen_str(10u));
         debug!(r.gen_str(10u));
         debug!(r.gen_str(10u));
@@ -948,7 +966,7 @@ mod tests {
 
     #[test]
     fn test_gen_bytes() {
-        let r = rng();
+        let mut r = rng();
         assert!(r.gen_bytes(0u).len() == 0u);
         assert!(r.gen_bytes(10u).len() == 10u);
         assert!(r.gen_bytes(16u).len() == 16u);
@@ -956,13 +974,13 @@ mod tests {
 
     #[test]
     fn test_choose() {
-        let r = rng();
+        let mut r = rng();
         assert!(r.choose([1, 1, 1]) == 1);
     }
 
     #[test]
     fn test_choose_option() {
-        let r = rng();
+        let mut r = rng();
         let x: Option<int> = r.choose_option([]);
         assert!(x.is_none());
         assert!(r.choose_option([1, 1, 1]) == Some(1));
@@ -970,7 +988,7 @@ mod tests {
 
     #[test]
     fn test_choose_weighted() {
-        let r = rng();
+        let mut r = rng();
         assert!(r.choose_weighted(~[
             Weighted { weight: 1u, item: 42 },
         ]) == 42);
@@ -982,7 +1000,7 @@ mod tests {
 
     #[test]
     fn test_choose_weighted_option() {
-        let r = rng();
+        let mut r = rng();
         assert!(r.choose_weighted_option(~[
             Weighted { weight: 1u, item: 42 },
         ]) == Some(42));
@@ -996,7 +1014,7 @@ mod tests {
 
     #[test]
     fn test_weighted_vec() {
-        let r = rng();
+        let mut r = rng();
         let empty: ~[int] = ~[];
         assert!(r.weighted_vec(~[]) == empty);
         assert!(r.weighted_vec(~[
@@ -1008,7 +1026,7 @@ mod tests {
 
     #[test]
     fn test_shuffle() {
-        let r = rng();
+        let mut r = rng();
         let empty: ~[int] = ~[];
         assert!(r.shuffle(~[]) == empty);
         assert!(r.shuffle(~[1, 1, 1]) == ~[1, 1, 1]);
@@ -1016,7 +1034,7 @@ mod tests {
 
     #[test]
     fn test_task_rng() {
-        let r = task_rng();
+        let mut r = task_rng();
         r.gen::<int>();
         assert!(r.shuffle(~[1, 1, 1]) == ~[1, 1, 1]);
         assert!(r.gen_uint_range(0u, 1u) == 0u);
@@ -1063,7 +1081,7 @@ mod tests {
                 let rt_rng = do vec::as_imm_buf(seed) |p, sz| {
                     rustrt::rand_new_seeded(p, sz as size_t)
                 };
-                let rng = IsaacRng::new_seeded(seed);
+                let mut rng = IsaacRng::new_seeded(seed);
 
                 for 10000.times {
                     assert_eq!(rng.next(), rustrt::rand_next(rt_rng));
diff --git a/src/libcore/rand/distributions.rs b/src/libcore/rand/distributions.rs
index a644f60db69..72cff5111e7 100644
--- a/src/libcore/rand/distributions.rs
+++ b/src/libcore/rand/distributions.rs
@@ -27,13 +27,13 @@ mod ziggurat_tables;
 
 // inlining should mean there is no performance penalty for this
 #[inline(always)]
-fn ziggurat<R:Rng>(rng: &R,
+fn ziggurat<R:Rng>(rng: &mut R,
                    center_u: bool,
                    X: ziggurat_tables::ZigTable,
                    F: ziggurat_tables::ZigTable,
                    F_DIFF: ziggurat_tables::ZigTable,
                    pdf: &'static fn(f64) -> f64, // probability density function
-                   zero_case: &'static fn(&R, f64) -> f64) -> f64 {
+                   zero_case: &'static fn(&mut R, f64) -> f64) -> f64 {
     loop {
         let u = if center_u {2.0 * rng.gen() - 1.0} else {rng.gen()};
         let i: uint = rng.gen::<uint>() & 0xff;
@@ -76,13 +76,13 @@ fn ziggurat<R:Rng>(rng: &R,
 pub struct StandardNormal(f64);
 
 impl Rand for StandardNormal {
-    fn rand<R:Rng>(rng: &R) -> StandardNormal {
+    fn rand<R:Rng>(rng: &mut R) -> StandardNormal {
         #[inline(always)]
         fn pdf(x: f64) -> f64 {
             f64::exp((-x*x/2.0) as f64) as f64
         }
         #[inline(always)]
-        fn zero_case<R:Rng>(rng: &R, u: f64) -> f64 {
+        fn zero_case<R:Rng>(rng: &mut R, u: f64) -> f64 {
             // compute a random number in the tail by hand
 
             // strange initial conditions, because the loop is not
@@ -130,13 +130,13 @@ pub struct Exp1(f64);
 // This could be done via `-f64::ln(rng.gen::<f64>())` but that is slower.
 impl Rand for Exp1 {
     #[inline]
-    fn rand<R:Rng>(rng: &R) -> Exp1 {
+    fn rand<R:Rng>(rng: &mut R) -> Exp1 {
         #[inline(always)]
         fn pdf(x: f64) -> f64 {
             f64::exp(-x)
         }
         #[inline(always)]
-        fn zero_case<R:Rng>(rng: &R, _u: f64) -> f64 {
+        fn zero_case<R:Rng>(rng: &mut R, _u: f64) -> f64 {
             ziggurat_tables::ZIG_EXP_R - f64::ln(rng.gen())
         }
 
diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs
index 3d525993259..a645a7e8680 100644
--- a/src/libcore/repr.rs
+++ b/src/libcore/repr.rs
@@ -144,28 +144,30 @@ enum VariantState {
 }
 
 pub struct ReprVisitor {
-    mut ptr: *c_void,
-    mut ptr_stk: ~[*c_void],
-    mut var_stk: ~[VariantState],
+    ptr: @mut *c_void,
+    ptr_stk: @mut ~[*c_void],
+    var_stk: @mut ~[VariantState],
     writer: @Writer
 }
 pub fn ReprVisitor(ptr: *c_void, writer: @Writer) -> ReprVisitor {
-    ReprVisitor { ptr: ptr,
-                  ptr_stk: ~[],
-                  var_stk: ~[],
-                  writer: writer }
+    ReprVisitor {
+        ptr: @mut ptr,
+        ptr_stk: @mut ~[],
+        var_stk: @mut ~[],
+        writer: writer,
+    }
 }
 
 impl MovePtr for ReprVisitor {
     #[inline(always)]
     fn move_ptr(&self, adjustment: &fn(*c_void) -> *c_void) {
-        self.ptr = adjustment(self.ptr);
+        *self.ptr = adjustment(*self.ptr);
     }
     fn push_ptr(&self) {
-        self.ptr_stk.push(self.ptr);
+        self.ptr_stk.push(*self.ptr);
     }
     fn pop_ptr(&self) {
-        self.ptr = self.ptr_stk.pop();
+        *self.ptr = self.ptr_stk.pop();
     }
 }
 
@@ -176,14 +178,14 @@ pub impl ReprVisitor {
     #[inline(always)]
     fn get<T>(&self, f: &fn(&T)) -> bool {
         unsafe {
-            f(transmute::<*c_void,&T>(copy self.ptr));
+            f(transmute::<*c_void,&T>(*self.ptr));
         }
         true
     }
 
     #[inline(always)]
     fn visit_inner(&self, inner: *TyDesc) -> bool {
-        self.visit_ptr_inner(self.ptr, inner)
+        self.visit_ptr_inner(*self.ptr, inner)
     }
 
     #[inline(always)]
@@ -446,11 +448,16 @@ impl TyVisitor for ReprVisitor {
         true
     }
 
-    fn visit_enter_enum(&self, _n_variants: uint,
+    fn visit_enter_enum(&self,
+                        _n_variants: uint,
                         get_disr: extern unsafe fn(ptr: *Opaque) -> int,
-                        _sz: uint, _align: uint) -> bool {
-        let disr = unsafe { get_disr(transmute(self.ptr)) };
-        self.var_stk.push(SearchingFor(disr));
+                        _sz: uint,
+                        _align: uint) -> bool {
+        let var_stk: &mut ~[VariantState] = self.var_stk;
+        let disr = unsafe {
+            get_disr(transmute(*self.ptr))
+        };
+        var_stk.push(SearchingFor(disr));
         true
     }
 
@@ -482,8 +489,12 @@ impl TyVisitor for ReprVisitor {
         true
     }
 
-    fn visit_enum_variant_field(&self, i: uint, _offset: uint, inner: *TyDesc) -> bool {
-        match self.var_stk[vec::uniq_len(&const self.var_stk) - 1] {
+    fn visit_enum_variant_field(&self,
+                                i: uint,
+                                _offset: uint,
+                                inner: *TyDesc)
+                                -> bool {
+        match self.var_stk[vec::uniq_len(&const *self.var_stk) - 1] {
             Matched => {
                 if i != 0 {
                     self.writer.write_str(", ");
@@ -501,7 +512,7 @@ impl TyVisitor for ReprVisitor {
                                 _disr_val: int,
                                 n_fields: uint,
                                 _name: &str) -> bool {
-        match self.var_stk[vec::uniq_len(&const self.var_stk) - 1] {
+        match self.var_stk[vec::uniq_len(&const *self.var_stk) - 1] {
             Matched => {
                 if n_fields > 0 {
                     self.writer.write_char(')');
@@ -512,10 +523,14 @@ impl TyVisitor for ReprVisitor {
         true
     }
 
-    fn visit_leave_enum(&self, _n_variants: uint,
+    fn visit_leave_enum(&self,
+                        _n_variants: uint,
                         _get_disr: extern unsafe fn(ptr: *Opaque) -> int,
-                        _sz: uint, _align: uint) -> bool {
-        match self.var_stk.pop() {
+                        _sz: uint,
+                        _align: uint)
+                        -> bool {
+        let var_stk: &mut ~[VariantState] = self.var_stk;
+        match var_stk.pop() {
             SearchingFor(*) => fail!(~"enum value matched no variant"),
             _ => true
         }
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 17cc07c660d..1d67e754a4f 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -300,7 +300,7 @@ pub fn map_vec<T,U:Copy,V:Copy>(
     ts: &[T], op: &fn(&T) -> Result<V,U>) -> Result<~[V],U> {
 
     let mut vs: ~[V] = vec::with_capacity(vec::len(ts));
-    for vec::each(ts) |t| {
+    for ts.each |t| {
         match op(t) {
           Ok(copy v) => vs.push(v),
           Err(copy u) => return Err(u)
diff --git a/src/libcore/rt/local_services.rs b/src/libcore/rt/local_services.rs
index b83e1d24648..5ca7a72e84e 100644
--- a/src/libcore/rt/local_services.rs
+++ b/src/libcore/rt/local_services.rs
@@ -225,8 +225,8 @@ mod test {
     fn rng() {
         do run_in_newsched_task() {
             use rand::{rng, Rng};
-            let r = rng();
+            let mut r = rng();
             let _ = r.next();
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/libcore/rt/mod.rs b/src/libcore/rt/mod.rs
index a072fccd33d..25f6c870654 100644
--- a/src/libcore/rt/mod.rs
+++ b/src/libcore/rt/mod.rs
@@ -38,22 +38,35 @@ mod local_heap;
 pub mod test;
 
 pub fn start(main: *u8, _argc: int, _argv: **c_char, _crate_map: *u8) -> int {
+
     use self::sched::{Scheduler, Task};
     use self::uvio::UvEventLoop;
+    use sys::Closure;
+    use ptr;
+    use cast;
 
     let loop_ = ~UvEventLoop::new();
     let mut sched = ~Scheduler::new(loop_);
+
     let main_task = ~do Task::new(&mut sched.stack_pool) {
-        // XXX: Can't call a C function pointer from Rust yet
-        unsafe { rust_call_nullary_fn(main) };
+
+        unsafe {
+            // `main` is an `fn() -> ()` that doesn't take an environment
+            // XXX: Could also call this as an `extern "Rust" fn` once they work
+            let main = Closure {
+                code: main as *(),
+                env: ptr::null(),
+            };
+            let mainfn: &fn() = cast::transmute(main);
+
+            mainfn();
+        }
     };
+
     sched.task_queue.push_back(main_task);
     sched.run();
-    return 0;
 
-    extern {
-        fn rust_call_nullary_fn(f: *u8);
-    }
+    return 0;
 }
 
 /// Possible contexts in which Rust code may be executing.
diff --git a/src/libcore/rt/uvll.rs b/src/libcore/rt/uvll.rs
index 3eb7f8006b9..4bff3bff7d3 100644
--- a/src/libcore/rt/uvll.rs
+++ b/src/libcore/rt/uvll.rs
@@ -393,24 +393,26 @@ extern {
     // FIXME ref #2064
     fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
                            tcp_handle_ptr: *uv_tcp_t,
-                           ++after_cb: *u8,
-                           ++addr: *sockaddr_in) -> c_int;
+                           after_cb: *u8,
+                           addr: *sockaddr_in) -> c_int;
     // FIXME ref #2064
-    fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, ++addr: *sockaddr_in) -> c_int;
+    fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t, addr: *sockaddr_in) -> c_int;
     // FIXME ref #2064
     fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
                             tcp_handle_ptr: *uv_tcp_t,
-                            ++after_cb: *u8,
-                            ++addr: *sockaddr_in6) -> c_int;
+                            after_cb: *u8,
+                            addr: *sockaddr_in6) -> c_int;
     // FIXME ref #2064
-    fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, ++addr: *sockaddr_in6) -> c_int;
-    fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t, ++name: *sockaddr_in) -> c_int;
-    fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t, ++name: *sockaddr_in6) ->c_int;
+    fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t, addr: *sockaddr_in6) -> c_int;
+    fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
+                               name: *sockaddr_in) -> c_int;
+    fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
+                                name: *sockaddr_in6) ->c_int;
     fn rust_uv_listen(stream: *c_void, backlog: c_int, cb: *u8) -> c_int;
     fn rust_uv_accept(server: *c_void, client: *c_void) -> c_int;
     fn rust_uv_write(req: *c_void,
                      stream: *c_void,
-                     ++buf_in: *uv_buf_t,
+                     buf_in: *uv_buf_t,
                      buf_cnt: c_int,
                      cb: *u8) -> c_int;
     fn rust_uv_read_start(stream: *c_void,
@@ -426,7 +428,7 @@ extern {
     fn rust_uv_timer_stop(handle: *uv_timer_t) -> c_int;
 
     fn rust_uv_malloc_buf_base_of(sug_size: size_t) -> *u8;
-    fn rust_uv_free_base_of_buf(++buf: uv_buf_t);
+    fn rust_uv_free_base_of_buf(buf: uv_buf_t);
     fn rust_uv_get_stream_handle_from_connect_req(connect_req: *uv_connect_t) -> *uv_stream_t;
     fn rust_uv_get_stream_handle_from_write_req(write_req: *uv_write_t) -> *uv_stream_t;
     fn rust_uv_get_loop_for_uv_handle(handle: *c_void) -> *c_void;
@@ -436,6 +438,6 @@ extern {
     fn rust_uv_set_data_for_uv_handle(handle: *c_void, data: *c_void);
     fn rust_uv_get_data_for_req(req: *c_void) -> *c_void;
     fn rust_uv_set_data_for_req(req: *c_void, data: *c_void);
-    fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8;
-    fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> size_t;
+    fn rust_uv_get_base_from_buf(buf: uv_buf_t) -> *u8;
+    fn rust_uv_get_len_from_buf(buf: uv_buf_t) -> size_t;
 }
diff --git a/src/libcore/run.rs b/src/libcore/run.rs
index 55b6c5100dd..fd168dc02f6 100644
--- a/src/libcore/run.rs
+++ b/src/libcore/run.rs
@@ -426,7 +426,7 @@ fn with_argv<T>(prog: &str, args: &[~str],
                 cb: &fn(**libc::c_char) -> T) -> T {
     let mut argptrs = str::as_c_str(prog, |b| ~[b]);
     let mut tmps = ~[];
-    for vec::each(args) |arg| {
+    for args.each |arg| {
         let t = @copy *arg;
         tmps.push(t);
         argptrs.push_all(str::as_c_str(*t, |b| ~[b]));
@@ -445,7 +445,7 @@ fn with_envp<T>(env: &Option<~[(~str,~str)]>,
         let mut tmps = ~[];
         let mut ptrs = ~[];
 
-        for vec::each(*es) |e| {
+        for (*es).each |e| {
             let (k,v) = copy *e;
             let t = @(fmt!("%s=%s", k, v));
             tmps.push(t);
@@ -470,7 +470,7 @@ fn with_envp<T>(env: &Option<~[(~str,~str)]>,
         match *env {
           Some(ref es) if !vec::is_empty(*es) => {
             let mut blk : ~[u8] = ~[];
-            for vec::each(*es) |e| {
+            for (*es).each |e| {
                 let (k,v) = copy *e;
                 let t = fmt!("%s=%s", k, v);
                 let mut v : ~[u8] = ::cast::transmute(t);
diff --git a/src/libcore/stackwalk.rs b/src/libcore/stackwalk.rs
index 24237694502..1958b5b9d80 100644
--- a/src/libcore/stackwalk.rs
+++ b/src/libcore/stackwalk.rs
@@ -81,6 +81,6 @@ fn frame_address(f: &fn(x: *u8)) {
 pub mod rusti {
     #[abi = "rust-intrinsic"]
     pub extern "rust-intrinsic" {
-        pub fn frame_address(+f: &once fn(x: *u8));
+        pub fn frame_address(f: &once fn(x: *u8));
     }
 }
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index a41c99b266b..5ec6471ac4a 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -32,7 +32,7 @@ use uint;
 use vec;
 use to_str::ToStr;
 
-#[cfg(notest)] use cmp::{Eq, Ord, Equiv, TotalEq};
+#[cfg(not(test))] use cmp::{Eq, Ord, Equiv, TotalEq};
 
 /*
 Section: Creating a string
@@ -189,7 +189,7 @@ pub fn from_char(ch: char) -> ~str {
 pub fn from_chars(chs: &[char]) -> ~str {
     let mut buf = ~"";
     reserve(&mut buf, chs.len());
-    for vec::each(chs) |ch| {
+    for chs.each |ch| {
         push_char(&mut buf, *ch);
     }
     buf
@@ -326,7 +326,7 @@ pub fn connect_slices(v: &[&str], sep: &str) -> ~str {
             do as_buf(sep) |sepbuf, seplen| {
                 let seplen = seplen - 1;
                 let mut buf = ::cast::transmute_mut_unsafe(buf);
-                for vec::each(v) |ss| {
+                for v.each |ss| {
                     do as_buf(*ss) |ssbuf, sslen| {
                         let sslen = sslen - 1;
                         if first {
@@ -913,7 +913,7 @@ Section: Comparing strings
 */
 
 /// Bytewise slice equality
-#[cfg(notest)]
+#[cfg(not(test))]
 #[lang="str_eq"]
 #[inline]
 pub fn eq_slice(a: &str, b: &str) -> bool {
@@ -949,7 +949,7 @@ pub fn eq_slice(a: &str, b: &str) -> bool {
 }
 
 /// Bytewise string equality
-#[cfg(notest)]
+#[cfg(not(test))]
 #[lang="uniq_str_eq"]
 #[inline]
 pub fn eq(a: &~str, b: &~str) -> bool {
@@ -977,19 +977,19 @@ fn cmp(a: &str, b: &str) -> Ordering {
     a.len().cmp(&b.len())
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<'self> TotalOrd for &'self str {
     #[inline]
     fn cmp(&self, other: & &'self str) -> Ordering { cmp(*self, *other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl TotalOrd for ~str {
     #[inline]
     fn cmp(&self, other: &~str) -> Ordering { cmp(*self, *other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl TotalOrd for @str {
     #[inline]
     fn cmp(&self, other: &@str) -> Ordering { cmp(*self, *other) }
@@ -1030,7 +1030,7 @@ fn gt(a: &str, b: &str) -> bool {
     !le(a, b)
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<'self> Eq for &'self str {
     #[inline(always)]
     fn eq(&self, other: & &'self str) -> bool {
@@ -1040,7 +1040,7 @@ impl<'self> Eq for &'self str {
     fn ne(&self, other: & &'self str) -> bool { !(*self).eq(other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Eq for ~str {
     #[inline(always)]
     fn eq(&self, other: &~str) -> bool {
@@ -1050,7 +1050,7 @@ impl Eq for ~str {
     fn ne(&self, other: &~str) -> bool { !(*self).eq(other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Eq for @str {
     #[inline(always)]
     fn eq(&self, other: &@str) -> bool {
@@ -1060,7 +1060,7 @@ impl Eq for @str {
     fn ne(&self, other: &@str) -> bool { !(*self).eq(other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<'self> TotalEq for &'self str {
     #[inline(always)]
     fn equals(&self, other: & &'self str) -> bool {
@@ -1068,7 +1068,7 @@ impl<'self> TotalEq for &'self str {
     }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl TotalEq for ~str {
     #[inline(always)]
     fn equals(&self, other: &~str) -> bool {
@@ -1076,7 +1076,7 @@ impl TotalEq for ~str {
     }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl TotalEq for @str {
     #[inline(always)]
     fn equals(&self, other: &@str) -> bool {
@@ -1084,7 +1084,7 @@ impl TotalEq for @str {
     }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Ord for ~str {
     #[inline(always)]
     fn lt(&self, other: &~str) -> bool { lt((*self), (*other)) }
@@ -1096,7 +1096,7 @@ impl Ord for ~str {
     fn gt(&self, other: &~str) -> bool { gt((*self), (*other)) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<'self> Ord for &'self str {
     #[inline(always)]
     fn lt(&self, other: & &'self str) -> bool { lt((*self), (*other)) }
@@ -1108,7 +1108,7 @@ impl<'self> Ord for &'self str {
     fn gt(&self, other: & &'self str) -> bool { gt((*self), (*other)) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl Ord for @str {
     #[inline(always)]
     fn lt(&self, other: &@str) -> bool { lt((*self), (*other)) }
@@ -1120,7 +1120,7 @@ impl Ord for @str {
     fn gt(&self, other: &@str) -> bool { gt((*self), (*other)) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<'self> Equiv<~str> for &'self str {
     #[inline(always)]
     fn equiv(&self, other: &~str) -> bool { eq_slice(*self, *other) }
@@ -2407,7 +2407,7 @@ pub mod raw {
     unsafe fn push_bytes(s: &mut ~str, bytes: &[u8]) {
         let new_len = s.len() + bytes.len();
         reserve_at_least(&mut *s, new_len);
-        for vec::each(bytes) |byte| { push_byte(&mut *s, *byte); }
+        for bytes.each |byte| { push_byte(&mut *s, *byte); }
     }
 
     /// Removes the last byte from a string and returns it. (Not UTF-8 safe).
@@ -2451,7 +2451,7 @@ pub mod raw {
 
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 pub mod traits {
     use ops::Add;
     use str::append;
@@ -3782,7 +3782,7 @@ mod tests {
                0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16,
                0x000a_u16 ]) ];
 
-        for vec::each(pairs) |p| {
+        for pairs.each |p| {
             let (s, u) = copy *p;
             assert!(to_utf16(s) == u);
             assert!(from_utf16(u) == s);
diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs
index fd695c16ea7..e58aa14572b 100644
--- a/src/libcore/task/mod.rs
+++ b/src/libcore/task/mod.rs
@@ -156,7 +156,7 @@ pub struct SchedOpts {
 pub struct TaskOpts {
     linked: bool,
     supervised: bool,
-    mut notify_chan: Option<Chan<TaskResult>>,
+    notify_chan: Option<Chan<TaskResult>>,
     sched: SchedOpts
 }
 
@@ -176,9 +176,9 @@ pub struct TaskOpts {
 // FIXME (#3724): Replace the 'consumed' bit with move mode on self
 pub struct TaskBuilder {
     opts: TaskOpts,
-    mut gen_body: Option<~fn(v: ~fn()) -> ~fn()>,
+    gen_body: Option<~fn(v: ~fn()) -> ~fn()>,
     can_not_copy: Option<util::NonCopyable>,
-    mut consumed: bool,
+    consumed: bool,
 }
 
 /**
@@ -191,13 +191,13 @@ pub fn task() -> TaskBuilder {
         opts: default_task_opts(),
         gen_body: None,
         can_not_copy: None,
-        mut consumed: false,
+        consumed: false,
     }
 }
 
 #[doc(hidden)] // FIXME #3538
 priv impl TaskBuilder {
-    fn consume(&self) -> TaskBuilder {
+    fn consume(&mut self) -> TaskBuilder {
         if self.consumed {
             fail!(~"Cannot copy a task_builder"); // Fake move mode on self
         }
@@ -219,57 +219,25 @@ priv impl TaskBuilder {
 }
 
 pub impl TaskBuilder {
-    /**
-     * Decouple the child task's failure from the parent's. If either fails,
-     * the other will not be killed.
-     */
-    fn unlinked(&self) -> TaskBuilder {
-        let notify_chan = replace(&mut self.opts.notify_chan, None);
-        TaskBuilder {
-            opts: TaskOpts {
-                linked: false,
-                supervised: self.opts.supervised,
-                notify_chan: notify_chan,
-                sched: self.opts.sched
-            },
-            can_not_copy: None,
-            .. self.consume()
-        }
+    /// Decouple the child task's failure from the parent's. If either fails,
+    /// the other will not be killed.
+    fn unlinked(&mut self) {
+        self.opts.linked = false;
     }
-    /**
-     * Unidirectionally link the child task's failure with the parent's. The
-     * child's failure will not kill the parent, but the parent's will kill
-     * the child.
-     */
-    fn supervised(&self) -> TaskBuilder {
-        let notify_chan = replace(&mut self.opts.notify_chan, None);
-        TaskBuilder {
-            opts: TaskOpts {
-                linked: false,
-                supervised: true,
-                notify_chan: notify_chan,
-                sched: self.opts.sched
-            },
-            can_not_copy: None,
-            .. self.consume()
-        }
+
+    /// Unidirectionally link the child task's failure with the parent's. The
+    /// child's failure will not kill the parent, but the parent's will kill
+    /// the child.
+    fn supervised(&mut self) {
+        self.opts.supervised = true;
+        self.opts.linked = false;
     }
-    /**
-     * Link the child task's and parent task's failures. If either fails, the
-     * other will be killed.
-     */
-    fn linked(&self) -> TaskBuilder {
-        let notify_chan = replace(&mut self.opts.notify_chan, None);
-        TaskBuilder {
-            opts: TaskOpts {
-                linked: true,
-                supervised: false,
-                notify_chan: notify_chan,
-                sched: self.opts.sched
-            },
-            can_not_copy: None,
-            .. self.consume()
-        }
+
+    /// Link the child task's and parent task's failures. If either fails, the
+    /// other will be killed.
+    fn linked(&mut self) {
+        self.opts.linked = true;
+        self.opts.supervised = false;
     }
 
     /**
@@ -289,7 +257,7 @@ pub impl TaskBuilder {
      * # Failure
      * Fails if a future_result was already set for this task.
      */
-    fn future_result(&self, blk: &fn(v: Port<TaskResult>)) -> TaskBuilder {
+    fn future_result(&mut self, blk: &fn(v: Port<TaskResult>)) {
         // FIXME (#3725): Once linked failure and notification are
         // handled in the library, I can imagine implementing this by just
         // registering an arbitrary number of task::on_exit handlers and
@@ -305,30 +273,12 @@ pub impl TaskBuilder {
         blk(notify_pipe_po);
 
         // Reconfigure self to use a notify channel.
-        TaskBuilder {
-            opts: TaskOpts {
-                linked: self.opts.linked,
-                supervised: self.opts.supervised,
-                notify_chan: Some(notify_pipe_ch),
-                sched: self.opts.sched
-            },
-            can_not_copy: None,
-            .. self.consume()
-        }
+        self.opts.notify_chan = Some(notify_pipe_ch);
     }
+
     /// Configure a custom scheduler mode for the task.
-    fn sched_mode(&self, mode: SchedMode) -> TaskBuilder {
-        let notify_chan = replace(&mut self.opts.notify_chan, None);
-        TaskBuilder {
-            opts: TaskOpts {
-                linked: self.opts.linked,
-                supervised: self.opts.supervised,
-                notify_chan: notify_chan,
-                sched: SchedOpts { mode: mode, foreign_stack_size: None}
-            },
-            can_not_copy: None,
-            .. self.consume()
-        }
+    fn sched_mode(&mut self, mode: SchedMode) {
+        self.opts.sched.mode = mode;
     }
 
     /**
@@ -343,7 +293,7 @@ pub impl TaskBuilder {
      * generator by applying the task body which results from the
      * existing body generator to the new body generator.
      */
-    fn add_wrapper(&self, wrapper: ~fn(v: ~fn()) -> ~fn()) -> TaskBuilder {
+    fn add_wrapper(&mut self, wrapper: ~fn(v: ~fn()) -> ~fn()) {
         let prev_gen_body = replace(&mut self.gen_body, None);
         let prev_gen_body = match prev_gen_body {
             Some(gen) => gen,
@@ -360,18 +310,7 @@ pub impl TaskBuilder {
             };
             f
         };
-        let notify_chan = replace(&mut self.opts.notify_chan, None);
-        TaskBuilder {
-            opts: TaskOpts {
-                linked: self.opts.linked,
-                supervised: self.opts.supervised,
-                notify_chan: notify_chan,
-                sched: self.opts.sched
-            },
-            gen_body: Some(next_gen_body),
-            can_not_copy: None,
-            .. self.consume()
-        }
+        self.gen_body = Some(next_gen_body);
     }
 
     /**
@@ -386,7 +325,7 @@ pub impl TaskBuilder {
      * When spawning into a new scheduler, the number of threads requested
      * must be greater than zero.
      */
-    fn spawn(&self, f: ~fn()) {
+    fn spawn(&mut self, f: ~fn()) {
         let gen_body = replace(&mut self.gen_body, None);
         let notify_chan = replace(&mut self.opts.notify_chan, None);
         let x = self.consume();
@@ -406,8 +345,9 @@ pub impl TaskBuilder {
         };
         spawn::spawn_raw(opts, f);
     }
+
     /// Runs a task, while transfering ownership of one argument to the child.
-    fn spawn_with<A:Owned>(&self, arg: A, f: ~fn(v: A)) {
+    fn spawn_with<A:Owned>(&mut self, arg: A, f: ~fn(v: A)) {
         let arg = Cell(arg);
         do self.spawn {
             f(arg.take());
@@ -427,16 +367,16 @@ pub impl TaskBuilder {
      * # Failure
      * Fails if a future_result was already set for this task.
      */
-    fn try<T:Owned>(&self, f: ~fn() -> T) -> Result<T,()> {
+    fn try<T:Owned>(&mut self, f: ~fn() -> T) -> Result<T,()> {
         let (po, ch) = stream::<T>();
         let mut result = None;
 
-        let fr_task_builder = self.future_result(|+r| {
-            result = Some(r);
-        });
-        do fr_task_builder.spawn || {
+        self.future_result(|r| { result = Some(r); });
+
+        do self.spawn {
             ch.send(f());
         }
+
         match result.unwrap().recv() {
             Success => result::Ok(po.recv()),
             Failure => result::Err(())
@@ -468,26 +408,23 @@ pub fn default_task_opts() -> TaskOpts {
 
 /* Spawn convenience functions */
 
+/// Creates and executes a new child task
+///
+/// Sets up a new task with its own call stack and schedules it to run
+/// the provided unique closure.
+///
+/// This function is equivalent to `task().spawn(f)`.
 pub fn spawn(f: ~fn()) {
-    /*!
-     * Creates and executes a new child task
-     *
-     * Sets up a new task with its own call stack and schedules it to run
-     * the provided unique closure.
-     *
-     * This function is equivalent to `task().spawn(f)`.
-     */
-
-    task().spawn(f)
+    let mut task = task();
+    task.spawn(f)
 }
 
+/// Creates a child task unlinked from the current one. If either this
+/// task or the child task fails, the other will not be killed.
 pub fn spawn_unlinked(f: ~fn()) {
-    /*!
-     * Creates a child task unlinked from the current one. If either this
-     * task or the child task fails, the other will not be killed.
-     */
-
-    task().unlinked().spawn(f)
+    let mut task = task();
+    task.unlinked();
+    task.spawn(f)
 }
 
 pub fn spawn_supervised(f: ~fn()) {
@@ -497,7 +434,9 @@ pub fn spawn_supervised(f: ~fn()) {
      * the child will be killed.
      */
 
-    task().supervised().spawn(f)
+    let mut task = task();
+    task.supervised();
+    task.spawn(f)
 }
 
 pub fn spawn_with<A:Owned>(arg: A, f: ~fn(v: A)) {
@@ -511,7 +450,8 @@ pub fn spawn_with<A:Owned>(arg: A, f: ~fn(v: A)) {
      * This function is equivalent to `task().spawn_with(arg, f)`.
      */
 
-    task().spawn_with(arg, f)
+    let mut task = task();
+    task.spawn_with(arg, f)
 }
 
 pub fn spawn_sched(mode: SchedMode, f: ~fn()) {
@@ -527,7 +467,9 @@ pub fn spawn_sched(mode: SchedMode, f: ~fn()) {
      * greater than zero.
      */
 
-    task().sched_mode(mode).spawn(f)
+    let mut task = task();
+    task.sched_mode(mode);
+    task.spawn(f)
 }
 
 pub fn try<T:Owned>(f: ~fn() -> T) -> Result<T,()> {
@@ -538,7 +480,9 @@ pub fn try<T:Owned>(f: ~fn() -> T) -> Result<T,()> {
      * This is equivalent to task().supervised().try.
      */
 
-    task().supervised().try(f)
+    let mut task = task();
+    task.supervised();
+    task.try(f)
 }
 
 
@@ -653,12 +597,13 @@ pub unsafe fn atomically<U>(f: &fn() -> U) -> U {
 
 #[test] #[should_fail] #[ignore(cfg(windows))]
 fn test_cant_dup_task_builder() {
-    let b = task().unlinked();
-    do b.spawn { }
+    let mut builder = task();
+    builder.unlinked();
+    do builder.spawn {}
     // FIXME(#3724): For now, this is a -runtime- failure, because we haven't
     // got move mode on self. When 3724 is fixed, this test should fail to
     // compile instead, and should go in tests/compile-fail.
-    do b.spawn { } // b should have been consumed by the previous call
+    do builder.spawn {} // b should have been consumed by the previous call
 }
 
 // The following 8 tests test the following 2^3 combinations:
@@ -701,43 +646,31 @@ fn test_spawn_unlinked_sup_fail_down() {
 #[test] #[should_fail] #[ignore(cfg(windows))]
 fn test_spawn_linked_sup_fail_up() { // child fails; parent fails
     let (po, _ch) = stream::<()>();
+
     // Unidirectional "parenting" shouldn't override bidirectional linked.
     // We have to cheat with opts - the interface doesn't support them because
     // they don't make sense (redundant with task().supervised()).
-    let opts = {
-        let mut opts = default_task_opts();
-        opts.linked = true;
-        opts.supervised = true;
-        opts
-    };
+    let mut b0 = task();
+    b0.opts.linked = true;
+    b0.opts.supervised = true;
 
-    let b0 = task();
-    let b1 = TaskBuilder {
-        opts: opts,
-        can_not_copy: None,
-        .. b0
-    };
-    do b1.spawn { fail!(); }
+    do b0.spawn {
+        fail!();
+    }
     po.recv(); // We should get punted awake
 }
 #[test] #[should_fail] #[ignore(cfg(windows))]
 fn test_spawn_linked_sup_fail_down() { // parent fails; child fails
     // We have to cheat with opts - the interface doesn't support them because
     // they don't make sense (redundant with task().supervised()).
-    let opts = {
-        let mut opts = default_task_opts();
-        opts.linked = true;
-        opts.supervised = true;
-        opts
-    };
-
-    let b0 = task();
-    let b1 = TaskBuilder {
-        opts: opts,
-        can_not_copy: None,
-        .. b0
-    };
-    do b1.spawn { loop { task::yield(); } }
+    let mut b0 = task();
+    b0.opts.linked = true;
+    b0.opts.supervised = true;
+    do b0.spawn {
+        loop {
+            task::yield();
+        }
+    }
     fail!(); // *both* mechanisms would be wrong if this didn't kill the child
 }
 #[test] #[should_fail] #[ignore(cfg(windows))]
@@ -756,7 +689,13 @@ fn test_spawn_linked_unsup_fail_down() { // parent fails; child fails
 #[test] #[should_fail] #[ignore(cfg(windows))]
 fn test_spawn_linked_unsup_default_opts() { // parent fails; child fails
     // Make sure the above test is the same as this one.
-    do task().linked().spawn { loop { task::yield(); } }
+    let mut builder = task();
+    builder.linked();
+    do builder.spawn {
+        loop {
+            task::yield();
+        }
+    }
     fail!();
 }
 
@@ -814,7 +753,8 @@ fn test_spawn_linked_sup_propagate_sibling() {
 #[test]
 fn test_run_basic() {
     let (po, ch) = stream::<()>();
-    do task().spawn {
+    let mut builder = task();
+    do builder.spawn {
         ch.send(());
     }
     po.recv();
@@ -822,24 +762,24 @@ fn test_run_basic() {
 
 #[cfg(test)]
 struct Wrapper {
-    mut f: Option<Chan<()>>
+    f: Option<Chan<()>>
 }
 
 #[test]
 fn test_add_wrapper() {
     let (po, ch) = stream::<()>();
-    let b0 = task();
-    let ch = Wrapper { f: Some(ch) };
-    let b1 = do b0.add_wrapper |body| {
-        let ch = Wrapper { f: Some(ch.f.swap_unwrap()) };
+    let mut b0 = task();
+    let ch = Cell(ch);
+    do b0.add_wrapper |body| {
+        let ch = Cell(ch.take());
         let result: ~fn() = || {
-            let ch = ch.f.swap_unwrap();
+            let mut ch = ch.take();
             body();
             ch.send(());
         };
         result
     };
-    do b1.spawn { }
+    do b0.spawn { }
     po.recv();
 }
 
@@ -847,12 +787,16 @@ fn test_add_wrapper() {
 #[ignore(cfg(windows))]
 fn test_future_result() {
     let mut result = None;
-    do task().future_result(|+r| { result = Some(r); }).spawn { }
+    let mut builder = task();
+    builder.future_result(|r| result = Some(r));
+    do builder.spawn {}
     assert!(result.unwrap().recv() == Success);
 
     result = None;
-    do task().future_result(|+r|
-        { result = Some(r); }).unlinked().spawn {
+    let mut builder = task();
+    builder.future_result(|r| result = Some(r));
+    builder.unlinked();
+    do builder.spawn {
         fail!();
     }
     assert!(result.unwrap().recv() == Failure);
@@ -860,7 +804,9 @@ fn test_future_result() {
 
 #[test] #[should_fail] #[ignore(cfg(windows))]
 fn test_back_to_the_future_result() {
-    let _ = task().future_result(util::ignore).future_result(util::ignore);
+    let mut builder = task();
+    builder.future_result(util::ignore);
+    builder.future_result(util::ignore);
 }
 
 #[test]
@@ -922,12 +868,12 @@ fn test_spawn_sched_childs_on_default_sched() {
     // Assuming tests run on the default scheduler
     let default_id = unsafe { rt::rust_get_sched_id() };
 
-    let ch = Wrapper { f: Some(ch) };
+    let ch = Cell(ch);
     do spawn_sched(SingleThreaded) {
         let parent_sched_id = unsafe { rt::rust_get_sched_id() };
-        let ch = Wrapper { f: Some(ch.f.swap_unwrap()) };
+        let ch = Cell(ch.take());
         do spawn {
-            let ch = ch.f.swap_unwrap();
+            let ch = ch.take();
             let child_sched_id = unsafe { rt::rust_get_sched_id() };
             assert!(parent_sched_id != child_sched_id);
             assert!(child_sched_id == default_id);
@@ -1035,7 +981,8 @@ fn test_avoid_copying_the_body_spawn() {
 #[test]
 fn test_avoid_copying_the_body_task_spawn() {
     do avoid_copying_the_body |f| {
-        do task().spawn || {
+        let mut builder = task();
+        do builder.spawn || {
             f();
         }
     }
@@ -1062,7 +1009,9 @@ fn test_avoid_copying_the_body_unlinked() {
 #[test]
 fn test_platform_thread() {
     let (po, ch) = stream();
-    do task().sched_mode(PlatformThread).spawn {
+    let mut builder = task();
+    builder.sched_mode(PlatformThread);
+    do builder.spawn {
         ch.send(());
     }
     po.recv();
diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs
index 267250b3642..19c417dfdfc 100644
--- a/src/libcore/task/spawn.rs
+++ b/src/libcore/task/spawn.rs
@@ -72,6 +72,7 @@
 
 #[doc(hidden)]; // FIXME #3538
 
+use cast::transmute;
 use cast;
 use cell::Cell;
 use container::Map;
@@ -117,10 +118,10 @@ pub fn taskset_each(tasks: &TaskSet, blk: &fn(v: *rust_task) -> bool) {
 struct TaskGroupData {
     // All tasks which might kill this group. When this is empty, the group
     // can be "GC"ed (i.e., its link in the ancestor list can be removed).
-    mut members:     TaskSet,
+    members:     TaskSet,
     // All tasks unidirectionally supervised by (directly or transitively)
     // tasks in this group.
-    mut descendants: TaskSet,
+    descendants: TaskSet,
 }
 type TaskGroupArc = unstable::Exclusive<Option<TaskGroupData>>;
 
@@ -145,11 +146,11 @@ struct AncestorNode {
     // Hence we assert that this counter monotonically decreases as we
     // approach the tail of the list.
     // FIXME(#3068): Make the generation counter togglable with #[cfg(debug)].
-    generation:       uint,
-    // Should really be an immutable non-option. This way appeases borrowck.
-    mut parent_group: Option<TaskGroupArc>,
+    generation:     uint,
+    // Should really be a non-option. This way appeases borrowck.
+    parent_group:   Option<TaskGroupArc>,
     // Recursive rest of the list.
-    mut ancestors:    AncestorList,
+    ancestors:      AncestorList,
 }
 
 struct AncestorList(Option<unstable::Exclusive<AncestorNode>>);
@@ -301,22 +302,26 @@ fn each_ancestor(list:        &mut AncestorList,
 
 // One of these per task.
 struct TCB {
-    me:            *rust_task,
+    me:         *rust_task,
     // List of tasks with whose fates this one's is intertwined.
-    tasks:         TaskGroupArc, // 'none' means the group has failed.
+    tasks:      TaskGroupArc, // 'none' means the group has failed.
     // Lists of tasks who will kill us if they fail, but whom we won't kill.
-    mut ancestors: AncestorList,
-    is_main:       bool,
-    notifier:      Option<AutoNotify>,
+    ancestors:  AncestorList,
+    is_main:    bool,
+    notifier:   Option<AutoNotify>,
 }
 
 impl Drop for TCB {
     // Runs on task exit.
     fn finalize(&self) {
         unsafe {
+            let this: &mut TCB = transmute(self);
+
             // If we are failing, the whole taskgroup needs to die.
             if rt::rust_task_is_unwinding(self.me) {
-                for self.notifier.each |x| { x.failed = true; }
+                for this.notifier.each_mut |x| {
+                    x.failed = true;
+                }
                 // Take everybody down with us.
                 do access_group(&self.tasks) |tg| {
                     kill_taskgroup(tg, self.me, self.is_main);
@@ -331,16 +336,21 @@ impl Drop for TCB {
             // with our own taskgroup, so long as both happen before we die.
             // We remove ourself from every ancestor we can, so no cleanup; no
             // break.
-            for each_ancestor(&mut self.ancestors, None) |ancestor_group| {
+            for each_ancestor(&mut this.ancestors, None) |ancestor_group| {
                 leave_taskgroup(ancestor_group, self.me, false);
             };
         }
     }
 }
 
-fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList,
-       is_main: bool, notifier: Option<AutoNotify>) -> TCB {
-    for notifier.each |x| { x.failed = false; }
+fn TCB(me: *rust_task,
+       tasks: TaskGroupArc,
+       ancestors: AncestorList,
+       is_main: bool,
+       mut notifier: Option<AutoNotify>) -> TCB {
+    for notifier.each_mut |x| {
+        x.failed = false;
+    }
 
     TCB {
         me: me,
@@ -353,7 +363,7 @@ fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList,
 
 struct AutoNotify {
     notify_chan: Chan<TaskResult>,
-    mut failed:  bool,
+    failed: bool,
 }
 
 impl Drop for AutoNotify {
@@ -375,9 +385,12 @@ fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task,
     let newstate = util::replace(&mut *state, None);
     // If 'None', the group was failing. Can't enlist.
     if newstate.is_some() {
-        let group = newstate.unwrap();
-        taskset_insert(if is_member { &mut group.members }
-                       else         { &mut group.descendants }, me);
+        let mut group = newstate.unwrap();
+        taskset_insert(if is_member {
+            &mut group.members
+        } else {
+            &mut group.descendants
+        }, me);
         *state = Some(group);
         true
     } else {
@@ -391,9 +404,12 @@ fn leave_taskgroup(state: TaskGroupInner, me: *rust_task,
     let newstate = util::replace(&mut *state, None);
     // If 'None', already failing and we've already gotten a kill signal.
     if newstate.is_some() {
-        let group = newstate.unwrap();
-        taskset_remove(if is_member { &mut group.members }
-                       else         { &mut group.descendants }, me);
+        let mut group = newstate.unwrap();
+        taskset_remove(if is_member {
+            &mut group.members
+        } else {
+            &mut group.descendants
+        }, me);
         *state = Some(group);
     }
 }
@@ -451,23 +467,30 @@ fn gen_child_taskgroup(linked: bool, supervised: bool)
         /*##################################################################*
          * Step 1. Get spawner's taskgroup info.
          *##################################################################*/
-        let spawner_group = match local_get(OldHandle(spawner), taskgroup_key!()) {
-            None => {
-                // Main task, doing first spawn ever. Lazily initialise here.
-                let mut members = new_taskset();
-                taskset_insert(&mut members, spawner);
-                let tasks = unstable::exclusive(Some(TaskGroupData {
-                    members: members,
-                    descendants: new_taskset(),
-                }));
-                // Main task/group has no ancestors, no notifier, etc.
-                let group =
-                    @TCB(spawner, tasks, AncestorList(None), true, None);
-                local_set(OldHandle(spawner), taskgroup_key!(), group);
-                group
-            }
-            Some(group) => group
-        };
+        let mut spawner_group: @@mut TCB =
+            match local_get(OldHandle(spawner), taskgroup_key!()) {
+                None => {
+                    // Main task, doing first spawn ever. Lazily initialise
+                    // here.
+                    let mut members = new_taskset();
+                    taskset_insert(&mut members, spawner);
+                    let tasks = unstable::exclusive(Some(TaskGroupData {
+                        members: members,
+                        descendants: new_taskset(),
+                    }));
+                    // Main task/group has no ancestors, no notifier, etc.
+                    let group = @@mut TCB(spawner,
+                                          tasks,
+                                          AncestorList(None),
+                                          true,
+                                          None);
+                    local_set(OldHandle(spawner), taskgroup_key!(), group);
+                    group
+                }
+                Some(group) => group
+            };
+        let spawner_group: &mut TCB = *spawner_group;
+
         /*##################################################################*
          * Step 2. Process spawn options for child.
          *##################################################################*/
@@ -557,7 +580,7 @@ fn spawn_raw_newsched(_opts: TaskOpts, f: ~fn()) {
     sched.schedule_new_task(task);
 }
 
-fn spawn_raw_oldsched(opts: TaskOpts, f: ~fn()) {
+fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) {
 
     let (child_tg, ancestors, is_main) =
         gen_child_taskgroup(opts.linked, opts.supervised);
@@ -624,8 +647,11 @@ fn spawn_raw_oldsched(opts: TaskOpts, f: ~fn()) {
             };
 
             if enlist_many(child, &child_arc, &mut ancestors) {
-                let group = @TCB(child, child_arc, ancestors,
-                                 is_main, notifier);
+                let group = @@mut TCB(child,
+                                      child_arc,
+                                      ancestors,
+                                      is_main,
+                                      notifier);
                 unsafe {
                     local_set(OldHandle(child), taskgroup_key!(), group);
                 }
diff --git a/src/libcore/tuple.rs b/src/libcore/tuple.rs
index 6da22657906..b29a4e55426 100644
--- a/src/libcore/tuple.rs
+++ b/src/libcore/tuple.rs
@@ -14,7 +14,7 @@ use clone::Clone;
 use kinds::Copy;
 use vec;
 
-#[cfg(notest)] use cmp::{Eq, Ord};
+#[cfg(not(test))] use cmp::{Eq, Ord};
 
 pub trait CopyableTuple<T, U> {
     fn first(&self) -> T;
@@ -122,7 +122,7 @@ impl<A:Copy,B:Copy> ExtendedTupleOps<A,B> for (~[A], ~[B]) {
     }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<A:Eq> Eq for (A,) {
     #[inline(always)]
     fn eq(&self, other: &(A,)) -> bool {
@@ -138,7 +138,7 @@ impl<A:Eq> Eq for (A,) {
     fn ne(&self, other: &(A,)) -> bool { !(*self).eq(other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<A:Ord> Ord for (A,) {
     #[inline(always)]
     fn lt(&self, other: &(A,)) -> bool {
@@ -161,7 +161,7 @@ impl<A:Ord> Ord for (A,) {
     fn gt(&self, other: &(A,)) -> bool { other.lt(&(*self))  }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<A:Eq,B:Eq> Eq for (A, B) {
     #[inline(always)]
     fn eq(&self, other: &(A, B)) -> bool {
@@ -177,7 +177,7 @@ impl<A:Eq,B:Eq> Eq for (A, B) {
     fn ne(&self, other: &(A, B)) -> bool { !(*self).eq(other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<A:Ord,B:Ord> Ord for (A, B) {
     #[inline(always)]
     fn lt(&self, other: &(A, B)) -> bool {
@@ -202,7 +202,7 @@ impl<A:Ord,B:Ord> Ord for (A, B) {
     fn gt(&self, other: &(A, B)) -> bool { (*other).lt(&(*self))  }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<A:Eq,B:Eq,C:Eq> Eq for (A, B, C) {
     #[inline(always)]
     fn eq(&self, other: &(A, B, C)) -> bool {
@@ -219,7 +219,7 @@ impl<A:Eq,B:Eq,C:Eq> Eq for (A, B, C) {
     fn ne(&self, other: &(A, B, C)) -> bool { !(*self).eq(other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<A:Ord,B:Ord,C:Ord> Ord for (A, B, C) {
     #[inline(always)]
     fn lt(&self, other: &(A, B, C)) -> bool {
diff --git a/src/libcore/unstable.rs b/src/libcore/unstable.rs
index 4a69de26f6b..25e4d07b01d 100644
--- a/src/libcore/unstable.rs
+++ b/src/libcore/unstable.rs
@@ -30,10 +30,12 @@ pub mod weak_task;
 pub mod exchange_alloc;
 #[path = "unstable/intrinsics.rs"]
 pub mod intrinsics;
+#[path = "unstable/simd.rs"]
+pub mod simd;
 #[path = "unstable/extfmt.rs"]
 pub mod extfmt;
 #[path = "unstable/lang.rs"]
-#[cfg(notest)]
+#[cfg(not(test))]
 pub mod lang;
 
 mod rustrt {
@@ -233,17 +235,30 @@ pub impl LittleLock {
     }
 }
 
-struct ExData<T> { lock: LittleLock, failed: bool, data: T, }
+struct ExData<T> {
+    lock: LittleLock,
+    failed: bool,
+    data: T,
+}
+
 /**
  * An arc over mutable data that is protected by a lock. For library use only.
  */
-pub struct Exclusive<T> { x: SharedMutableState<ExData<T>> }
+pub struct Exclusive<T> {
+    x: SharedMutableState<ExData<T>>
+}
 
 pub fn exclusive<T:Owned>(user_data: T) -> Exclusive<T> {
     let data = ExData {
-        lock: LittleLock(), failed: false, data: user_data
+        lock: LittleLock(),
+        failed: false,
+        data: user_data
     };
-    Exclusive { x: unsafe { shared_mutable_state(data) } }
+    Exclusive {
+        x: unsafe {
+            shared_mutable_state(data)
+        }
+    }
 }
 
 impl<T:Owned> Clone for Exclusive<T> {
diff --git a/src/libcore/unstable/at_exit.rs b/src/libcore/unstable/at_exit.rs
index bc4ec620aa8..39c930d415f 100644
--- a/src/libcore/unstable/at_exit.rs
+++ b/src/libcore/unstable/at_exit.rs
@@ -62,14 +62,17 @@ fn exit_runner(exit_fns: *ExitFunctions) {
     // give us ownership of the array of functions
     let mut exit_fns_vec = unsafe { vec::from_buf(start, count as uint) };
     // Let's not make any promises about execution order
-    rand::rng().shuffle_mut(exit_fns_vec);
+    let mut rng = rand::rng();
+    rng.shuffle_mut(exit_fns_vec);
 
     debug!("running %u exit functions", exit_fns_vec.len());
 
     while !exit_fns_vec.is_empty() {
         match exit_fns_vec.pop() {
             ~f => {
-                task::task().supervised().spawn(f);
+                let mut task = task::task();
+                task.supervised();
+                task.spawn(f);
             }
         }
     }
diff --git a/src/libcore/unstable/intrinsics.rs b/src/libcore/unstable/intrinsics.rs
index 65cfc6ec1fe..363dbb84c1c 100644
--- a/src/libcore/unstable/intrinsics.rs
+++ b/src/libcore/unstable/intrinsics.rs
@@ -34,8 +34,8 @@ pub extern "rust-intrinsic" {
 
     pub fn size_of<T>() -> uint;
 
-    pub fn move_val<T>(dst: &mut T, +src: T);
-    pub fn move_val_init<T>(dst: &mut T, +src: T);
+    pub fn move_val<T>(dst: &mut T, src: T);
+    pub fn move_val_init<T>(dst: &mut T, src: T);
 
     pub fn min_align_of<T>() -> uint;
     pub fn pref_align_of<T>() -> uint;
diff --git a/src/libcore/unstable/simd.rs b/src/libcore/unstable/simd.rs
new file mode 100644
index 00000000000..a05f6e8af5a
--- /dev/null
+++ b/src/libcore/unstable/simd.rs
@@ -0,0 +1,43 @@
+// Copyright 2013 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.
+
+//! SIMD vectors
+
+#[allow(non_camel_case_types)];
+
+#[simd]
+pub struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8);
+
+#[simd]
+pub struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16);
+
+#[simd]
+pub struct i32x4(i32, i32, i32, i32);
+
+#[simd]
+pub struct i64x2(i64, i64);
+
+#[simd]
+pub struct u8x16(u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8);
+
+#[simd]
+pub struct u16x8(u16, u16, u16, u16, u16, u16, u16, u16);
+
+#[simd]
+pub struct u32x4(u32, u32, u32, u32);
+
+#[simd]
+pub struct u64x2(u64, u64);
+
+#[simd]
+pub struct f32x4(f32, f32, f32, f32);
+
+#[simd]
+pub struct f64x2(f64, f64);
diff --git a/src/libcore/unstable/weak_task.rs b/src/libcore/unstable/weak_task.rs
index 6edbdcb51b0..8670bcfcd9a 100644
--- a/src/libcore/unstable/weak_task.rs
+++ b/src/libcore/unstable/weak_task.rs
@@ -72,7 +72,9 @@ fn create_global_service() -> ~WeakTaskService {
     let chan = SharedChan::new(chan);
     let chan_clone = chan.clone();
 
-    do task().unlinked().spawn {
+    let mut task = task();
+    task.unlinked();
+    do task.spawn {
         debug!("running global weak task service");
         let port = Cell(port.take());
         do (|| {
@@ -189,12 +191,14 @@ fn test_select_stream_and_oneshot() {
     use comm::select2i;
     use either::{Left, Right};
 
-    let (port, chan) = stream();
+    let mut (port, chan) = stream();
+    let port = Cell(port);
     let (waitport, waitchan) = stream();
     do spawn {
         unsafe {
-            do weaken_task |signal| {
-                match select2i(&port, &signal) {
+            do weaken_task |mut signal| {
+                let mut port = port.take();
+                match select2i(&mut port, &mut signal) {
                     Left(*) => (),
                     Right(*) => fail!()
                 }
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index bd8a1c8a156..bf8f5b4ce18 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -30,7 +30,7 @@ use uint;
 use unstable::intrinsics;
 use vec;
 
-#[cfg(notest)] use cmp::Equiv;
+#[cfg(not(test))] use cmp::Equiv;
 
 pub mod rustrt {
     use libc;
@@ -42,13 +42,13 @@ pub mod rustrt {
         // These names are terrible. reserve_shared applies
         // to ~[] and reserve_shared_actual applies to @[].
         #[fast_ffi]
-        unsafe fn vec_reserve_shared(++t: *sys::TypeDesc,
-                                     ++v: **raw::VecRepr,
-                                     ++n: libc::size_t);
+        unsafe fn vec_reserve_shared(t: *sys::TypeDesc,
+                                     v: **raw::VecRepr,
+                                     n: libc::size_t);
         #[fast_ffi]
-        unsafe fn vec_reserve_shared_actual(++t: *sys::TypeDesc,
-                                            ++v: **raw::VecRepr,
-                                            ++n: libc::size_t);
+        unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc,
+                                            v: **raw::VecRepr,
+                                            n: libc::size_t);
     }
 }
 
@@ -1656,7 +1656,7 @@ fn equals<T: TotalEq>(a: &[T], b: &[T]) -> bool {
     true
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<'self,T:Eq> Eq for &'self [T] {
     #[inline(always)]
     fn eq(&self, other: & &'self [T]) -> bool { eq(*self, *other) }
@@ -1664,7 +1664,7 @@ impl<'self,T:Eq> Eq for &'self [T] {
     fn ne(&self, other: & &'self [T]) -> bool { !self.eq(other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T:Eq> Eq for ~[T] {
     #[inline(always)]
     fn eq(&self, other: &~[T]) -> bool { eq(*self, *other) }
@@ -1672,7 +1672,7 @@ impl<T:Eq> Eq for ~[T] {
     fn ne(&self, other: &~[T]) -> bool { !self.eq(other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T:Eq> Eq for @[T] {
     #[inline(always)]
     fn eq(&self, other: &@[T]) -> bool { eq(*self, *other) }
@@ -1680,25 +1680,25 @@ impl<T:Eq> Eq for @[T] {
     fn ne(&self, other: &@[T]) -> bool { !self.eq(other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<'self,T:TotalEq> TotalEq for &'self [T] {
     #[inline(always)]
     fn equals(&self, other: & &'self [T]) -> bool { equals(*self, *other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T:TotalEq> TotalEq for ~[T] {
     #[inline(always)]
     fn equals(&self, other: &~[T]) -> bool { equals(*self, *other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T:TotalEq> TotalEq for @[T] {
     #[inline(always)]
     fn equals(&self, other: &@[T]) -> bool { equals(*self, *other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<'self,T:Eq> Equiv<~[T]> for &'self [T] {
     #[inline(always)]
     fn equiv(&self, other: &~[T]) -> bool { eq(*self, *other) }
@@ -1720,19 +1720,19 @@ fn cmp<T: TotalOrd>(a: &[T], b: &[T]) -> Ordering {
     a.len().cmp(&b.len())
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<'self,T:TotalOrd> TotalOrd for &'self [T] {
     #[inline(always)]
     fn cmp(&self, other: & &'self [T]) -> Ordering { cmp(*self, *other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T: TotalOrd> TotalOrd for ~[T] {
     #[inline(always)]
     fn cmp(&self, other: &~[T]) -> Ordering { cmp(*self, *other) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T: TotalOrd> TotalOrd for @[T] {
     #[inline(always)]
     fn cmp(&self, other: &@[T]) -> Ordering { cmp(*self, *other) }
@@ -1757,7 +1757,7 @@ fn le<T:Ord>(a: &[T], b: &[T]) -> bool { !lt(b, a) }
 fn ge<T:Ord>(a: &[T], b: &[T]) -> bool { !lt(a, b) }
 fn gt<T:Ord>(a: &[T], b: &[T]) -> bool { lt(b, a)  }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<'self,T:Ord> Ord for &'self [T] {
     #[inline(always)]
     fn lt(&self, other: & &'self [T]) -> bool { lt((*self), (*other)) }
@@ -1769,7 +1769,7 @@ impl<'self,T:Ord> Ord for &'self [T] {
     fn gt(&self, other: & &'self [T]) -> bool { gt((*self), (*other)) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T:Ord> Ord for ~[T] {
     #[inline(always)]
     fn lt(&self, other: &~[T]) -> bool { lt((*self), (*other)) }
@@ -1781,7 +1781,7 @@ impl<T:Ord> Ord for ~[T] {
     fn gt(&self, other: &~[T]) -> bool { gt((*self), (*other)) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 impl<T:Ord> Ord for @[T] {
     #[inline(always)]
     fn lt(&self, other: &@[T]) -> bool { lt((*self), (*other)) }
@@ -1793,7 +1793,7 @@ impl<T:Ord> Ord for @[T] {
     fn gt(&self, other: &@[T]) -> bool { gt((*self), (*other)) }
 }
 
-#[cfg(notest)]
+#[cfg(not(test))]
 pub mod traits {
     use kinds::Copy;
     use ops::Add;
diff --git a/src/libfuzzer/fuzzer.rc b/src/libfuzzer/fuzzer.rc
index 7c93d867f50..33e970c305a 100644
--- a/src/libfuzzer/fuzzer.rc
+++ b/src/libfuzzer/fuzzer.rc
@@ -263,7 +263,7 @@ pub fn under(n: uint, it: &fn(uint)) {
     while i < n { it(i); i += 1u; }
 }
 
-pub fn as_str(f: @fn(+x: @io::Writer)) -> ~str {
+pub fn as_str(f: @fn(x: @io::Writer)) -> ~str {
     io::with_str_writer(f)
 }
 
diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs
index c34c7fe303e..3b5c90ec1f9 100644
--- a/src/librustc/back/link.rs
+++ b/src/librustc/back/link.rs
@@ -22,9 +22,9 @@ use util::ppaux;
 
 use core::hash::Streaming;
 use core::hash;
-use core::io::WriterUtil;
 use core::libc::{c_int, c_uint};
 use core::os::consts::{macos, freebsd, linux, android, win32};
+use core::rt::io::Writer;
 use core::run;
 use syntax::ast;
 use syntax::ast_map::{path, path_mod, path_name};
@@ -41,6 +41,11 @@ pub enum output_type {
     output_type_exe,
 }
 
+fn write_string<W:Writer>(writer: &mut W, string: &str) {
+    let buffer = str::as_bytes_slice(string);
+    writer.write(buffer);
+}
+
 pub fn llvm_err(sess: Session, msg: ~str) -> ! {
     unsafe {
         let cstr = llvm::LLVMRustGetLastError();
@@ -458,9 +463,11 @@ pub mod write {
  *
  */
 
-pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
-                   symbol_hasher: &hash::State) -> LinkMeta {
-
+pub fn build_link_meta(sess: Session,
+                       c: &ast::crate,
+                       output: &Path,
+                       symbol_hasher: &mut hash::State)
+                       -> LinkMeta {
     struct ProvidedMetas {
         name: Option<@str>,
         vers: Option<@str>,
@@ -498,7 +505,7 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
     }
 
     // This calculates CMH as defined above
-    fn crate_meta_extras_hash(symbol_hasher: &hash::State,
+    fn crate_meta_extras_hash(symbol_hasher: &mut hash::State,
                               cmh_items: ~[@ast::meta_item],
                               dep_hashes: ~[~str]) -> @str {
         fn len_and_str(s: &str) -> ~str {
@@ -511,17 +518,17 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
 
         let cmh_items = attr::sort_meta_items(cmh_items);
 
-        fn hash(symbol_hasher: &hash::State, m: &@ast::meta_item) {
+        fn hash(symbol_hasher: &mut hash::State, m: &@ast::meta_item) {
             match m.node {
               ast::meta_name_value(key, value) => {
-                symbol_hasher.write_str(len_and_str(*key));
-                symbol_hasher.write_str(len_and_str_lit(value));
+                write_string(symbol_hasher, len_and_str(*key));
+                write_string(symbol_hasher, len_and_str_lit(value));
               }
               ast::meta_word(name) => {
-                symbol_hasher.write_str(len_and_str(*name));
+                write_string(symbol_hasher, len_and_str(*name));
               }
               ast::meta_list(name, ref mis) => {
-                symbol_hasher.write_str(len_and_str(*name));
+                write_string(symbol_hasher, len_and_str(*name));
                 for mis.each |m_| {
                     hash(symbol_hasher, m_);
                 }
@@ -535,7 +542,7 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
         }
 
         for dep_hashes.each |dh| {
-            symbol_hasher.write_str(len_and_str(*dh));
+            write_string(symbol_hasher, len_and_str(*dh));
         }
 
     // tjc: allocation is unfortunate; need to change core::hash
@@ -596,23 +603,26 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path,
     }
 }
 
-pub fn truncated_hash_result(symbol_hasher: &hash::State) -> ~str {
+pub fn truncated_hash_result(symbol_hasher: &mut hash::State) -> ~str {
     symbol_hasher.result_str()
 }
 
 
 // This calculates STH for a symbol, as defined above
-pub fn symbol_hash(tcx: ty::ctxt, symbol_hasher: &hash::State, t: ty::t,
-               link_meta: LinkMeta) -> @str {
+pub fn symbol_hash(tcx: ty::ctxt,
+                   symbol_hasher: &mut hash::State,
+                   t: ty::t,
+                   link_meta: LinkMeta)
+                   -> @str {
     // NB: do *not* use abbrevs here as we want the symbol names
     // to be independent of one another in the crate.
 
     symbol_hasher.reset();
-    symbol_hasher.write_str(link_meta.name);
-    symbol_hasher.write_str(~"-");
-    symbol_hasher.write_str(link_meta.extras_hash);
-    symbol_hasher.write_str(~"-");
-    symbol_hasher.write_str(encoder::encoded_ty(tcx, t));
+    write_string(symbol_hasher, link_meta.name);
+    write_string(symbol_hasher, ~"-");
+    write_string(symbol_hasher, link_meta.extras_hash);
+    write_string(symbol_hasher, ~"-");
+    write_string(symbol_hasher, encoder::encoded_ty(tcx, t));
     let mut hash = truncated_hash_result(symbol_hasher);
     // Prefix with _ so that it never blends into adjacent digits
     str::unshift_char(&mut hash, '_');
diff --git a/src/librustc/back/upcall.rs b/src/librustc/back/upcall.rs
index 8fcc5234e8b..4d2ea4eb4a6 100644
--- a/src/librustc/back/upcall.rs
+++ b/src/librustc/back/upcall.rs
@@ -34,9 +34,9 @@ pub fn declare_upcalls(targ_cfg: @session::config,
     fn nothrow(f: ValueRef) -> ValueRef {
         base::set_no_unwind(f); f
     }
-    let d: &fn(+a: ~str, +b: ~[TypeRef], +c: TypeRef) -> ValueRef =
+    let d: &fn(a: ~str, b: ~[TypeRef], c: TypeRef) -> ValueRef =
         |a,b,c| decl(llmod, ~"upcall_", a, b, c);
-    let dv: &fn(+a: ~str, +b: ~[TypeRef]) -> ValueRef =
+    let dv: &fn(a: ~str, b: ~[TypeRef]) -> ValueRef =
         |a,b| decl(llmod, ~"upcall_", a, b, T_void());
 
     let int_t = T_int(targ_cfg);
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index 5e8dab0f772..cf77f81a492 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -119,9 +119,8 @@ pub fn build_configuration(sess: Session, argv0: @~str, input: &input) ->
     let default_cfg = default_configuration(sess, argv0, input);
     let user_cfg = /*bad*/copy sess.opts.cfg;
     // If the user wants a test runner, then add the test cfg
-    let user_cfg = append_configuration(
-        user_cfg,
-        if sess.opts.test { ~"test" } else { ~"notest" });
+    let user_cfg = if sess.opts.test { append_configuration(user_cfg, ~"test") }
+                   else { user_cfg };
     // If the user requested GC, then add the GC cfg
     let user_cfg = append_configuration(
         user_cfg,
@@ -225,6 +224,9 @@ pub fn compile_rest(sess: Session,
         time(time_passes, ~"resolution", ||
              middle::resolve::resolve_crate(sess, lang_items, crate));
 
+    time(time_passes, ~"looking for entry point",
+         || middle::entry::find_entry_point(sess, crate, ast_map));
+
     let freevars = time(time_passes, ~"freevar finding", ||
         freevars::annotate_freevars(def_map, crate));
 
diff --git a/src/librustc/front/intrinsic.rs b/src/librustc/front/intrinsic.rs
index 452623c2742..ece53451ccf 100644
--- a/src/librustc/front/intrinsic.rs
+++ b/src/librustc/front/intrinsic.rs
@@ -132,7 +132,7 @@ pub mod intrinsic {
         #[abi = "rust-intrinsic"]
         pub extern "rust-intrinsic" {
             pub fn get_tydesc<T>() -> *();
-            pub fn visit_tydesc(++td: *TyDesc, ++tv: @TyVisitor);
+            pub fn visit_tydesc(td: *TyDesc, tv: @TyVisitor);
         }
     }
 }
diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs
index fbb3380554d..36d5a8e3cfe 100644
--- a/src/librustc/lib/llvm.rs
+++ b/src/librustc/lib/llvm.rs
@@ -1561,12 +1561,18 @@ pub mod llvm {
                                        Name: *c_char) -> ValueRef;
 
         /* Atomic Operations */
-        pub unsafe fn LLVMBuildAtomicCmpXchg(B: BuilderRef, LHS: ValueRef,
-                                  CMP: ValueRef, RHS: ValueRef,
-                                  ++Order: AtomicOrdering) -> ValueRef;
-        pub unsafe fn LLVMBuildAtomicRMW(B: BuilderRef, ++Op: AtomicBinOp,
-                              LHS: ValueRef, RHS: ValueRef,
-                              ++Order: AtomicOrdering) -> ValueRef;
+        pub unsafe fn LLVMBuildAtomicCmpXchg(B: BuilderRef,
+                                             LHS: ValueRef,
+                                             CMP: ValueRef,
+                                             RHS: ValueRef,
+                                             Order: AtomicOrdering)
+                                             -> ValueRef;
+        pub unsafe fn LLVMBuildAtomicRMW(B: BuilderRef,
+                                         Op: AtomicBinOp,
+                                         LHS: ValueRef,
+                                         RHS: ValueRef,
+                                         Order: AtomicOrdering)
+                                         -> ValueRef;
 
         /* Selected entries from the downcasts. */
         #[fast_ffi]
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 1e6bb397068..fd35a4425d8 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -204,18 +204,6 @@ fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) {
     }
 }
 
-fn field_mutability(d: ebml::Doc) -> ast::struct_mutability {
-    // Use maybe_get_doc in case it's a method
-    reader::maybe_get_doc(d, tag_struct_mut).map_default(
-        ast::struct_immutable,
-        |d| {
-            match reader::doc_as_u8(*d) as char {
-              'm' => ast::struct_mutable,
-              _   => ast::struct_immutable
-            }
-        })
-}
-
 fn variant_disr_val(d: ebml::Doc) -> Option<int> {
     do reader::maybe_get_doc(d, tag_disr_val).chain |val_doc| {
         int::parse_bytes(reader::doc_data(val_doc), 10u)
@@ -923,12 +911,10 @@ pub fn get_struct_fields(intr: @ident_interner, cdata: cmd, id: ast::node_id)
         if f == PublicField || f == PrivateField || f == InheritedField {
             let name = item_name(intr, an_item);
             let did = item_def_id(an_item, cdata);
-            let mt = field_mutability(an_item);
             result.push(ty::field_ty {
                 ident: name,
                 id: did, vis:
                 struct_field_family_to_visibility(f),
-                mutability: mt,
             });
         }
     }
@@ -938,7 +924,6 @@ pub fn get_struct_fields(intr: @ident_interner, cdata: cmd, id: ast::node_id)
             ident: special_idents::unnamed_field,
             id: did,
             vis: ast::inherited,
-            mutability: ast::struct_immutable,
         });
     }
     result
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index ccf3ffcdfff..6c02ece9289 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -119,16 +119,6 @@ fn encode_region_param(ecx: @EncodeContext,
     }
 }
 
-fn encode_mutability(ebml_w: &mut writer::Encoder, mt: struct_mutability) {
-    ebml_w.start_tag(tag_struct_mut);
-    let val = match mt {
-      struct_immutable => 'a',
-      struct_mutable => 'm'
-    };
-    ebml_w.writer.write(&[val as u8]);
-    ebml_w.end_tag();
-}
-
 struct entry<T> {
     val: T,
     pos: uint
@@ -518,13 +508,9 @@ fn encode_info_for_struct(ecx: @EncodeContext,
      /* We encode both private and public fields -- need to include
         private fields to get the offsets right */
     for fields.each |field| {
-        let (nm, mt, vis) = match field.node.kind {
-            named_field(nm, mt, vis) => (nm, mt, vis),
-            unnamed_field => (
-                special_idents::unnamed_field,
-                struct_immutable,
-                inherited
-            )
+        let (nm, vis) = match field.node.kind {
+            named_field(nm, vis) => (nm, vis),
+            unnamed_field => (special_idents::unnamed_field, inherited)
         };
 
         let id = field.node.id;
@@ -537,7 +523,6 @@ fn encode_info_for_struct(ecx: @EncodeContext,
         encode_name(ecx, ebml_w, nm);
         encode_path(ecx, ebml_w, path, ast_map::path_name(nm));
         encode_type(ecx, ebml_w, node_id_to_type(tcx, id));
-        encode_mutability(ebml_w, mt);
         encode_def_id(ebml_w, local_def(id));
         ebml_w.end_tag();
     }
@@ -828,7 +813,7 @@ fn encode_info_for_item(ecx: @EncodeContext,
         needs to know*/
         for struct_def.fields.each |f| {
             match f.node.kind {
-                named_field(ident, _, vis) => {
+                named_field(ident, vis) => {
                    ebml_w.start_tag(tag_item_field);
                    encode_struct_field_family(ebml_w, vis);
                    encode_name(ecx, ebml_w, ident);
@@ -1099,7 +1084,7 @@ fn encode_index<T>(ebml_w: &mut writer::Encoder,
     for buckets.each |bucket| {
         bucket_locs.push(ebml_w.writer.tell());
         ebml_w.start_tag(tag_index_buckets_bucket);
-        for vec::each(**bucket) |elt| {
+        for (**bucket).each |elt| {
             ebml_w.start_tag(tag_index_buckets_bucket_elt);
             assert!(elt.pos < 0xffff_ffff);
             writer.write_be_u32(elt.pos as u32);
@@ -1372,41 +1357,40 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
 
     encode_hash(&mut ebml_w, ecx.link_meta.extras_hash);
 
-    let mut i = wr.pos;
+    let mut i = *wr.pos;
     let crate_attrs = synthesize_crate_attrs(ecx, crate);
     encode_attributes(&mut ebml_w, crate_attrs);
-    ecx.stats.attr_bytes = wr.pos - i;
+    ecx.stats.attr_bytes = *wr.pos - i;
 
-    i = wr.pos;
+    i = *wr.pos;
     encode_crate_deps(ecx, &mut ebml_w, ecx.cstore);
-    ecx.stats.dep_bytes = wr.pos - i;
+    ecx.stats.dep_bytes = *wr.pos - i;
 
     // Encode the language items.
-    i = wr.pos;
+    i = *wr.pos;
     encode_lang_items(ecx, &mut ebml_w);
-    ecx.stats.lang_item_bytes = wr.pos - i;
+    ecx.stats.lang_item_bytes = *wr.pos - i;
 
     // Encode the link args.
-    i = wr.pos;
+    i = *wr.pos;
     encode_link_args(ecx, &mut ebml_w);
-    ecx.stats.link_args_bytes = wr.pos - i;
+    ecx.stats.link_args_bytes = *wr.pos - i;
 
     // Encode and index the items.
     ebml_w.start_tag(tag_items);
-    i = wr.pos;
+    i = *wr.pos;
     let items_index = encode_info_for_items(ecx, &mut ebml_w, crate);
-    ecx.stats.item_bytes = wr.pos - i;
+    ecx.stats.item_bytes = *wr.pos - i;
 
-    i = wr.pos;
+    i = *wr.pos;
     let items_buckets = create_index(items_index);
     encode_index(&mut ebml_w, items_buckets, write_int);
-    ecx.stats.index_bytes = wr.pos - i;
+    ecx.stats.index_bytes = *wr.pos - i;
     ebml_w.end_tag();
 
-    ecx.stats.total_bytes = wr.pos;
+    ecx.stats.total_bytes = *wr.pos;
 
     if (tcx.sess.meta_stats()) {
-
         do wr.bytes.each |e| {
             if *e == 0 {
                 ecx.stats.zero_bytes += 1;
@@ -1438,9 +1422,11 @@ pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
     //
     //   vec::from_slice(metadata_encoding_version) +
 
+    let writer_bytes: &mut ~[u8] = wr.bytes;
+
     (do str::as_bytes(&~"rust\x00\x00\x00\x01") |bytes| {
         vec::slice(*bytes, 0, 8).to_vec()
-    }) + flate::deflate_bytes(wr.bytes)
+    }) + flate::deflate_bytes(*writer_bytes)
 }
 
 // Get the encoded string for a type
diff --git a/src/librustc/metadata/tyencode.rs b/src/librustc/metadata/tyencode.rs
index c44a8e74130..3abe5b22e1a 100644
--- a/src/librustc/metadata/tyencode.rs
+++ b/src/librustc/metadata/tyencode.rs
@@ -17,7 +17,6 @@ use core::hashmap::HashMap;
 use core::io::WriterUtil;
 use core::io;
 use core::uint;
-use core::vec;
 use syntax::abi::AbiSet;
 use syntax::ast;
 use syntax::ast::*;
@@ -398,7 +397,7 @@ fn enc_fn_sig(w: @io::Writer, cx: @ctxt, fsig: &ty::FnSig) {
 }
 
 fn enc_bounds(w: @io::Writer, cx: @ctxt, bs: @~[ty::param_bound]) {
-    for vec::each(*bs) |bound| {
+    for (*bs).each |bound| {
         match *bound {
           ty::bound_owned => w.write_char('S'),
           ty::bound_copy => w.write_char('C'),
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index f3eac7995e8..c223ff821c2 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -1237,7 +1237,7 @@ fn test_simplification() {
     let ext_cx = mk_ctxt();
     let item_in = ast::ii_item(quote_item!(
         fn new_int_alist<B:Copy>() -> alist<int, B> {
-            fn eq_int(&&a: int, &&b: int) -> bool { a == b }
+            fn eq_int(a: int, b: int) -> bool { a == b }
             return alist {eq_fn: eq_int, data: ~[]};
         }
     ).get());
diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs
index a50895aa013..09232b5bba8 100644
--- a/src/librustc/middle/check_match.rs
+++ b/src/librustc/middle/check_match.rs
@@ -366,7 +366,7 @@ pub fn missing_ctor(cx: @MatchCheckCtxt,
         }
         let variants = ty::enum_variants(cx.tcx, eid);
         if found.len() != (*variants).len() {
-            for vec::each(*variants) |v| {
+            for (*variants).each |v| {
                 if !found.contains(&(variant(v.id))) {
                     return Some(variant(v.id));
                 }
diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs
new file mode 100644
index 00000000000..9ffd0e6f22c
--- /dev/null
+++ b/src/librustc/middle/entry.rs
@@ -0,0 +1,150 @@
+// 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.
+
+use driver::session;
+use driver::session::Session;
+use syntax::parse::token::special_idents;
+use syntax::ast::{crate, node_id, item, item_fn};
+use syntax::codemap::span;
+use syntax::visit::{default_visitor, mk_vt, vt, Visitor, visit_crate, visit_item};
+use syntax::attr::{attrs_contains_name};
+use syntax::ast_map;
+use core::util;
+
+struct EntryContext {
+    session: Session,
+
+    ast_map: ast_map::map,
+
+    // The top-level function called 'main'
+    main_fn: Option<(node_id, span)>,
+
+    // The function that has attribute named 'main'
+    attr_main_fn: Option<(node_id, span)>,
+
+    // The function that has the attribute 'start' on it
+    start_fn: Option<(node_id, span)>,
+
+    // The functions that one might think are 'main' but aren't, e.g.
+    // main functions not defined at the top level. For diagnostics.
+    non_main_fns: ~[(node_id, span)],
+}
+
+type EntryVisitor = vt<@mut EntryContext>;
+
+pub fn find_entry_point(session: Session, crate: @crate, ast_map: ast_map::map) {
+
+    // FIXME #4404 android JNI hacks
+    if *session.building_library &&
+        session.targ_cfg.os != session::os_android {
+        // No need to find a main function
+        return;
+    }
+
+    let ctxt = @mut EntryContext {
+        session: session,
+        ast_map: ast_map,
+        main_fn: None,
+        attr_main_fn: None,
+        start_fn: None,
+        non_main_fns: ~[],
+    };
+
+    visit_crate(crate, ctxt, mk_vt(@Visitor {
+        visit_item: |item, ctxt, visitor| find_item(item, ctxt, visitor),
+        .. *default_visitor()
+    }));
+
+    configure_main(ctxt);
+}
+
+fn find_item(item: @item, ctxt: @mut EntryContext, visitor: EntryVisitor) {
+    match item.node {
+        item_fn(*) => {
+            if item.ident == special_idents::main {
+                match ctxt.ast_map.find(&item.id) {
+                    Some(&ast_map::node_item(_, path)) => {
+                        if path.len() == 0 {
+                            // This is a top-level function so can be 'main'
+                            if ctxt.main_fn.is_none() {
+                                ctxt.main_fn = Some((item.id, item.span));
+                            } else {
+                                ctxt.session.span_err(
+                                    item.span,
+                                    ~"multiple 'main' functions");
+                            }
+                        } else {
+                            // This isn't main
+                            ctxt.non_main_fns.push((item.id, item.span));
+                        }
+                    }
+                    _ => util::unreachable()
+                }
+            }
+
+            if attrs_contains_name(item.attrs, ~"main") {
+                if ctxt.attr_main_fn.is_none() {
+                    ctxt.attr_main_fn = Some((item.id, item.span));
+                } else {
+                    ctxt.session.span_err(
+                        item.span,
+                        ~"multiple 'main' functions");
+                }
+            }
+
+            if attrs_contains_name(item.attrs, ~"start") {
+                if ctxt.start_fn.is_none() {
+                    ctxt.start_fn = Some((item.id, item.span));
+                } else {
+                    ctxt.session.span_err(
+                        item.span,
+                        ~"multiple 'start' functions");
+                }
+            }
+        }
+        _ => ()
+    }
+
+    visit_item(item, ctxt, visitor);
+}
+
+fn configure_main(ctxt: @mut EntryContext) {
+    let this = &mut *ctxt;
+    if this.start_fn.is_some() {
+        *this.session.entry_fn = this.start_fn;
+        *this.session.entry_type = Some(session::EntryStart);
+    } else if this.attr_main_fn.is_some() {
+        *this.session.entry_fn = this.attr_main_fn;
+        *this.session.entry_type = Some(session::EntryMain);
+    } else if this.main_fn.is_some() {
+        *this.session.entry_fn = this.main_fn;
+        *this.session.entry_type = Some(session::EntryMain);
+    } else {
+        if !*this.session.building_library {
+            // No main function
+            this.session.err(~"main function not found");
+            if !this.non_main_fns.is_empty() {
+                // There were some functions named 'main' though. Try to give the user a hint.
+                this.session.note(~"the main function must be defined at the crate level \
+                                    but you have one or more functions named 'main' that are not \
+                                    defined at the crate level. Either move the definition or \
+                                    attach the `#[main]` attribute to override this behavior.");
+                for this.non_main_fns.each |&(_, span)| {
+                    this.session.span_note(span, ~"here is a function named 'main'");
+                }
+            }
+            this.session.abort_if_errors();
+        } else {
+            // If we *are* building a library, then we're on android where we still might
+            // optionally want to translate main $4404
+            assert!(this.session.targ_cfg.os == session::os_android);
+        }
+    }
+}
diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs
index 57c3e7c3b9a..0050e0f81c7 100644
--- a/src/librustc/middle/kind.rs
+++ b/src/librustc/middle/kind.rs
@@ -235,7 +235,7 @@ fn check_fn(
 }
 
 fn check_arm(a: &arm, cx: Context, v: visit::vt<Context>) {
-    for vec::each(a.pats) |p| {
+    for a.pats.each |p| {
         do pat_util::pat_bindings(cx.tcx.def_map, *p) |mode, id, span, _pth| {
             if mode == bind_by_copy {
                 let t = ty::node_id_to_type(cx.tcx, id);
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index 9ca1cc9b924..b3bd60d8ac7 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -56,7 +56,6 @@ pub enum lint {
     non_camel_case_types,
     type_limits,
     default_methods,
-    deprecated_mutable_fields,
     unused_unsafe,
 
     managed_heap_memory,
@@ -197,13 +196,6 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[
         default: deny
      }),
 
-    ("deprecated_mutable_fields",
-     LintSpec {
-        lint: deprecated_mutable_fields,
-        desc: "deprecated mutable fields in structures",
-        default: deny
-    }),
-
     ("unused_unsafe",
      LintSpec {
         lint: unused_unsafe,
@@ -455,7 +447,6 @@ fn check_item(i: @ast::item, cx: ty::ctxt) {
     check_item_heap(cx, i);
     check_item_type_limits(cx, i);
     check_item_default_methods(cx, i);
-    check_item_deprecated_mutable_fields(cx, i);
     check_item_unused_unsafe(cx, i);
     check_item_unused_mut(cx, i);
 }
@@ -640,28 +631,7 @@ fn check_item_default_methods(cx: ty::ctxt, item: @ast::item) {
     }
 }
 
-fn check_item_deprecated_mutable_fields(cx: ty::ctxt, item: @ast::item) {
-    match item.node {
-        ast::item_struct(struct_def, _) => {
-            for struct_def.fields.each |field| {
-                match field.node.kind {
-                    ast::named_field(_, ast::struct_mutable, _) => {
-                        cx.sess.span_lint(deprecated_mutable_fields,
-                                          item.id,
-                                          item.id,
-                                          field.span,
-                                          "mutable fields are deprecated");
-                    }
-                    ast::named_field(*) | ast::unnamed_field => {}
-                }
-            }
-        }
-        _ => {}
-    }
-}
-
 fn check_item_ctypes(cx: ty::ctxt, it: @ast::item) {
-
     fn check_foreign_fn(cx: ty::ctxt, fn_id: ast::node_id,
                         decl: &ast::fn_decl) {
         let tys = vec::map(decl.inputs, |a| a.ty );
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index dde4c044792..26992388b29 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -581,17 +581,7 @@ pub impl mem_categorization_ctxt {
                              f_name: ast::ident,
                              f_ty: ty::t,
                              field_id: ast::node_id) -> cmt {
-        let f_mutbl = match field_mutbl(self.tcx, base_cmt.ty,
-                                        f_name, field_id) {
-            Some(f_mutbl) => f_mutbl,
-            None => {
-                self.tcx.sess.span_bug(
-                    node.span(),
-                    fmt!("Cannot find field `%s` in type `%s`",
-                         *self.tcx.sess.str_of(f_name),
-                         ty_to_str(self.tcx, base_cmt.ty)));
-            }
-        };
+        let f_mutbl = m_imm;
         let m = self.inherited_mutability(base_cmt.mutbl, f_mutbl);
         let f_interior = interior_field(f_name, f_mutbl);
         @cmt_ {
@@ -968,11 +958,7 @@ pub fn field_mutbl(tcx: ty::ctxt,
       ty::ty_struct(did, _) => {
         for ty::lookup_struct_fields(tcx, did).each |fld| {
             if fld.ident == f_name {
-                let m = match fld.mutability {
-                  ast::struct_mutable => ast::m_mutbl,
-                  ast::struct_immutable => ast::m_imm
-                };
-                return Some(m);
+                return Some(ast::m_imm);
             }
         }
       }
@@ -981,11 +967,7 @@ pub fn field_mutbl(tcx: ty::ctxt,
           ast::def_variant(_, variant_id) => {
             for ty::lookup_struct_fields(tcx, variant_id).each |fld| {
                 if fld.ident == f_name {
-                    let m = match fld.mutability {
-                      ast::struct_mutable => ast::m_mutbl,
-                      ast::struct_immutable => ast::m_imm
-                    };
-                    return Some(m);
+                    return Some(ast::m_imm);
                 }
             }
           }
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index cdc3aa9fedb..76d35527104 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -894,17 +894,7 @@ pub fn determine_rp_in_struct_field(
         cm: @ast::struct_field,
         cx: @mut DetermineRpCtxt,
         visitor: visit::vt<@mut DetermineRpCtxt>) {
-    match cm.node.kind {
-      ast::named_field(_, ast::struct_mutable, _) => {
-        do cx.with_ambient_variance(rv_invariant) {
-            visit::visit_struct_field(cm, cx, visitor);
-        }
-      }
-      ast::named_field(_, ast::struct_immutable, _) |
-      ast::unnamed_field => {
-        visit::visit_struct_field(cm, cx, visitor);
-      }
-    }
+    visit::visit_struct_field(cm, cx, visitor);
 }
 
 pub fn determine_rp_in_crate(sess: Session,
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 946bf26fd27..5c3bb6ca401 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use driver::session;
 use driver::session::Session;
 use metadata::csearch::{each_path, get_trait_method_def_ids};
 use metadata::csearch::get_method_name_and_self_ty;
@@ -794,11 +793,6 @@ pub fn Resolver(session: Session,
 
         namespaces: ~[ TypeNS, ValueNS ],
 
-        attr_main_fn: None,
-        main_fns: ~[],
-
-        start_fn: None,
-
         def_map: @mut HashMap::new(),
         export_map2: @mut HashMap::new(),
         trait_map: HashMap::new(),
@@ -856,15 +850,6 @@ pub struct Resolver {
     // The four namespaces.
     namespaces: ~[Namespace],
 
-    // The function that has attribute named 'main'
-    attr_main_fn: Option<(node_id, span)>,
-
-    // The functions that could be main functions
-    main_fns: ~[Option<(node_id, span)>],
-
-    // The function that has the attribute 'start' on it
-    start_fn: Option<(node_id, span)>,
-
     def_map: DefMap,
     export_map2: ExportMap2,
     trait_map: TraitMap,
@@ -885,7 +870,6 @@ pub impl Resolver {
         self.resolve_crate();
         self.session.abort_if_errors();
 
-        self.check_duplicate_main();
         self.check_for_unused_imports_if_necessary();
     }
 
@@ -3544,40 +3528,6 @@ pub impl Resolver {
             }
 
             item_fn(ref fn_decl, _, _, ref generics, ref block) => {
-                // If this is the main function, we must record it in the
-                // session.
-
-                // FIXME #4404 android JNI hacks
-                if !*self.session.building_library ||
-                    self.session.targ_cfg.os == session::os_android {
-
-                    if self.attr_main_fn.is_none() &&
-                           item.ident == special_idents::main {
-
-                        self.main_fns.push(Some((item.id, item.span)));
-                    }
-
-                    if attrs_contains_name(item.attrs, ~"main") {
-                        if self.attr_main_fn.is_none() {
-                            self.attr_main_fn = Some((item.id, item.span));
-                        } else {
-                            self.session.span_err(
-                                    item.span,
-                                    ~"multiple 'main' functions");
-                        }
-                    }
-
-                    if attrs_contains_name(item.attrs, ~"start") {
-                        if self.start_fn.is_none() {
-                            self.start_fn = Some((item.id, item.span));
-                        } else {
-                            self.session.span_err(
-                                    item.span,
-                                    ~"multiple 'start' functions");
-                        }
-                    }
-                }
-
                 self.resolve_function(OpaqueFunctionRibKind,
                                       Some(fn_decl),
                                       HasTypeParameters
@@ -4680,7 +4630,7 @@ pub impl Resolver {
         }
 
         let mut smallest = 0;
-        for vec::eachi(maybes) |i, &other| {
+        for maybes.eachi |i, &other| {
 
             values[i] = str::levdistance(name, other);
 
@@ -4714,10 +4664,10 @@ pub impl Resolver {
                 if item.id == node_id {
                   match item.node {
                     item_struct(class_def, _) => {
-                      for vec::each(class_def.fields) |field| {
+                      for class_def.fields.each |field| {
                         match field.node.kind {
                           unnamed_field => {},
-                          named_field(ident, _, _) => {
+                          named_field(ident, _) => {
                               if str::eq_slice(*this.session.str_of(ident),
                                                name) {
                                 return true
@@ -5090,35 +5040,6 @@ pub impl Resolver {
     }
 
     //
-    // main function checking
-    //
-    // be sure that there is only one main function
-    //
-    fn check_duplicate_main(@mut self) {
-        let this = &mut *self;
-        if this.attr_main_fn.is_none() && this.start_fn.is_none() {
-            if this.main_fns.len() >= 1u {
-                let mut i = 1u;
-                while i < this.main_fns.len() {
-                    let (_, dup_main_span) = this.main_fns[i].unwrap();
-                    this.session.span_err(
-                        dup_main_span,
-                        ~"multiple 'main' functions");
-                    i += 1;
-                }
-                *this.session.entry_fn = this.main_fns[0];
-                *this.session.entry_type = Some(session::EntryMain);
-            }
-        } else if !this.start_fn.is_none() {
-            *this.session.entry_fn = this.start_fn;
-            *this.session.entry_type = Some(session::EntryStart);
-        } else {
-            *this.session.entry_fn = this.attr_main_fn;
-            *this.session.entry_type = Some(session::EntryMain);
-        }
-    }
-
-    //
     // Unused import checking
     //
     // Although this is a lint pass, it lives in here because it depends on
diff --git a/src/librustc/middle/resolve_stage0.rs b/src/librustc/middle/resolve_stage0.rs
index 2773710ca98..3a6424efe1d 100644
--- a/src/librustc/middle/resolve_stage0.rs
+++ b/src/librustc/middle/resolve_stage0.rs
@@ -4681,7 +4681,7 @@ pub impl Resolver {
         }
 
         let mut smallest = 0;
-        for vec::eachi(maybes) |i, &other| {
+        for maybes.eachi |i, &other| {
 
             values[i] = str::levdistance(name, other);
 
@@ -4715,10 +4715,10 @@ pub impl Resolver {
                 if item.id == node_id {
                   match item.node {
                     item_struct(class_def, _) => {
-                      for vec::each(class_def.fields) |field| {
+                      for class_def.fields.each |field| {
                         match field.node.kind {
                           unnamed_field => {},
-                          named_field(ident, _, _) => {
+                          named_field(ident, _) => {
                               if str::eq_slice(*this.session.str_of(ident),
                                                name) {
                                 return true
diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs
index d074a2f796f..1443a7ef304 100644
--- a/src/librustc/middle/trans/_match.rs
+++ b/src/librustc/middle/trans/_match.rs
@@ -283,7 +283,7 @@ pub fn variant_opt(bcx: block, pat_id: ast::node_id)
     match ccx.tcx.def_map.get_copy(&pat_id) {
         ast::def_variant(enum_id, var_id) => {
             let variants = ty::enum_variants(ccx.tcx, enum_id);
-            for vec::each(*variants) |v| {
+            for (*variants).each |v| {
                 if var_id == v.id {
                     return var(v.disr_val,
                                adt::represent_node(bcx, pat_id))
@@ -349,7 +349,7 @@ pub fn matches_to_str(bcx: block, m: &[@Match]) -> ~str {
 }
 
 pub fn has_nested_bindings(m: &[@Match], col: uint) -> bool {
-    for vec::each(m) |br| {
+    for m.each |br| {
         match br.pats[col].node {
           ast::pat_ident(_, _, Some(_)) => return true,
           _ => ()
@@ -418,7 +418,7 @@ pub fn enter_match<'r>(bcx: block,
     let _indenter = indenter();
 
     let mut result = ~[];
-    for vec::each(m) |br| {
+    for m.each |br| {
         match e(br.pats[col]) {
             Some(sub) => {
                 let pats =
@@ -934,7 +934,7 @@ pub fn collect_record_or_struct_fields(bcx: block,
                                        col: uint)
                                     -> ~[ast::ident] {
     let mut fields: ~[ast::ident] = ~[];
-    for vec::each(m) |br| {
+    for m.each |br| {
         match br.pats[col].node {
           ast::pat_struct(_, ref fs, _) => {
             match ty::get(node_id_type(bcx, br.pats[col].id)).sty {
@@ -973,7 +973,7 @@ pub fn root_pats_as_necessary(mut bcx: block,
                               col: uint,
                               val: ValueRef)
                            -> block {
-    for vec::each(m) |br| {
+    for m.each |br| {
         let pat_id = br.pats[col].id;
         if pat_id != 0 {
             let datum = Datum {val: val, ty: node_id_type(bcx, pat_id),
@@ -1042,14 +1042,14 @@ pub fn pick_col(m: &[@Match]) -> uint {
         }
     }
     let mut scores = vec::from_elem(m[0].pats.len(), 0u);
-    for vec::each(m) |br| {
+    for m.each |br| {
         let mut i = 0u;
-        for vec::each(br.pats) |p| { scores[i] += score(*p); i += 1u; }
+        for br.pats.each |p| { scores[i] += score(*p); i += 1u; }
     }
     let mut max_score = 0u;
     let mut best_col = 0u;
     let mut i = 0u;
-    for vec::each(scores) |score| {
+    for scores.each |score| {
         let score = *score;
 
         // Irrefutable columns always go first, they'd only be duplicated in
@@ -1306,7 +1306,7 @@ pub fn compile_submatch(bcx: block,
     let ccx = *bcx.fcx.ccx;
     let mut pat_id = 0;
     let mut pat_span = dummy_sp();
-    for vec::each(m) |br| {
+    for m.each |br| {
         // Find a real id (we're adding placeholder wildcard patterns, but
         // each column is guaranteed to have at least one real pattern)
         if pat_id == 0 {
@@ -1438,7 +1438,7 @@ pub fn compile_submatch(bcx: block,
             }
         }
     }
-    for vec::each(opts) |o| {
+    for opts.each |o| {
         match *o {
             range(_, _) => { kind = compare; break }
             _ => ()
@@ -1460,7 +1460,7 @@ pub fn compile_submatch(bcx: block,
     let mut i = 0u;
 
     // Compile subtrees for each option
-    for vec::each(opts) |opt| {
+    for opts.each |opt| {
         i += 1u;
         let mut opt_cx = else_cx;
         if !exhaustive || i < len {
@@ -1631,7 +1631,7 @@ pub fn trans_match_inner(scope_cx: block,
     }
 
     let mut arm_datas = ~[], matches = ~[];
-    for vec::each(arms) |arm| {
+    for arms.each |arm| {
         let body = scope_block(bcx, arm.body.info(), ~"case_body");
 
         // Create the bindings map, which is a mapping from each binding name
@@ -1670,7 +1670,7 @@ pub fn trans_match_inner(scope_cx: block,
                                  arm: arm,
                                  bindings_map: bindings_map};
         arm_datas.push(arm_data);
-        for vec::each(arm.pats) |p| {
+        for arm.pats.each |p| {
             matches.push(@Match {pats: ~[*p], data: arm_data});
         }
     }
@@ -1793,7 +1793,7 @@ pub fn bind_irrefutable_pat(bcx: block,
                                                     vinfo.disr_val,
                                                     val);
                     for sub_pats.each |sub_pat| {
-                        for vec::eachi(args.vals) |i, argval| {
+                        for args.vals.eachi |i, argval| {
                             bcx = bind_irrefutable_pat(bcx,
                                                        sub_pat[i],
                                                        *argval,
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 34f798ec7a6..77a90e22150 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -668,7 +668,7 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
       ty::ty_struct(*) => {
           let repr = adt::represent_type(cx.ccx(), t);
           do expr::with_field_tys(cx.tcx(), t, None) |discr, field_tys| {
-              for vec::eachi(field_tys) |i, field_ty| {
+              for field_tys.eachi |i, field_ty| {
                   let llfld_a = adt::trans_field_ptr(cx, repr, av, discr, i);
                   cx = f(cx, llfld_a, field_ty.mt.ty);
               }
@@ -709,7 +709,7 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t,
                                         n_variants);
                   let next_cx = sub_block(cx, ~"enum-iter-next");
 
-                  for vec::each(*variants) |variant| {
+                  for (*variants).each |variant| {
                       let variant_cx =
                           sub_block(cx, ~"enum-iter-variant-" +
                                     int::to_str(variant.disr_val));
@@ -888,7 +888,7 @@ pub fn need_invoke(bcx: block) -> bool {
         match cur.kind {
             block_scope(inf) => {
                 let inf = &mut *inf; // FIXME(#5074) workaround old borrowck
-                for vec::each(inf.cleanups) |cleanup| {
+                for inf.cleanups.each |cleanup| {
                     match *cleanup {
                         clean(_, cleanup_type) | clean_temp(_, _, cleanup_type) => {
                             if cleanup_type == normal_exit_and_unwind {
@@ -1391,7 +1391,7 @@ pub fn with_scope_datumblock(bcx: block, opt_node_info: Option<NodeInfo>,
 }
 
 pub fn block_locals(b: &ast::blk, it: &fn(@ast::local)) {
-    for vec::each(b.node.stmts) |s| {
+    for b.node.stmts.each |s| {
         match s.node {
           ast::stmt_decl(d, _) => {
             match d.node {
@@ -1973,7 +1973,7 @@ pub fn trans_enum_variant(ccx: @CrateContext,
            repr, ty_to_str(ccx.tcx, enum_ty));
 
     adt::trans_start_init(bcx, repr, fcx.llretptr.get(), disr);
-    for vec::eachi(args) |i, va| {
+    for args.eachi |i, va| {
         let lldestptr = adt::trans_field_ptr(bcx,
                                              repr,
                                              fcx.llretptr.get(),
@@ -2072,7 +2072,7 @@ pub fn trans_tuple_struct(ccx: @CrateContext,
 pub fn trans_enum_def(ccx: @CrateContext, enum_definition: &ast::enum_def,
                       id: ast::node_id, vi: @~[ty::VariantInfo],
                       i: &mut uint) {
-    for vec::each(enum_definition.variants) |variant| {
+    for enum_definition.variants.each |variant| {
         let disr_val = vi[*i].disr_val;
         *i += 1;
 
@@ -2559,7 +2559,7 @@ pub fn trans_constant(ccx: @CrateContext, it: @ast::item) {
                                                  node: it.id });
         let mut i = 0;
         let path = item_path(ccx, it);
-        for vec::each((*enum_definition).variants) |variant| {
+        for (*enum_definition).variants.each |variant| {
             let p = vec::append(/*bad*/copy path, ~[
                 path_name(variant.node.name),
                 path_name(special_idents::descrim)
@@ -2987,9 +2987,8 @@ pub fn trans_crate(sess: session::Session,
                    emap2: resolve::ExportMap2,
                    maps: astencode::Maps) -> (ModuleRef, LinkMeta) {
 
-    let symbol_hasher = @hash::default_state();
-    let link_meta =
-        link::build_link_meta(sess, crate, output, symbol_hasher);
+    let symbol_hasher = @mut hash::default_state();
+    let link_meta = link::build_link_meta(sess, crate, output, symbol_hasher);
     let reachable = reachable::find_reachable(
         &crate.node.module,
         emap2,
diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs
index c3dc4f1e8eb..29fd90edce8 100644
--- a/src/librustc/middle/trans/build.rs
+++ b/src/librustc/middle/trans/build.rs
@@ -963,20 +963,28 @@ pub fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) ->
 }
 
 pub fn InsertElement(cx: block, VecVal: ValueRef, EltVal: ValueRef,
-                 Index: ValueRef) {
+                     Index: ValueRef) -> ValueRef {
     unsafe {
-        if cx.unreachable { return; }
+        if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
         count_insn(cx, "insertelement");
-        llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname());
+        llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname())
     }
 }
 
 pub fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef,
-                     Mask: ValueRef) {
+                     Mask: ValueRef) -> ValueRef {
     unsafe {
-        if cx.unreachable { return; }
+        if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); }
         count_insn(cx, "shufflevector");
-        llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname());
+        llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname())
+    }
+}
+
+pub fn VectorSplat(cx: block, NumElts: uint, EltVal: ValueRef) -> ValueRef {
+    unsafe {
+        let Undef = llvm::LLVMGetUndef(T_vector(val_ty(EltVal), NumElts));
+        let VecVal = InsertElement(cx, Undef, EltVal, C_i32(0));
+        ShuffleVector(cx, VecVal, Undef, C_null(T_vector(T_i32(), NumElts)))
     }
 }
 
diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs
index ecde50f3470..4da2199501f 100644
--- a/src/librustc/middle/trans/cabi_x86_64.rs
+++ b/src/librustc/middle/trans/cabi_x86_64.rs
@@ -161,7 +161,7 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] {
                        cls: &mut [x86_64_reg_class], i: uint,
                        off: uint) {
         let mut field_off = off;
-        for vec::each(tys) |ty| {
+        for tys.each |ty| {
             field_off = align(field_off, *ty);
             classify(*ty, cls, i, field_off);
             field_off += ty_size(*ty);
@@ -283,7 +283,7 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] {
 fn llreg_ty(cls: &[x86_64_reg_class]) -> TypeRef {
     fn llvec_len(cls: &[x86_64_reg_class]) -> uint {
         let mut len = 1u;
-        for vec::each(cls) |c| {
+        for cls.each |c| {
             if *c != sseup_class {
                 break;
             }
@@ -370,7 +370,7 @@ fn x86_64_tys(atys: &[TypeRef],
 
     let mut arg_tys = ~[];
     let mut attrs = ~[];
-    for vec::each(atys) |t| {
+    for atys.each |t| {
         let (ty, attr) = x86_64_ty(*t, is_pass_byval, ByValAttribute);
         arg_tys.push(ty);
         attrs.push(attr);
diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs
index 87322393ab9..e5e60b2d4ac 100644
--- a/src/librustc/middle/trans/callee.rs
+++ b/src/librustc/middle/trans/callee.rs
@@ -631,7 +631,7 @@ pub fn trans_args(cx: block,
     match args {
       ArgExprs(arg_exprs) => {
         let last = arg_exprs.len() - 1u;
-        for vec::eachi(arg_exprs) |i, arg_expr| {
+        for arg_exprs.eachi |i, arg_expr| {
             let arg_val = unpack_result!(bcx, {
                 trans_arg_expr(bcx,
                                arg_tys[i],
diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs
index 442b5d25c8b..c1309b42288 100644
--- a/src/librustc/middle/trans/common.rs
+++ b/src/librustc/middle/trans/common.rs
@@ -207,7 +207,7 @@ pub struct CrateContext {
      adt_reprs: @mut HashMap<ty::t, @adt::Repr>,
      names: namegen,
      next_addrspace: addrspace_gen,
-     symbol_hasher: @hash::State,
+     symbol_hasher: @mut hash::State,
      type_hashcodes: @mut HashMap<ty::t, @str>,
      type_short_names: @mut HashMap<ty::t, ~str>,
      all_llvm_symbols: @mut HashSet<@~str>,
@@ -984,6 +984,12 @@ pub fn T_array(t: TypeRef, n: uint) -> TypeRef {
     }
 }
 
+pub fn T_vector(t: TypeRef, n: uint) -> TypeRef {
+    unsafe {
+        return llvm::LLVMVectorType(t, n as c_uint);
+    }
+}
+
 // Interior vector.
 pub fn T_vec2(targ_cfg: @session::config, t: TypeRef) -> TypeRef {
     return T_struct(~[T_int(targ_cfg), // fill
diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs
index f1192488bdd..8b72ddda044 100644
--- a/src/librustc/middle/trans/controlflow.rs
+++ b/src/librustc/middle/trans/controlflow.rs
@@ -34,7 +34,7 @@ pub fn trans_block(bcx: block, b: &ast::blk, dest: expr::Dest) -> block {
     do block_locals(b) |local| {
         bcx = alloc_local(bcx, local);
     };
-    for vec::each(b.node.stmts) |s| {
+    for b.node.stmts.each |s| {
         debuginfo::update_source_pos(bcx, b.span);
         bcx = trans_stmt(bcx, *s);
     }
@@ -107,7 +107,7 @@ pub fn trans_if(bcx: block,
 pub fn join_blocks(parent_bcx: block, in_cxs: &[block]) -> block {
     let out = sub_block(parent_bcx, ~"join");
     let mut reachable = false;
-    for vec::each(in_cxs) |bcx| {
+    for in_cxs.each |bcx| {
         if !bcx.unreachable {
             Br(*bcx, out.llbb);
             reachable = true;
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 2c59d5c6bd6..29227b7c95a 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -120,14 +120,14 @@ lvalues are *never* stored by value.
 */
 
 use back::abi;
-use lib;
 use lib::llvm::{ValueRef, TypeRef, llvm};
+use lib;
 use metadata::csearch;
 use middle::trans::_match;
 use middle::trans::adt;
 use middle::trans::asm;
-use middle::trans::base;
 use middle::trans::base::*;
+use middle::trans::base;
 use middle::trans::build::*;
 use middle::trans::callee::DoAutorefArg;
 use middle::trans::callee;
@@ -142,8 +142,10 @@ use middle::trans::machine;
 use middle::trans::meth;
 use middle::trans::tvec;
 use middle::trans::type_of;
+use middle::ty::struct_fields;
+use middle::ty::{AutoDerefRef, AutoAddEnv};
+use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn};
 use middle::ty;
-use middle::ty::struct_mutable_fields;
 use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef, AutoBorrowFn,
                  AutoDerefRef, AutoAddEnv, AutoUnsafe};
 use util::common::indenter;
@@ -1107,7 +1109,7 @@ pub fn with_field_tys<R>(tcx: ty::ctxt,
                          op: &fn(int, (&[ty::field])) -> R) -> R {
     match ty::get(ty).sty {
         ty::ty_struct(did, ref substs) => {
-            op(0, struct_mutable_fields(tcx, did, substs))
+            op(0, struct_fields(tcx, did, substs))
         }
 
         ty::ty_enum(_, ref substs) => {
@@ -1124,8 +1126,8 @@ pub fn with_field_tys<R>(tcx: ty::ctxt,
                         ast::def_variant(enum_id, variant_id) => {
                             let variant_info = ty::enum_variant_with_id(
                                 tcx, enum_id, variant_id);
-                            op(variant_info.disr_val, struct_mutable_fields(
-                                tcx, variant_id, substs))
+                            op(variant_info.disr_val,
+                               struct_fields(tcx, variant_id, substs))
                         }
                         _ => {
                             tcx.sess.bug(~"resolve didn't map this expr to a \
@@ -1262,7 +1264,7 @@ fn trans_adt(bcx: block, repr: &adt::Repr, discr: int,
         }
     }
 
-    for vec::each(temp_cleanups) |cleanup| {
+    for temp_cleanups.each |cleanup| {
         revoke_clean(bcx, *cleanup);
     }
     return bcx;
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs
index 21e29b9ad82..7eea65e458f 100644
--- a/src/librustc/middle/trans/foreign.rs
+++ b/src/librustc/middle/trans/foreign.rs
@@ -294,7 +294,7 @@ pub fn trans_foreign_mod(ccx: @CrateContext,
         Some(abi) => abi,
     };
 
-    for vec::each(foreign_mod.items) |&foreign_item| {
+    for foreign_mod.items.each |&foreign_item| {
         match foreign_item.node {
             ast::foreign_item_fn(*) => {
                 let id = foreign_item.id;
diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs
index a35c40b8520..3b06f903641 100644
--- a/src/librustc/middle/trans/glue.rs
+++ b/src/librustc/middle/trans/glue.rs
@@ -496,9 +496,7 @@ pub fn trans_struct_drop(bcx: block,
         Call(bcx, dtor_addr, args);
 
         // Drop the fields
-        let field_tys =
-            ty::struct_mutable_fields(bcx.tcx(), class_did,
-                                              substs);
+        let field_tys = ty::struct_fields(bcx.tcx(), class_did, substs);
         for vec::eachi(field_tys) |i, fld| {
             let llfld_a = adt::trans_field_ptr(bcx, repr, v0, 0, i);
             bcx = drop_ty(bcx, llfld_a, fld.mt.ty);
diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs
index 934a995b588..f20af0409c5 100644
--- a/src/librustc/middle/trans/meth.rs
+++ b/src/librustc/middle/trans/meth.rs
@@ -51,7 +51,7 @@ pub fn trans_impl(ccx: @CrateContext, path: path, name: ast::ident,
 
     if !generics.ty_params.is_empty() { return; }
     let sub_path = vec::append_one(path, path_name(name));
-    for vec::each(methods) |method| {
+    for methods.each |method| {
         if method.generics.ty_params.len() == 0u {
             let llfn = get_item_val(ccx, method.id);
             let path = vec::append_one(/*bad*/copy sub_path,
diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs
index e8075c1f2ad..d9bf25bf377 100644
--- a/src/librustc/middle/trans/tvec.rs
+++ b/src/librustc/middle/trans/tvec.rs
@@ -28,7 +28,6 @@ use util::common::indenter;
 use util::ppaux::ty_to_str;
 
 use core::option::None;
-use core::vec;
 use syntax::ast;
 use syntax::codemap;
 
@@ -395,7 +394,7 @@ pub fn write_content(bcx: block,
                         add_clean_temp_mem(bcx, lleltptr, vt.unit_ty);
                         temp_cleanups.push(lleltptr);
                     }
-                    for vec::each(temp_cleanups) |cleanup| {
+                    for temp_cleanups.each |cleanup| {
                         revoke_clean(bcx, *cleanup);
                     }
                 }
diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs
index fc27c11c06f..b8e0b58f866 100644
--- a/src/librustc/middle/trans/type_of.rs
+++ b/src/librustc/middle/trans/type_of.rs
@@ -155,9 +155,15 @@ pub fn sizing_type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
         }
 
         ty::ty_struct(did, _) => {
-            let repr = adt::represent_type(cx, t);
-            let packed = ty::lookup_packed(cx.tcx, did);
-            T_struct(adt::sizing_fields_of(cx, repr), packed)
+            if ty::type_is_simd(cx.tcx, t) {
+                let et = ty::simd_type(cx.tcx, t);
+                let n = ty::simd_size(cx.tcx, t);
+                T_vector(type_of(cx, et), n)
+            } else {
+                let repr = adt::represent_type(cx, t);
+                let packed = ty::lookup_packed(cx.tcx, did);
+                T_struct(adt::sizing_fields_of(cx, repr), packed)
+            }
         }
 
         ty::ty_self(_) | ty::ty_infer(*) | ty::ty_param(*) | ty::ty_err(*) => {
@@ -263,14 +269,19 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
       }
       ty::ty_opaque_closure_ptr(_) => T_opaque_box_ptr(cx),
       ty::ty_struct(did, ref substs) => {
-        // Only create the named struct, but don't fill it in. We fill it
-        // in *after* placing it into the type cache. This prevents
-        // infinite recursion with recursive struct types.
-
-        common::T_named_struct(llvm_type_name(cx,
-                                              a_struct,
-                                              did,
-                                              /*bad*/ copy substs.tps))
+        if ty::type_is_simd(cx.tcx, t) {
+          let et = ty::simd_type(cx.tcx, t);
+          let n = ty::simd_size(cx.tcx, t);
+          T_vector(type_of(cx, et), n)
+        } else {
+          // Only create the named struct, but don't fill it in. We fill it
+          // in *after* placing it into the type cache. This prevents
+          // infinite recursion with recursive struct types.
+          T_named_struct(llvm_type_name(cx,
+                                        a_struct,
+                                        did,
+                                        /*bad*/ copy substs.tps))
+        }
       }
       ty::ty_self(*) => cx.tcx.sess.unimpl(~"type_of: ty_self"),
       ty::ty_infer(*) => cx.tcx.sess.bug(~"type_of with ty_infer"),
@@ -289,10 +300,12 @@ pub fn type_of(cx: @CrateContext, t: ty::t) -> TypeRef {
       }
 
       ty::ty_struct(did, _) => {
-        let repr = adt::represent_type(cx, t);
-        let packed = ty::lookup_packed(cx.tcx, did);
-        common::set_struct_body(llty, adt::fields_of(cx, repr),
-                                packed);
+        if !ty::type_is_simd(cx.tcx, t) {
+          let repr = adt::represent_type(cx, t);
+          let packed = ty::lookup_packed(cx.tcx, did);
+          common::set_struct_body(llty, adt::fields_of(cx, repr),
+                                  packed);
+        }
       }
       _ => ()
     }
diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs
index 94ef33e45bb..f1c3a42d158 100644
--- a/src/librustc/middle/trans/type_use.rs
+++ b/src/librustc/middle/trans/type_use.rs
@@ -77,7 +77,7 @@ pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint)
     match ty::get(ty::lookup_item_type(cx.ccx.tcx, fn_id).ty).sty {
         ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) |
         ty::ty_closure(ty::ClosureTy {sig: ref sig, _}) => {
-            for vec::each(sig.inputs) |arg| {
+            for sig.inputs.each |arg| {
                 type_needs(cx, use_repr, arg.ty);
             }
         }
@@ -213,7 +213,7 @@ pub fn type_needs_inner(cx: Context,
                 if list::find(enums_seen, |id| *id == did).is_none() {
                     let seen = @Cons(did, enums_seen);
                     for vec::each(*ty::enum_variants(cx.ccx.tcx, did)) |v| {
-                        for vec::each(v.args) |aty| {
+                        for v.args.each |aty| {
                             let t = ty::subst(cx.ccx.tcx, &(*substs), *aty);
                             type_needs_inner(cx, use_, t, seen);
                         }
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index b6e024b011e..2daba3212e1 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -106,10 +106,9 @@ pub enum SelfMode {
 }
 
 pub struct field_ty {
-  ident: ident,
-  id: def_id,
-  vis: ast::visibility,
-  mutability: ast::struct_mutability,
+    ident: ident,
+    id: def_id,
+    vis: ast::visibility,
 }
 
 // Contains information needed to resolve types and (in the future) look up
@@ -1567,6 +1566,13 @@ pub fn type_is_sequence(ty: t) -> bool {
     }
 }
 
+pub fn type_is_simd(cx: ctxt, ty: t) -> bool {
+    match get(ty).sty {
+        ty_struct(did, _) => lookup_simd(cx, did),
+        _ => false
+    }
+}
+
 pub fn type_is_str(ty: t) -> bool {
     match get(ty).sty {
       ty_estr(_) => true,
@@ -1583,6 +1589,26 @@ pub fn sequence_element_type(cx: ctxt, ty: t) -> t {
     }
 }
 
+pub fn simd_type(cx: ctxt, ty: t) -> t {
+    match get(ty).sty {
+        ty_struct(did, ref substs) => {
+            let fields = lookup_struct_fields(cx, did);
+            lookup_field_type(cx, did, fields[0].id, substs)
+        }
+        _ => fail!(~"simd_type called on invalid type")
+    }
+}
+
+pub fn simd_size(cx: ctxt, ty: t) -> uint {
+    match get(ty).sty {
+        ty_struct(did, _) => {
+            let fields = lookup_struct_fields(cx, did);
+            fields.len()
+        }
+        _ => fail!(~"simd_size called on invalid type")
+    }
+}
+
 pub fn get_element_type(ty: t, i: uint) -> t {
     match get(ty).sty {
       ty_tup(ref ts) => return ts[i],
@@ -1714,7 +1740,7 @@ fn type_needs_unwind_cleanup_(cx: ctxt, ty: t,
             true
           }
           ty_enum(did, ref substs) => {
-            for vec::each(*enum_variants(cx, did)) |v| {
+            for (*enum_variants(cx, did)).each |v| {
                 for v.args.each |aty| {
                     let t = subst(cx, substs, *aty);
                     needs_unwind_cleanup |=
@@ -2309,7 +2335,7 @@ pub fn type_structurally_contains(cx: ctxt,
     if test(sty) { return true; }
     match *sty {
       ty_enum(did, ref substs) => {
-        for vec::each(*enum_variants(cx, did)) |variant| {
+        for (*enum_variants(cx, did)).each |variant| {
             for variant.args.each |aty| {
                 let sty = subst(cx, substs, *aty);
                 if type_structurally_contains(cx, sty, test) { return true; }
@@ -2381,6 +2407,14 @@ pub fn type_is_signed(ty: t) -> bool {
     }
 }
 
+pub fn type_is_machine(ty: t) -> bool {
+    match get(ty).sty {
+        ty_int(ast::ty_i) | ty_uint(ast::ty_u) | ty_float(ast::ty_f) => false,
+        ty_int(*) | ty_uint(*) | ty_float(*) => true,
+        _ => false
+    }
+}
+
 // Whether a type is Plain Old Data -- meaning it does not contain pointers
 // that the cycle collector might care about.
 pub fn type_is_pod(cx: ctxt, ty: t) -> bool {
@@ -2397,7 +2431,7 @@ pub fn type_is_pod(cx: ctxt, ty: t) -> bool {
       // Structural types
       ty_enum(did, ref substs) => {
         let variants = enum_variants(cx, did);
-        for vec::each(*variants) |variant| {
+        for (*variants).each |variant| {
             let tup_ty = mk_tup(cx, /*bad*/copy variant.args);
 
             // Perform any type parameter substitutions.
@@ -3896,7 +3930,7 @@ pub fn has_attr(tcx: ctxt, did: def_id, attr: &str) -> bool {
                     attrs: ref attrs,
                     _
                 }, _)) => attr::attrs_contains_name(*attrs, attr),
-            _ => tcx.sess.bug(fmt!("lookup_packed: %? is not an item",
+            _ => tcx.sess.bug(fmt!("has_attr: %? is not an item",
                                    did))
         }
     } else {
@@ -3908,11 +3942,16 @@ pub fn has_attr(tcx: ctxt, did: def_id, attr: &str) -> bool {
     }
 }
 
-/// Determine whether an item is annotated with `#[packed]` or not
+/// Determine whether an item is annotated with `#[packed]`
 pub fn lookup_packed(tcx: ctxt, did: def_id) -> bool {
     has_attr(tcx, did, "packed")
 }
 
+/// Determine whether an item is annotated with `#[simd]`
+pub fn lookup_simd(tcx: ctxt, did: def_id) -> bool {
+    has_attr(tcx, did, "simd")
+}
+
 // Look up a field ID, whether or not it's local
 // Takes a list of type substs in case the struct is generic
 pub fn lookup_field_type(tcx: ctxt,
@@ -3987,12 +4026,11 @@ pub fn lookup_struct_field(cx: ctxt,
 fn struct_field_tys(fields: &[@struct_field]) -> ~[field_ty] {
     do fields.map |field| {
         match field.node.kind {
-            named_field(ident, mutability, visibility) => {
+            named_field(ident, visibility) => {
                 field_ty {
                     ident: ident,
                     id: ast_util::local_def(field.node.id),
                     vis: visibility,
-                    mutability: mutability,
                 }
             }
             unnamed_field => {
@@ -4001,51 +4039,22 @@ fn struct_field_tys(fields: &[@struct_field]) -> ~[field_ty] {
                         syntax::parse::token::special_idents::unnamed_field,
                     id: ast_util::local_def(field.node.id),
                     vis: ast::public,
-                    mutability: ast::struct_immutable,
                 }
             }
         }
     }
 }
 
-// Return a list of fields corresponding to the struct's items
-// (as if the struct was a record). trans uses this
-// Takes a list of substs with which to instantiate field types
-// Keep in mind that this function reports that all fields are
-// mutable, regardless of how they were declared. It's meant to
-// be used in trans.
-pub fn struct_mutable_fields(cx: ctxt,
-                             did: ast::def_id,
-                             substs: &substs)
-                          -> ~[field] {
-    struct_item_fields(cx, did, substs, |_mt| m_mutbl)
-}
-
-// Same as struct_mutable_fields, but doesn't change
-// mutability.
-pub fn struct_fields(cx: ctxt,
-                     did: ast::def_id,
-                     substs: &substs)
-                  -> ~[field] {
-    struct_item_fields(cx, did, substs, |mt| match mt {
-      struct_mutable => m_mutbl,
-        struct_immutable => m_imm })
-}
-
-
-fn struct_item_fields(cx:ctxt,
-                     did: ast::def_id,
-                     substs: &substs,
-                     frob_mutability: &fn(struct_mutability) -> mutability)
-    -> ~[field] {
+// Returns a list of fields corresponding to the struct's items. trans uses
+// this. Takes a list of substs with which to instantiate field types.
+pub fn struct_fields(cx: ctxt, did: ast::def_id, substs: &substs)
+                     -> ~[field] {
     do lookup_struct_fields(cx, did).map |f| {
-       // consider all instance vars mut, because the
-       // constructor may mutate all vars
        field {
-           ident: f.ident,
+            ident: f.ident,
             mt: mt {
                 ty: lookup_field_type(cx, did, f.id, substs),
-                mutbl: frob_mutability(f.mutability)
+                mutbl: m_imm
             }
         }
     }
diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs
index 68700d62187..6cd10b5bd6f 100644
--- a/src/librustc/middle/typeck/check/mod.rs
+++ b/src/librustc/middle/typeck/check/mod.rs
@@ -561,8 +561,14 @@ pub fn check_no_duplicate_fields(tcx: ty::ctxt,
 }
 
 pub fn check_struct(ccx: @mut CrateCtxt, id: ast::node_id, span: span) {
+    let tcx = ccx.tcx;
+
     // Check that the class is instantiable
-    check_instantiable(ccx.tcx, span, id);
+    check_instantiable(tcx, span, id);
+
+    if ty::lookup_simd(tcx, local_def(id)) {
+        check_simd(tcx, span, id);
+    }
 }
 
 pub fn check_item(ccx: @mut CrateCtxt, it: @ast::item) {
@@ -3034,6 +3040,35 @@ pub fn check_instantiable(tcx: ty::ctxt,
     }
 }
 
+pub fn check_simd(tcx: ty::ctxt, sp: span, id: ast::node_id) {
+    let t = ty::node_id_to_type(tcx, id);
+    if ty::type_needs_subst(t) {
+        tcx.sess.span_err(sp, "SIMD vector cannot be generic");
+        return;
+    }
+    match ty::get(t).sty {
+        ty::ty_struct(did, ref substs) => {
+            let fields = ty::lookup_struct_fields(tcx, did);
+            if fields.is_empty() {
+                tcx.sess.span_err(sp, "SIMD vector cannot be empty");
+                return;
+            }
+            let e = ty::lookup_field_type(tcx, did, fields[0].id, substs);
+            if !vec::all(fields,
+                         |f| ty::lookup_field_type(tcx, did, f.id, substs) == e) {
+                tcx.sess.span_err(sp, "SIMD vector should be homogeneous");
+                return;
+            }
+            if !ty::type_is_machine(e) {
+                tcx.sess.span_err(sp, "SIMD vector element type should be \
+                                       machine type");
+                return;
+            }
+        }
+        _ => ()
+    }
+}
+
 pub fn check_enum_variants(ccx: @mut CrateCtxt,
                            sp: span,
                            vs: &[ast::variant],
diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs
index b7713eaa2fd..2869c3737c9 100644
--- a/src/librustc/middle/typeck/check/writeback.rs
+++ b/src/librustc/middle/typeck/check/writeback.rs
@@ -228,7 +228,7 @@ fn visit_expr(e: @ast::expr, wbcx: @mut WbCtxt, v: wb_vt) {
 
     match e.node {
         ast::expr_fn_block(ref decl, _) => {
-            for vec::each(decl.inputs) |input| {
+            for decl.inputs.each |input| {
                 let _ = resolve_type_vars_for_node(wbcx, e.span, input.id);
             }
         }
diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs
index a3b5369d22a..8349e16d2c4 100644
--- a/src/librustc/middle/typeck/infer/region_inference.rs
+++ b/src/librustc/middle/typeck/infer/region_inference.rs
@@ -1572,8 +1572,8 @@ pub impl RegionVarBindings {
             return;
         }
 
-        for vec::each(lower_bounds) |lower_bound| {
-            for vec::each(upper_bounds) |upper_bound| {
+        for lower_bounds.each |lower_bound| {
+            for upper_bounds.each |upper_bound| {
                 if !self.is_subregion_of(lower_bound.region,
                                          upper_bound.region) {
 
@@ -1629,8 +1629,8 @@ pub impl RegionVarBindings {
             return;
         }
 
-        for vec::each(upper_bounds) |upper_bound_1| {
-            for vec::each(upper_bounds) |upper_bound_2| {
+        for upper_bounds.each |upper_bound_1| {
+            for upper_bounds.each |upper_bound_2| {
                 match self.glb_concrete_regions(upper_bound_1.region,
                                                 upper_bound_2.region) {
                   Ok(_) => {}
diff --git a/src/librustc/middle/typeck/mod.rs b/src/librustc/middle/typeck/mod.rs
index 1a152f3c291..5da14d99171 100644
--- a/src/librustc/middle/typeck/mod.rs
+++ b/src/librustc/middle/typeck/mod.rs
@@ -393,7 +393,7 @@ fn check_for_entry_fn(ccx: @mut CrateCtxt) {
               Some(session::EntryStart) => check_start_fn_ty(ccx, id, sp),
               None => tcx.sess.bug(~"entry function without a type")
           },
-          None => tcx.sess.err(~"entry function not found")
+          None => tcx.sess.bug(~"type checking without entry function")
         }
     }
 }
diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc
index f8a19eaf374..f69a38c96dc 100644
--- a/src/librustc/rustc.rc
+++ b/src/librustc/rustc.rc
@@ -100,6 +100,7 @@ pub mod middle {
     pub mod lang_items;
     pub mod privacy;
     pub mod moves;
+    pub mod entry;
 }
 
 pub mod front {
diff --git a/src/librustdoc/extract.rs b/src/librustdoc/extract.rs
index ce120f477a5..34faf6cefa3 100644
--- a/src/librustdoc/extract.rs
+++ b/src/librustdoc/extract.rs
@@ -22,7 +22,7 @@ use syntax;
  * there. */
 macro_rules! interner_key (
     () => (cast::transmute::<(uint, uint),
-           &fn(+v: @@syntax::parse::token::ident_interner)>((-3 as uint, 0u)))
+           &fn(v: @@syntax::parse::token::ident_interner)>((-3 as uint, 0u)))
 )
 
 // Hack; rather than thread an interner through everywhere, rely on
@@ -274,7 +274,7 @@ fn structdoc_from_struct(
         item: itemdoc,
         fields: do struct_def.fields.map |field| {
             match field.node.kind {
-                ast::named_field(ident, _, _) => to_str(ident),
+                ast::named_field(ident, _) => to_str(ident),
                 ast::unnamed_field => ~"(unnamed)",
             }
         },
diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs
index 16b84190ee3..e376e4afa5c 100644
--- a/src/librustdoc/markdown_pass.rs
+++ b/src/librustdoc/markdown_pass.rs
@@ -276,7 +276,7 @@ fn write_desc(
 }
 
 fn write_sections(ctxt: &Ctxt, sections: &[doc::Section]) {
-    for vec::each(sections) |section| {
+    for sections.each |section| {
         write_section(ctxt, copy *section);
     }
 }
@@ -439,7 +439,7 @@ fn write_variants(
 
     write_header_(ctxt, H4, ~"Variants");
 
-    for vec::each(docs) |variant| {
+    for docs.each |variant| {
         write_variant(ctxt, copy *variant);
     }
 
@@ -465,7 +465,7 @@ fn write_trait(ctxt: &Ctxt, doc: doc::TraitDoc) {
 }
 
 fn write_methods(ctxt: &Ctxt, docs: &[doc::MethodDoc]) {
-    for vec::each(docs) |doc| {
+    for docs.each |doc| {
         write_method(ctxt, copy *doc);
     }
 }
diff --git a/src/librustdoc/markdown_writer.rs b/src/librustdoc/markdown_writer.rs
index b9a2ee7ccb7..e56b0fb60cd 100644
--- a/src/librustdoc/markdown_writer.rs
+++ b/src/librustdoc/markdown_writer.rs
@@ -26,8 +26,8 @@ pub type Writer = ~fn(v: WriteInstr);
 pub type WriterFactory = ~fn(page: doc::Page) -> Writer;
 
 pub trait WriterUtils {
-    fn put_str(&self, +str: ~str);
-    fn put_line(&self, +str: ~str);
+    fn put_str(&self, str: ~str);
+    fn put_line(&self, str: ~str);
     fn put_done(&self);
 }
 
@@ -230,6 +230,7 @@ pub fn future_writer_factory(
         let markdown_ch = markdown_ch.clone();
         do task::spawn || {
             let (writer, future) = future_writer();
+            let mut future = future;
             writer_ch.send(writer);
             let s = future.get();
             markdown_ch.send((copy page, s));
diff --git a/src/librustdoc/pass.rs b/src/librustdoc/pass.rs
index 94db038bdec..b80f43a7bbd 100644
--- a/src/librustdoc/pass.rs
+++ b/src/librustdoc/pass.rs
@@ -17,7 +17,7 @@ use time;
 /// A single operation on the document model
 pub struct Pass {
     name: ~str,
-    f: @fn(srv: astsrv::Srv, +doc: doc::Doc) -> doc::Doc
+    f: @fn(srv: astsrv::Srv, doc: doc::Doc) -> doc::Doc
 }
 
 pub fn run_passes(
diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs
index 0762fa4ad7f..5e43cb43960 100644
--- a/src/librustpkg/util.rs
+++ b/src/librustpkg/util.rs
@@ -11,6 +11,7 @@
 use core::*;
 use core::cmp::Ord;
 use core::hash::Streaming;
+use core::rt::io::Writer;
 use rustc::driver::{driver, session};
 use rustc::driver::session::{lib_crate, unknown_crate};
 use rustc::metadata::filesearch;
@@ -367,9 +368,9 @@ pub fn error(msg: ~str) {
 }
 
 pub fn hash(data: ~str) -> ~str {
-    let hasher = &hash::default_state();
-
-    hasher.write_str(data);
+    let mut hasher = hash::default_state();
+    let buffer = str::as_bytes_slice(data);
+    hasher.write(buffer);
     hasher.result_str()
 }
 
diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs
index 6c39fa1f9dc..08507fbf34e 100644
--- a/src/libstd/arc.rs
+++ b/src/libstd/arc.rs
@@ -484,7 +484,6 @@ mod tests {
 
     use core::cell::Cell;
     use core::task;
-    use core::vec;
 
     #[test]
     fn manually_share_arc() {
@@ -673,8 +672,9 @@ mod tests {
         let mut children = ~[];
         for 5.times {
             let arc3 = (*arc).clone();
-            do task::task().future_result(|+r| children.push(r)).spawn
-                || {
+            let mut builder = task::task();
+            builder.future_result(|r| children.push(r));
+            do builder.spawn {
                 do arc3.read |num| {
                     assert!(*num >= 0);
                 }
@@ -682,11 +682,15 @@ mod tests {
         }
 
         // Wait for children to pass their asserts
-        for vec::each(children) |r| { r.recv(); }
+        for children.each |r| {
+            r.recv();
+        }
 
         // Wait for writer to finish
         p.recv();
-        do arc.read |num| { assert!(*num == 10); }
+        do arc.read |num| {
+            assert!(*num == 10);
+        }
     }
     #[test]
     fn test_rw_downgrade() {
@@ -743,7 +747,7 @@ mod tests {
                 assert!(*state == 42);
                 *state = 31337;
                 // send to other readers
-                for vec::each(reader_convos) |x| {
+                for reader_convos.each |x| {
                     match *x {
                         (ref rc, _) => rc.send(()),
                     }
@@ -752,7 +756,7 @@ mod tests {
             let read_mode = arc.downgrade(write_mode);
             do (&read_mode).read |state| {
                 // complete handshake with other readers
-                for vec::each(reader_convos) |x| {
+                for reader_convos.each |x| {
                     match *x {
                         (_, ref rp) => rp.recv(),
                     }
diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs
index 3a55d3e337c..fd9fba8c1d7 100644
--- a/src/libstd/arena.rs
+++ b/src/libstd/arena.rs
@@ -47,7 +47,7 @@ use core::vec;
 pub mod rusti {
     #[abi = "rust-intrinsic"]
     pub extern "rust-intrinsic" {
-        fn move_val_init<T>(dst: &mut T, +src: T);
+        fn move_val_init<T>(dst: &mut T, src: T);
         fn needs_drop<T>() -> bool;
     }
 }
diff --git a/src/libstd/base64.rs b/src/libstd/base64.rs
index b26296c9aca..85ba2707863 100644
--- a/src/libstd/base64.rs
+++ b/src/libstd/base64.rs
@@ -156,31 +156,27 @@ impl FromBase64 for ~[u8] {
                 let ch = self[i] as char;
                 n <<= 6u;
 
-                if ch >= 'A' && ch <= 'Z' {
-                    n |= (ch as uint) - 0x41u;
-                } else if ch >= 'a' && ch <= 'z' {
-                    n |= (ch as uint) - 0x47u;
-                } else if ch >= '0' && ch <= '9' {
-                    n |= (ch as uint) + 0x04u;
-                } else if ch == '+' {
-                    n |= 0x3Eu;
-                } else if ch == '/' {
-                    n |= 0x3Fu;
-                } else if ch == '=' {
-                    match len - i {
-                      1u => {
-                        r.push(((n >> 16u) & 0xFFu) as u8);
-                        r.push(((n >> 8u ) & 0xFFu) as u8);
-                        return copy r;
-                      }
-                      2u => {
-                        r.push(((n >> 10u) & 0xFFu) as u8);
-                        return copy r;
-                      }
-                      _ => fail!(~"invalid base64 padding")
+                match ch {
+                    'A'..'Z' => n |= (ch as uint) - 0x41,
+                    'a'..'z' => n |= (ch as uint) - 0x47,
+                    '0'..'9' => n |= (ch as uint) + 0x04,
+                    '+'      => n |= 0x3E,
+                    '/'      => n |= 0x3F,
+                    '='      => {
+                        match len - i {
+                            1u => {
+                                r.push(((n >> 16u) & 0xFFu) as u8);
+                                r.push(((n >> 8u ) & 0xFFu) as u8);
+                                return copy r;
+                            }
+                            2u => {
+                                r.push(((n >> 10u) & 0xFFu) as u8);
+                                return copy r;
+                            }
+                            _ => fail!(~"invalid base64 padding")
+                        }
                     }
-                } else {
-                    fail!(~"invalid base64 character");
+                    _ => fail!(~"invalid base64 character")
                 }
 
                 i += 1u;
diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs
index ceb67fcabfa..461fb61ed56 100644
--- a/src/libstd/bitv.rs
+++ b/src/libstd/bitv.rs
@@ -1426,7 +1426,7 @@ mod tests {
 
     #[bench]
     fn bench_uint_small(b: &mut BenchHarness) {
-        let r = rng();
+        let mut r = rng();
         let mut bitv = 0 as uint;
         do b.iter {
             bitv |= (1 << ((r.next() as uint) % uint::bits));
@@ -1435,7 +1435,7 @@ mod tests {
 
     #[bench]
     fn bench_small_bitv_small(b: &mut BenchHarness) {
-        let r = rng();
+        let mut r = rng();
         let mut bitv = SmallBitv::new(uint::bits);
         do b.iter {
             bitv.set((r.next() as uint) % uint::bits, true);
@@ -1444,7 +1444,7 @@ mod tests {
 
     #[bench]
     fn bench_big_bitv_small(b: &mut BenchHarness) {
-        let r = rng();
+        let mut r = rng();
         let mut bitv = BigBitv::new(~[0]);
         do b.iter {
             bitv.set((r.next() as uint) % uint::bits, true);
@@ -1453,7 +1453,7 @@ mod tests {
 
     #[bench]
     fn bench_big_bitv_big(b: &mut BenchHarness) {
-        let r = rng();
+        let mut r = rng();
         let mut storage = ~[];
         storage.grow(bench_bits / uint::bits, &0);
         let mut bitv = BigBitv::new(storage);
@@ -1464,7 +1464,7 @@ mod tests {
 
     #[bench]
     fn bench_bitv_big(b: &mut BenchHarness) {
-        let r = rng();
+        let mut r = rng();
         let mut bitv = Bitv::new(bench_bits, false);
         do b.iter {
             bitv.set((r.next() as uint) % bench_bits, true);
@@ -1473,7 +1473,7 @@ mod tests {
 
     #[bench]
     fn bench_bitv_small(b: &mut BenchHarness) {
-        let r = rng();
+        let mut r = rng();
         let mut bitv = Bitv::new(uint::bits, false);
         do b.iter {
             bitv.set((r.next() as uint) % uint::bits, true);
@@ -1482,7 +1482,7 @@ mod tests {
 
     #[bench]
     fn bench_bitv_set_small(b: &mut BenchHarness) {
-        let r = rng();
+        let mut r = rng();
         let mut bitv = BitvSet::new();
         do b.iter {
             bitv.insert((r.next() as uint) % uint::bits);
@@ -1491,7 +1491,7 @@ mod tests {
 
     #[bench]
     fn bench_bitv_set_big(b: &mut BenchHarness) {
-        let r = rng();
+        let mut r = rng();
         let mut bitv = BitvSet::new();
         do b.iter {
             bitv.insert((r.next() as uint) % bench_bits);
diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs
index d866ee6cedb..20ab2d61ecc 100644
--- a/src/libstd/comm.rs
+++ b/src/libstd/comm.rs
@@ -72,7 +72,7 @@ impl<T:Owned,U:Owned> Peekable<U> for DuplexStream<T, U> {
 }
 
 impl<T:Owned,U:Owned> Selectable for DuplexStream<T, U> {
-    fn header(&self) -> *pipes::PacketHeader {
+    fn header(&mut self) -> *mut pipes::PacketHeader {
         self.port.header()
     }
 }
diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs
index af433c6dd9d..5e4f708f52f 100644
--- a/src/libstd/ebml.rs
+++ b/src/libstd/ebml.rs
@@ -600,11 +600,18 @@ pub mod writer {
     use core::vec;
 
     // ebml writing
+    #[cfg(stage0)]
     pub struct Encoder {
         writer: @io::Writer,
         priv mut size_positions: ~[uint],
     }
 
+    #[cfg(not(stage0))]
+    pub struct Encoder {
+        writer: @io::Writer,
+        priv size_positions: ~[uint],
+    }
+
     fn write_sized_vuint(w: @io::Writer, n: uint, size: uint) {
         match size {
             1u => w.write(&[0x80u8 | (n as u8)]),
@@ -625,9 +632,22 @@ pub mod writer {
         fail!(fmt!("vint to write too big: %?", n));
     }
 
+    #[cfg(stage0)]
+    pub fn Encoder(w: @io::Writer) -> Encoder {
+        let size_positions: ~[uint] = ~[];
+        Encoder {
+            writer: w,
+            mut size_positions: size_positions
+        }
+    }
+
+    #[cfg(not(stage0))]
     pub fn Encoder(w: @io::Writer) -> Encoder {
         let size_positions: ~[uint] = ~[];
-        Encoder { writer: w, mut size_positions: size_positions }
+        Encoder {
+            writer: w,
+            size_positions: size_positions
+        }
     }
 
     // FIXME (#2741): Provide a function to write the standard ebml header.
diff --git a/src/libstd/fileinput.rs b/src/libstd/fileinput.rs
index a24b11d71c6..90774d19595 100644
--- a/src/libstd/fileinput.rs
+++ b/src/libstd/fileinput.rs
@@ -145,7 +145,7 @@ struct FileInput_ {
 // "self.fi." -> "self." and renaming FileInput_. Documentation above
 // will likely have to be updated to use `let mut in = ...`.
 pub struct FileInput  {
-    priv mut fi: FileInput_
+    priv fi: @mut FileInput_
 }
 
 impl FileInput {
@@ -170,7 +170,7 @@ impl FileInput {
     pub fn from_vec_raw(files: ~[Option<Path>])
                                          -> FileInput {
         FileInput{
-            fi: FileInput_ {
+            fi: @mut FileInput_ {
                 files: files,
                 current_reader: None,
                 state: FileInputState {
diff --git a/src/libstd/flatpipes.rs b/src/libstd/flatpipes.rs
index 874b96fd588..b712d6840ea 100644
--- a/src/libstd/flatpipes.rs
+++ b/src/libstd/flatpipes.rs
@@ -558,9 +558,11 @@ pub mod bytepipes {
         }
     }
 
+    // XXX: Remove `@mut` when this module is ported to the new I/O traits,
+    // which use `&mut self` properly.
     pub struct PipeBytePort {
         port: comm::Port<~[u8]>,
-        mut buf: ~[u8]
+        buf: @mut ~[u8]
     }
 
     pub struct PipeByteChan {
@@ -569,13 +571,13 @@ pub mod bytepipes {
 
     impl BytePort for PipeBytePort {
         fn try_recv(&self, count: uint) -> Option<~[u8]> {
-            if vec::uniq_len(&const self.buf) >= count {
-                let mut bytes = ::core::util::replace(&mut self.buf, ~[]);
-                self.buf = bytes.slice(count, bytes.len()).to_owned();
+            if vec::uniq_len(&const *self.buf) >= count {
+                let mut bytes = ::core::util::replace(&mut *self.buf, ~[]);
+                *self.buf = bytes.slice(count, bytes.len()).to_owned();
                 bytes.truncate(count);
                 return Some(bytes);
-            } else if vec::uniq_len(&const self.buf) > 0 {
-                let mut bytes = ::core::util::replace(&mut self.buf, ~[]);
+            } else if vec::uniq_len(&const *self.buf) > 0 {
+                let mut bytes = ::core::util::replace(&mut *self.buf, ~[]);
                 assert!(count > bytes.len());
                 match self.try_recv(count - bytes.len()) {
                     Some(rest) => {
@@ -584,11 +586,11 @@ pub mod bytepipes {
                     }
                     None => return None
                 }
-            } else if vec::uniq_len(&const self.buf) == 0 {
+            } else if vec::uniq_len(&const *self.buf) == 0 {
                 match self.port.try_recv() {
                     Some(buf) => {
                         assert!(!buf.is_empty());
-                        self.buf = buf;
+                        *self.buf = buf;
                         return self.try_recv(count);
                     }
                     None => return None
@@ -609,7 +611,7 @@ pub mod bytepipes {
         fn new(p: Port<~[u8]>) -> PipeBytePort {
             PipeBytePort {
                 port: p,
-                buf: ~[]
+                buf: @mut ~[]
             }
         }
     }
@@ -643,7 +645,7 @@ mod test {
 
         chan.send(10);
 
-        let bytes = copy chan.byte_chan.writer.bytes;
+        let bytes = copy *chan.byte_chan.writer.bytes;
 
         let reader = BufReader::new(bytes);
         let port = serial::reader_port(reader);
@@ -690,7 +692,7 @@ mod test {
 
         chan.send(10);
 
-        let bytes = copy chan.byte_chan.writer.bytes;
+        let bytes = copy *chan.byte_chan.writer.bytes;
 
         let reader = BufReader::new(bytes);
         let port = pod::reader_port(reader);
@@ -926,7 +928,7 @@ mod test {
             test_try_recv_none3(pipe_port_loader);
         }
 
-        fn test_try_recv_none4<P:BytePort>(+loader: PortLoader<P>) {
+        fn test_try_recv_none4<P:BytePort>(loader: PortLoader<P>) {
             assert!(do task::try || {
                 static CONTINUE: [u8, ..4] = [0xAA, 0xBB, 0xCC, 0xDD];
                 // The control word is followed by a valid length,
diff --git a/src/libstd/future.rs b/src/libstd/future.rs
index 5e3e64b2f1c..37eb1e02a80 100644
--- a/src/libstd/future.rs
+++ b/src/libstd/future.rs
@@ -28,10 +28,17 @@ use core::pipes::recv;
 use core::task;
 
 #[doc = "The future type"]
+#[cfg(stage0)]
 pub struct Future<A> {
     priv mut state: FutureState<A>,
 }
 
+#[doc = "The future type"]
+#[cfg(not(stage0))]
+pub struct Future<A> {
+    priv state: FutureState<A>,
+}
+
 // FIXME(#2829) -- futures should not be copyable, because they close
 // over ~fn's that have pipes and so forth within!
 #[unsafe_destructor]
@@ -47,13 +54,14 @@ priv enum FutureState<A> {
 
 /// Methods on the `future` type
 pub impl<A:Copy> Future<A> {
-    fn get(&self) -> A {
+    fn get(&mut self) -> A {
         //! Get the value of the future
         *(self.get_ref())
     }
 }
 
 pub impl<A> Future<A> {
+    #[cfg(stage0)]
     fn get_ref<'a>(&'a self) -> &'a A {
         /*!
         * Executes the future's closure and then returns a borrowed
@@ -61,19 +69,53 @@ pub impl<A> Future<A> {
         * the future.
         */
         unsafe {
-            match self.state {
-                Forced(ref mut v) => { return cast::transmute(v); }
-                Evaluating => fail!(~"Recursive forcing of future!"),
-                Pending(_) => {}
+            {
+                match self.state {
+                    Forced(ref mut v) => { return cast::transmute(v); }
+                    Evaluating => fail!(~"Recursive forcing of future!"),
+                    Pending(_) => {}
+                }
             }
+            {
+                let mut state = Evaluating;
+                self.state <-> state;
+                match state {
+                    Forced(_) | Evaluating => fail!(~"Logic error."),
+                    Pending(f) => {
+                        self.state = Forced(f());
+                        cast::transmute(self.get_ref())
+                    }
+                }
+            }
+        }
+    }
 
-            let mut state = Evaluating;
-            self.state <-> state;
-            match state {
-                Forced(_) | Evaluating => fail!(~"Logic error."),
-                Pending(f) => {
-                    self.state = Forced(f());
-                    self.get_ref()
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[cfg(stage3)]
+    fn get_ref<'a>(&'a mut self) -> &'a A {
+        /*!
+        * Executes the future's closure and then returns a borrowed
+        * pointer to the result.  The borrowed pointer lasts as long as
+        * the future.
+        */
+        unsafe {
+            {
+                match self.state {
+                    Forced(ref mut v) => { return cast::transmute(v); }
+                    Evaluating => fail!(~"Recursive forcing of future!"),
+                    Pending(_) => {}
+                }
+            }
+            {
+                let mut state = Evaluating;
+                self.state <-> state;
+                match state {
+                    Forced(_) | Evaluating => fail!(~"Logic error."),
+                    Pending(f) => {
+                        self.state = Forced(f());
+                        cast::transmute(self.get_ref())
+                    }
                 }
             }
         }
@@ -142,15 +184,15 @@ pub fn spawn<A:Owned>(blk: ~fn() -> A) -> Future<A> {
 #[allow(non_implicitly_copyable_typarams)]
 #[cfg(test)]
 mod test {
-
     use future::*;
 
+    use core::cell::Cell;
     use core::comm::{oneshot, send_one};
     use core::task;
 
     #[test]
     fn test_from_value() {
-        let f = from_value(~"snail");
+        let mut f = from_value(~"snail");
         assert!(f.get() == ~"snail");
     }
 
@@ -158,31 +200,31 @@ mod test {
     fn test_from_port() {
         let (po, ch) = oneshot();
         send_one(ch, ~"whale");
-        let f = from_port(po);
+        let mut f = from_port(po);
         assert!(f.get() == ~"whale");
     }
 
     #[test]
     fn test_from_fn() {
-        let f = from_fn(|| ~"brail");
+        let mut f = from_fn(|| ~"brail");
         assert!(f.get() == ~"brail");
     }
 
     #[test]
     fn test_interface_get() {
-        let f = from_value(~"fail");
+        let mut f = from_value(~"fail");
         assert!(f.get() == ~"fail");
     }
 
     #[test]
     fn test_get_ref_method() {
-        let f = from_value(22);
+        let mut f = from_value(22);
         assert!(*f.get_ref() == 22);
     }
 
     #[test]
     fn test_spawn() {
-        let f = spawn(|| ~"bale");
+        let mut f = spawn(|| ~"bale");
         assert!(f.get() == ~"bale");
     }
 
@@ -190,15 +232,16 @@ mod test {
     #[should_fail]
     #[ignore(cfg(target_os = "win32"))]
     fn test_futurefail() {
-        let f = spawn(|| fail!());
+        let mut f = spawn(|| fail!());
         let _x: ~str = f.get();
     }
 
     #[test]
     fn test_sendable_future() {
         let expected = ~"schlorf";
-        let f = do spawn { copy expected };
-        do task::spawn || {
+        let f = Cell(do spawn { copy expected });
+        do task::spawn {
+            let mut f = f.take();
             let actual = f.get();
             assert!(actual == expected);
         }
diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs
index 781e44a8f3f..f684ebe8a3c 100644
--- a/src/libstd/getopts.rs
+++ b/src/libstd/getopts.rs
@@ -368,7 +368,7 @@ pub fn opt_count(mm: &Matches, nm: &str) -> uint {
 
 /// Returns true if any of several options were matched
 pub fn opts_present(mm: &Matches, names: &[~str]) -> bool {
-    for vec::each(names) |nm| {
+    for names.each |nm| {
         match find_opt(mm.opts, mkname(*nm)) {
             Some(id) if !mm.vals[id].is_empty() => return true,
             _ => (),
@@ -395,7 +395,7 @@ pub fn opt_str(mm: &Matches, nm: &str) -> ~str {
  * option took an argument
  */
 pub fn opts_str(mm: &Matches, names: &[~str]) -> ~str {
-    for vec::each(names) |nm| {
+    for names.each |nm| {
         match opt_val(mm, *nm) {
           Val(copy s) => return s,
           _ => ()
diff --git a/src/libstd/io_util.rs b/src/libstd/io_util.rs
index 50d2eb6a785..7d43663cc80 100644
--- a/src/libstd/io_util.rs
+++ b/src/libstd/io_util.rs
@@ -13,14 +13,14 @@ use core::io;
 
 pub struct BufReader {
     buf: ~[u8],
-    mut pos: uint
+    pos: @mut uint
 }
 
 pub impl BufReader {
     pub fn new(v: ~[u8]) -> BufReader {
         BufReader {
             buf: v,
-            pos: 0
+            pos: @mut 0
         }
     }
 
@@ -29,13 +29,13 @@ pub impl BufReader {
         // I can't get the borrowing to work correctly
         let bytes_reader = BytesReader {
             bytes: ::core::util::id::<&[u8]>(self.buf),
-            pos: self.pos
+            pos: @mut *self.pos
         };
 
         let res = f(&bytes_reader);
 
         // FIXME #4429: This isn't correct if f fails
-        self.pos = bytes_reader.pos;
+        *self.pos = *bytes_reader.pos;
 
         return res;
     }
diff --git a/src/libstd/json.rs b/src/libstd/json.rs
index 3960a07dfce..c815c9dd480 100644
--- a/src/libstd/json.rs
+++ b/src/libstd/json.rs
@@ -220,11 +220,18 @@ impl serialize::Encoder for Encoder {
     }
 }
 
+#[cfg(stage0)]
 pub struct PrettyEncoder {
     priv wr: @io::Writer,
     priv mut indent: uint,
 }
 
+#[cfg(not(stage0))]
+pub struct PrettyEncoder {
+    priv wr: @io::Writer,
+    priv indent: uint,
+}
+
 pub fn PrettyEncoder(wr: @io::Writer) -> PrettyEncoder {
     PrettyEncoder {
         wr: wr,
@@ -838,10 +845,16 @@ pub fn from_str(s: &str) -> Result<Json, Error> {
     }
 }
 
+#[cfg(stage0)]
 pub struct Decoder {
     priv mut stack: ~[Json],
 }
 
+#[cfg(not(stage0))]
+pub struct Decoder {
+    priv stack: ~[Json],
+}
+
 pub fn Decoder(json: Json) -> Decoder {
     Decoder {
         stack: ~[json]
diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs
index aac0ff63166..9a0eb6d85db 100644
--- a/src/libstd/net_ip.rs
+++ b/src/libstd/net_ip.rs
@@ -425,7 +425,7 @@ mod test {
         let results = result::unwrap(ga_result);
         debug!("test_get_addr: Number of results for %s: %?",
                         localhost_name, vec::len(results));
-        for vec::each(results) |r| {
+        for results.each |r| {
             let ipv_prefix = match *r {
               Ipv4(_) => ~"IPv4",
               Ipv6(_) => ~"IPv6"
diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs
index 53eb6c5561b..bc4168ba7f8 100644
--- a/src/libstd/net_tcp.rs
+++ b/src/libstd/net_tcp.rs
@@ -71,14 +71,14 @@ pub fn TcpSocket(socket_data: @TcpSocketData) -> TcpSocket {
  * satisfy both the `io::Reader` and `io::Writer` traits.
  */
 pub struct TcpSocketBuf {
-    data: @TcpBufferedSocketData,
-    mut end_of_stream: bool
+    data: @mut TcpBufferedSocketData,
+    end_of_stream: @mut bool
 }
 
-pub fn TcpSocketBuf(data: @TcpBufferedSocketData) -> TcpSocketBuf {
+pub fn TcpSocketBuf(data: @mut TcpBufferedSocketData) -> TcpSocketBuf {
     TcpSocketBuf {
         data: data,
-        end_of_stream: false
+        end_of_stream: @mut false
     }
 }
 
@@ -670,7 +670,7 @@ fn listen_common(host_ip: ip::IpAddr,
             &ip::Ipv4(_) => { false }
             &ip::Ipv6(_) => { true }
         },
-        mut active: true
+        active: @mut true
     };
     let server_data_ptr: *TcpListenFcData = &server_data;
 
@@ -751,7 +751,7 @@ fn listen_common(host_ip: ip::IpAddr,
                     debug!(
                         "tcp::listen post-kill recv hl interact %?",
                              loop_ptr);
-                    (*server_data_ptr).active = false;
+                    *(*server_data_ptr).active = false;
                     uv::ll::close(server_stream_ptr, tcp_lfc_close_cb);
                 }
             };
@@ -782,7 +782,7 @@ fn listen_common(host_ip: ip::IpAddr,
                     debug!(
                         "tcp::listen post-kill recv hl interact %?",
                              loop_ptr);
-                    (*server_data_ptr).active = false;
+                    *(*server_data_ptr).active = false;
                     uv::ll::close(server_stream_ptr, tcp_lfc_close_cb);
                 }
             };
@@ -816,8 +816,8 @@ fn listen_common(host_ip: ip::IpAddr,
  * A buffered wrapper that you can cast as an `io::Reader` or `io::Writer`
  */
 pub fn socket_buf(sock: TcpSocket) -> TcpSocketBuf {
-    TcpSocketBuf(@TcpBufferedSocketData {
-        sock: sock, mut buf: ~[], buf_off: 0
+    TcpSocketBuf(@mut TcpBufferedSocketData {
+        sock: sock, buf: ~[], buf_off: 0
     })
 }
 
@@ -902,12 +902,15 @@ impl io::Reader for TcpSocketBuf {
           // need to read in data from the socket. Note that the internal
           // buffer is of no use anymore as we read all bytes from it,
           // so we can throw it away.
-          let read_result = read(&self.data.sock, 0u);
+          let read_result = {
+            let data = &*self.data;
+            read(&data.sock, 0)
+          };
           if read_result.is_err() {
               let err_data = read_result.get_err();
 
               if err_data.err_name == ~"EOF" {
-                  self.end_of_stream = true;
+                  *self.end_of_stream = true;
                   break;
               } else {
                   debug!("ERROR sock_buf as io::reader.read err %? %?",
@@ -917,8 +920,7 @@ impl io::Reader for TcpSocketBuf {
                   // should show up in a later call to read().
                   break;
               }
-          }
-          else {
+          } else {
               self.data.buf = result::unwrap(read_result);
               self.data.buf_off = 0;
           }
@@ -934,27 +936,29 @@ impl io::Reader for TcpSocketBuf {
             return c as int
           }
 
-          let read_result = read(&self.data.sock, 0u);
+          let read_result = {
+            let data = &*self.data;
+            read(&data.sock, 0)
+          };
           if read_result.is_err() {
               let err_data = read_result.get_err();
 
               if err_data.err_name == ~"EOF" {
-                  self.end_of_stream = true;
+                  *self.end_of_stream = true;
                   return -1
               } else {
                   debug!("ERROR sock_buf as io::reader.read err %? %?",
                          err_data.err_name, err_data.err_msg);
                   fail!()
               }
-          }
-          else {
+          } else {
               self.data.buf = result::unwrap(read_result);
               self.data.buf_off = 0;
           }
         }
     }
     fn eof(&self) -> bool {
-        self.end_of_stream
+        *self.end_of_stream
     }
     fn seek(&self, dist: int, seek: io::SeekStyle) {
         debug!("tcp_socket_buf seek stub %? %?", dist, seek);
@@ -1204,7 +1208,7 @@ struct TcpListenFcData {
     on_connect_cb: ~fn(*uv::ll::uv_tcp_t),
     iotask: IoTask,
     ipv6: bool,
-    mut active: bool,
+    active: @mut bool,
 }
 
 extern fn tcp_lfc_close_cb(handle: *uv::ll::uv_tcp_t) {
@@ -1222,7 +1226,7 @@ extern fn tcp_lfc_on_connection_cb(handle: *uv::ll::uv_tcp_t,
         let server_data_ptr = uv::ll::get_data_for_uv_handle(handle)
             as *TcpListenFcData;
         let kill_ch = (*server_data_ptr).kill_ch.clone();
-        if (*server_data_ptr).active {
+        if *(*server_data_ptr).active {
             match status {
               0i32 => ((*server_data_ptr).on_connect_cb)(handle),
               _ => {
@@ -1230,7 +1234,7 @@ extern fn tcp_lfc_on_connection_cb(handle: *uv::ll::uv_tcp_t,
                 kill_ch.send(
                            Some(uv::ll::get_last_err_data(loop_ptr)
                                 .to_tcp_err()));
-                (*server_data_ptr).active = false;
+                *(*server_data_ptr).active = false;
               }
             }
         }
@@ -1430,8 +1434,8 @@ struct TcpSocketData {
 
 struct TcpBufferedSocketData {
     sock: TcpSocket,
-    mut buf: ~[u8],
-    mut buf_off: uint
+    buf: ~[u8],
+    buf_off: uint
 }
 
 #[cfg(test)]
@@ -1959,7 +1963,7 @@ mod test {
     }
 
     fn tcp_write_single(sock: &TcpSocket, val: ~[u8]) {
-        let write_result_future = sock.write_future(val);
+        let mut write_result_future = sock.write_future(val);
         let write_result = write_result_future.get();
         if result::is_err(&write_result) {
             debug!("tcp_write_single: write failed!");
diff --git a/src/libstd/par.rs b/src/libstd/par.rs
index cfedbb66caa..cf0eba9d30c 100644
--- a/src/libstd/par.rs
+++ b/src/libstd/par.rs
@@ -73,10 +73,10 @@ fn map_slices<A:Copy + Owned,B:Copy + Owned>(
         info!("num_tasks: %?", (num_tasks, futures.len()));
         assert!((num_tasks == futures.len()));
 
-        let r = do futures.map() |ys| {
+        let r = do vec::map_consume(futures) |ys| {
+            let mut ys = ys;
             ys.get()
         };
-        assert!((r.len() == futures.len()));
         r
     }
 }
diff --git a/src/libstd/priority_queue.rs b/src/libstd/priority_queue.rs
index 33fe1cfff8e..9bf7db07ac9 100644
--- a/src/libstd/priority_queue.rs
+++ b/src/libstd/priority_queue.rs
@@ -14,7 +14,7 @@ use core::old_iter::BaseIter;
 
 #[abi = "rust-intrinsic"]
 extern "rust-intrinsic" mod rusti {
-    fn move_val_init<T>(dst: &mut T, +src: T);
+    fn move_val_init<T>(dst: &mut T, src: T);
     fn init<T>() -> T;
 }
 
diff --git a/src/libstd/rc.rs b/src/libstd/rc.rs
index 6f72d8dc16d..815f03f4269 100644
--- a/src/libstd/rc.rs
+++ b/src/libstd/rc.rs
@@ -29,7 +29,7 @@ pub struct Rc<T> {
     priv ptr: *mut RcBox<T>,
 }
 
-pub impl<'self, T: Owned> Rc<T> {
+pub impl<T: Owned> Rc<T> {
     fn new(value: T) -> Rc<T> {
         unsafe {
             let ptr = malloc(sys::size_of::<RcBox<T>>() as size_t) as *mut RcBox<T>;
@@ -40,8 +40,8 @@ pub impl<'self, T: Owned> Rc<T> {
     }
 
     #[inline(always)]
-    fn borrow(&self) -> &'self T {
-        unsafe { cast::transmute_region(&(*self.ptr).value) }
+    fn borrow<'r>(&'r self) -> &'r T {
+        unsafe { cast::copy_lifetime(self, &(*self.ptr).value) }
     }
 }
 
@@ -119,7 +119,7 @@ pub struct RcMut<T> {
     priv ptr: *mut RcMutBox<T>,
 }
 
-pub impl<'self, T: Owned> RcMut<T> {
+pub impl<T: Owned> RcMut<T> {
     fn new(value: T) -> RcMut<T> {
         unsafe {
             let ptr = malloc(sys::size_of::<RcMutBox<T>>() as size_t) as *mut RcMutBox<T>;
@@ -136,7 +136,7 @@ pub impl<'self, T: Owned> RcMut<T> {
             assert!((*self.ptr).borrow != Mutable);
             let previous = (*self.ptr).borrow;
             (*self.ptr).borrow = Immutable;
-            f(cast::transmute_region(&(*self.ptr).value));
+            f(&(*self.ptr).value);
             (*self.ptr).borrow = previous;
         }
     }
@@ -147,7 +147,7 @@ pub impl<'self, T: Owned> RcMut<T> {
         unsafe {
             assert!((*self.ptr).borrow == Nothing);
             (*self.ptr).borrow = Mutable;
-            f(cast::transmute_mut_region(&mut (*self.ptr).value));
+            f(&mut (*self.ptr).value);
             (*self.ptr).borrow = Nothing;
         }
     }
diff --git a/src/libstd/sha1.rs b/src/libstd/sha1.rs
index a8e0f7d062a..cd5845ac544 100644
--- a/src/libstd/sha1.rs
+++ b/src/libstd/sha1.rs
@@ -250,7 +250,7 @@ pub fn sha1() -> @Sha1 {
         fn result_str(&mut self) -> ~str {
             let rr = mk_result(self);
             let mut s = ~"";
-            for vec::each(rr) |b| {
+            for rr.each |b| {
                 let hex = uint::to_str_radix(*b as uint, 16u);
                 if hex.len() == 1 {
                     s += "0";
@@ -378,7 +378,7 @@ mod tests {
         // Test that it works when accepting the message all at once
 
         let mut sh = sha1::sha1();
-        for vec::each(tests) |t| {
+        for tests.each |t| {
             sh.input_str(t.input);
             let out = sh.result();
             check_vec_eq(t.output, out);
@@ -392,7 +392,7 @@ mod tests {
 
 
         // Test that it works when accepting the message in pieces
-        for vec::each(tests) |t| {
+        for tests.each |t| {
             let len = str::len(t.input);
             let mut left = len;
             while left > 0u {
diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs
index a18e2f47a77..ae474e0c394 100644
--- a/src/libstd/sort.rs
+++ b/src/libstd/sort.rs
@@ -859,7 +859,7 @@ mod test_qsort {
         let immut_names = names;
 
         let pairs = vec::zip_slice(expected, immut_names);
-        for vec::each(pairs) |p| {
+        for pairs.each |p| {
             let (a, b) = *p;
             debug!("%d %d", a, b);
             assert!((a == b));
@@ -946,8 +946,10 @@ mod test_tim_sort {
 
     impl Ord for CVal {
         fn lt(&self, other: &CVal) -> bool {
-            let rng = rand::rng();
-            if rng.gen::<float>() > 0.995 { fail!(~"It's happening!!!"); }
+            let mut rng = rand::rng();
+            if rng.gen::<float>() > 0.995 {
+                fail!(~"It's happening!!!");
+            }
             (*self).val < other.val
         }
         fn le(&self, other: &CVal) -> bool { (*self).val <= other.val }
@@ -995,7 +997,7 @@ mod test_tim_sort {
     #[should_fail]
     #[cfg(unix)]
     fn crash_test() {
-        let rng = rand::rng();
+        let mut rng = rand::rng();
         let mut arr = do vec::from_fn(1000) |_i| {
             CVal { val: rng.gen() }
         };
@@ -1015,7 +1017,7 @@ mod test_tim_sort {
 
     #[test]
     fn test_bad_Ord_impl() {
-        let rng = rand::rng();
+        let mut rng = rand::rng();
         let mut arr = do vec::from_fn(500) |_i| {
             DVal { val: rng.gen() }
         };
@@ -1067,7 +1069,7 @@ mod big_tests {
             }
         }
 
-        let rng = rand::rng();
+        let mut rng = rand::rng();
 
         for uint::range(lo, hi) |i| {
             let n = 1 << i;
@@ -1138,7 +1140,7 @@ mod big_tests {
             }
         }
 
-        let rng = rand::rng();
+        let mut rng = rand::rng();
 
         for uint::range(lo, hi) |i| {
             let n = 1 << i;
diff --git a/src/libstd/sort_stage0.rs b/src/libstd/sort_stage0.rs
index f3d30ecd5cd..044c616dcd3 100644
--- a/src/libstd/sort_stage0.rs
+++ b/src/libstd/sort_stage0.rs
@@ -852,7 +852,7 @@ mod test_qsort {
         let immut_names = names;
 
         let pairs = vec::zip_slice(expected, immut_names);
-        for vec::each(pairs) |p| {
+        for pairs.each |p| {
             let (a, b) = *p;
             debug!("%d %d", a, b);
             assert!((a == b));
diff --git a/src/libstd/std.rc b/src/libstd/std.rc
index 51e11669f44..931974d2454 100644
--- a/src/libstd/std.rc
+++ b/src/libstd/std.rc
@@ -28,7 +28,9 @@ not required in or otherwise suitable for the core library.
 
 #[allow(vecs_implicitly_copyable)];
 #[deny(non_camel_case_types)];
-#[allow(deprecated_mutable_fields)];
+
+// Allow mutable fields only in stage0.
+#[warn(deprecated_mutable_fields)];
 
 pub mod uv_ll;
 
diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs
index e86ec793188..17d051518a9 100644
--- a/src/libstd/sync.rs
+++ b/src/libstd/sync.rs
@@ -997,7 +997,7 @@ mod tests {
                     }
                 }
             }
-            for vec::each(sibling_convos) |p| {
+            for sibling_convos.each |p| {
                 let _ = p.recv(); // wait for sibling to get in the mutex
             }
             do m2.lock { }
diff --git a/src/libstd/task_pool.rs b/src/libstd/task_pool.rs
index 661247df1c1..0c52e1ff80e 100644
--- a/src/libstd/task_pool.rs
+++ b/src/libstd/task_pool.rs
@@ -70,7 +70,9 @@ pub impl<T> TaskPool<T> {
                     task::spawn(task_body);
                 }
                 Some(sched_mode) => {
-                    task::task().sched_mode(sched_mode).spawn(task_body);
+                    let mut task = task::task();
+                    task.sched_mode(sched_mode);
+                    task.spawn(task_body);
                 }
             }
 
diff --git a/src/libstd/tempfile.rs b/src/libstd/tempfile.rs
index 10645e947e2..e02a7a33733 100644
--- a/src/libstd/tempfile.rs
+++ b/src/libstd/tempfile.rs
@@ -13,7 +13,7 @@
 use core::rand::RngUtil;
 
 pub fn mkdtemp(tmpdir: &Path, suffix: &str) -> Option<Path> {
-    let r = rand::rng();
+    let mut r = rand::rng();
     for 1000.times {
         let p = tmpdir.push(r.gen_str(16) + suffix);
         if os::make_dir(&p, 0x1c0) { // 700
diff --git a/src/libstd/term.rs b/src/libstd/term.rs
index a79b9f4c849..236c7f668c2 100644
--- a/src/libstd/term.rs
+++ b/src/libstd/term.rs
@@ -13,7 +13,6 @@
 use core::io;
 use core::option;
 use core::os;
-use core::vec;
 
 // FIXME (#2807): Windows support.
 
@@ -50,7 +49,7 @@ pub fn color_supported() -> bool {
                            ~"screen-bce", ~"xterm-256color"];
     return match os::getenv(~"TERM") {
           option::Some(ref env) => {
-            for vec::each(supported_terms) |term| {
+            for supported_terms.each |term| {
                 if *term == *env { return true; }
             }
             false
diff --git a/src/libstd/test.rs b/src/libstd/test.rs
index 95bfc80ac55..3b527efabd3 100644
--- a/src/libstd/test.rs
+++ b/src/libstd/test.rs
@@ -355,7 +355,7 @@ fn print_failures(st: &ConsoleTestState) {
         failures.push(name.to_str());
     }
     sort::tim_sort(failures);
-    for vec::each(failures) |name| {
+    for failures.each |name| {
         st.out.write_line(fmt!("    %s", name.to_str()));
     }
 }
@@ -556,9 +556,12 @@ pub fn run_test(force_ignore: bool,
         let testfn_cell = ::core::cell::Cell(testfn);
         do task::spawn {
             let mut result_future = None; // task::future_result(builder);
-            task::task().unlinked().future_result(|+r| {
-                result_future = Some(r);
-            }).spawn(testfn_cell.take());
+
+            let mut task = task::task();
+            task.unlinked();
+            task.future_result(|r| { result_future = Some(r) });
+            task.spawn(testfn_cell.take());
+
             let task_result = result_future.unwrap().recv();
             let test_result = calc_result(&desc,
                                           task_result == task::Success);
@@ -688,7 +691,7 @@ pub mod bench {
         // not met, it may run as long as the Go algorithm.
         pub fn auto_bench(&mut self, f: &fn(&mut BenchHarness)) -> ~[f64] {
 
-            let rng = rand::rng();
+            let mut rng = rand::rng();
             let mut magnitude = 10;
             let mut prev_madp = 0.0;
 
@@ -925,7 +928,7 @@ mod tests {
         {
             fn testfn() { }
             let mut tests = ~[];
-            for vec::each(names) |name| {
+            for names.each |name| {
                 let test = TestDescAndFn {
                     desc: TestDesc {
                         name: DynTestName(*name),
@@ -951,7 +954,7 @@ mod tests {
 
         let pairs = vec::zip(expected, filtered);
 
-        for vec::each(pairs) |p| {
+        for pairs.each |p| {
             match *p {
                 (ref a, ref b) => {
                     assert!((*a == b.desc.name.to_str()));
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 8889abe6472..31d8eb20a67 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -861,7 +861,6 @@ mod tests {
     use core::result;
     use core::result::{Err, Ok};
     use core::str;
-    use core::vec;
 
     fn test_get_time() {
         static some_recent_date: i64 = 1325376000i64; // 2012-01-01T00:00:00Z
@@ -1028,7 +1027,7 @@ mod tests {
             }
         }
 
-        for vec::each([
+        for [
             ~"Sunday",
             ~"Monday",
             ~"Tuesday",
@@ -1036,11 +1035,11 @@ mod tests {
             ~"Thursday",
             ~"Friday",
             ~"Saturday"
-        ]) |day| {
+        ].each |day| {
             assert!(test(*day, ~"%A"));
         }
 
-        for vec::each([
+        for [
             ~"Sun",
             ~"Mon",
             ~"Tue",
@@ -1048,11 +1047,11 @@ mod tests {
             ~"Thu",
             ~"Fri",
             ~"Sat"
-        ]) |day| {
+        ].each |day| {
             assert!(test(*day, ~"%a"));
         }
 
-        for vec::each([
+        for [
             ~"January",
             ~"February",
             ~"March",
@@ -1065,11 +1064,11 @@ mod tests {
             ~"October",
             ~"November",
             ~"December"
-        ]) |day| {
+        ].each |day| {
             assert!(test(*day, ~"%B"));
         }
 
-        for vec::each([
+        for [
             ~"Jan",
             ~"Feb",
             ~"Mar",
@@ -1082,7 +1081,7 @@ mod tests {
             ~"Oct",
             ~"Nov",
             ~"Dec"
-        ]) |day| {
+        ].each |day| {
             assert!(test(*day, ~"%b"));
         }
 
diff --git a/src/libstd/timer.rs b/src/libstd/timer.rs
index b19b2f2889e..0d15bbb54d3 100644
--- a/src/libstd/timer.rs
+++ b/src/libstd/timer.rs
@@ -14,10 +14,11 @@ use uv;
 use uv::iotask;
 use uv::iotask::IoTask;
 
-use core::libc;
-use core::libc::c_void;
 use core::cast::transmute;
+use core::cast;
 use core::comm::{stream, Chan, SharedChan, Port, select2i};
+use core::libc::c_void;
+use core::libc;
 
 /**
  * Wait for timeout period then send provided value over a channel
@@ -120,22 +121,28 @@ pub fn sleep(iotask: &IoTask, msecs: uint) {
 pub fn recv_timeout<T:Copy + Owned>(iotask: &IoTask,
                                    msecs: uint,
                                    wait_po: &Port<T>)
-                                -> Option<T> {
-    let (timeout_po, timeout_ch) = stream::<()>();
+                                   -> Option<T> {
+    let mut (timeout_po, timeout_ch) = stream::<()>();
     delayed_send(iotask, msecs, &timeout_ch, ());
-    // FIXME: This could be written clearer (#2618)
-    either::either(
-        |_| {
-            None
-        }, |_| {
-            Some(wait_po.recv())
-        }, &select2i(&timeout_po, wait_po)
-    )
+
+    // XXX: Workaround due to ports and channels not being &mut. They should
+    // be.
+    unsafe {
+        let wait_po = cast::transmute_mut(wait_po);
+
+        // FIXME: This could be written clearer (#2618)
+        either::either(
+            |_| {
+                None
+            }, |_| {
+                Some(wait_po.recv())
+            }, &select2i(&mut timeout_po, wait_po)
+        )
+    }
 }
 
 // INTERNAL API
-extern fn delayed_send_cb(handle: *uv::ll::uv_timer_t,
-                                status: libc::c_int) {
+extern fn delayed_send_cb(handle: *uv::ll::uv_timer_t, status: libc::c_int) {
     unsafe {
         debug!(
             "delayed_send_cb handle %? status %?", handle, status);
@@ -212,7 +219,7 @@ mod test {
                 let hl_loop_clone = hl_loop.clone();
                 do task::spawn {
                     use core::rand::*;
-                    let rng = rng();
+                    let mut rng = rng();
                     for old_iter::repeat(times) {
                         sleep(&hl_loop_clone, rng.next() as uint % maxms);
                     }
@@ -269,7 +276,8 @@ mod test {
         let hl_loop = uv::global_loop::get();
 
         for old_iter::repeat(times as uint) {
-            let expected = rand::rng().gen_str(16u);
+            let mut rng = rand::rng();
+            let expected = rng.gen_str(16u);
             let (test_po, test_ch) = stream::<~str>();
             let hl_loop_clone = hl_loop.clone();
             do task::spawn() {
diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs
index c8ab48e65c0..06ac1a71bac 100644
--- a/src/libstd/treemap.rs
+++ b/src/libstd/treemap.rs
@@ -848,7 +848,7 @@ mod test_treemap {
         check_equal(ctrl, &map);
         assert!(map.find(&5).is_none());
 
-        let rng = rand::IsaacRng::new_seeded(&[42]);
+        let mut rng = rand::IsaacRng::new_seeded(&[42]);
 
         for 3.times {
             for 90.times {
diff --git a/src/libstd/uv_global_loop.rs b/src/libstd/uv_global_loop.rs
index c8311cff2cf..97df64d5266 100644
--- a/src/libstd/uv_global_loop.rs
+++ b/src/libstd/uv_global_loop.rs
@@ -62,7 +62,9 @@ fn get_monitor_task_gl() -> IoTask {
                 }
             };
             if installed {
-                do task().unlinked().spawn() {
+                let mut task = task();
+                task.unlinked();
+                do task.spawn {
                     unsafe {
                         debug!("global monitor task starting");
                         // As a weak task the runtime will notify us
@@ -88,7 +90,9 @@ fn get_monitor_task_gl() -> IoTask {
 }
 
 fn spawn_loop() -> IoTask {
-    let builder = do task().add_wrapper |task_body| {
+    let mut builder = task();
+
+    do builder.add_wrapper |task_body| {
         let result: ~fn() = || {
             // The I/O loop task also needs to be weak so it doesn't keep
             // the runtime alive
@@ -107,7 +111,8 @@ fn spawn_loop() -> IoTask {
         };
         result
     };
-    let builder = builder.unlinked();
+
+    builder.unlinked();
     spawn_iotask(builder)
 }
 
diff --git a/src/libstd/uv_iotask.rs b/src/libstd/uv_iotask.rs
index 79a40559971..2922f403f34 100644
--- a/src/libstd/uv_iotask.rs
+++ b/src/libstd/uv_iotask.rs
@@ -36,11 +36,11 @@ impl Clone for IoTask {
     }
 }
 
-pub fn spawn_iotask(task: task::TaskBuilder) -> IoTask {
-
+pub fn spawn_iotask(mut task: task::TaskBuilder) -> IoTask {
     let (iotask_port, iotask_chan) = stream();
 
-    do task.sched_mode(task::SingleThreaded).spawn {
+    task.sched_mode(task::SingleThreaded);
+    do task.spawn {
         debug!("entering libuv task");
         run_loop(&iotask_chan);
         debug!("libuv task exiting");
diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs
index afc7b9c8106..5cccf2c348d 100644
--- a/src/libstd/uv_ll.rs
+++ b/src/libstd/uv_ll.rs
@@ -780,23 +780,24 @@ extern mod rustrt {
     // FIXME ref #2064
     unsafe fn rust_uv_tcp_connect(connect_ptr: *uv_connect_t,
                                   tcp_handle_ptr: *uv_tcp_t,
-                                  ++after_cb: *u8,
-                                  ++addr: *sockaddr_in) -> libc::c_int;
+                                  after_cb: *u8,
+                                  addr: *sockaddr_in)
+                                  -> libc::c_int;
     // FIXME ref #2064
     unsafe fn rust_uv_tcp_bind(tcp_server: *uv_tcp_t,
-                               ++addr: *sockaddr_in) -> libc::c_int;
+                               addr: *sockaddr_in) -> libc::c_int;
     // FIXME ref #2064
     unsafe fn rust_uv_tcp_connect6(connect_ptr: *uv_connect_t,
                                    tcp_handle_ptr: *uv_tcp_t,
-                                   ++after_cb: *u8,
-                                   ++addr: *sockaddr_in6) -> libc::c_int;
+                                   after_cb: *u8,
+                                   addr: *sockaddr_in6) -> libc::c_int;
     // FIXME ref #2064
     unsafe fn rust_uv_tcp_bind6(tcp_server: *uv_tcp_t,
-                                ++addr: *sockaddr_in6) -> libc::c_int;
+                                addr: *sockaddr_in6) -> libc::c_int;
     unsafe fn rust_uv_tcp_getpeername(tcp_handle_ptr: *uv_tcp_t,
-                                      ++name: *sockaddr_in) -> libc::c_int;
+                                      name: *sockaddr_in) -> libc::c_int;
     unsafe fn rust_uv_tcp_getpeername6(tcp_handle_ptr: *uv_tcp_t,
-                                       ++name: *sockaddr_in6) ->libc::c_int;
+                                       name: *sockaddr_in6) ->libc::c_int;
     unsafe fn rust_uv_listen(stream: *libc::c_void,
                              backlog: libc::c_int,
                              cb: *u8) -> libc::c_int;
@@ -804,7 +805,7 @@ extern mod rustrt {
                           -> libc::c_int;
     unsafe fn rust_uv_write(req: *libc::c_void,
                             stream: *libc::c_void,
-                            ++buf_in: *uv_buf_t,
+                            buf_in: *uv_buf_t,
                             buf_cnt: libc::c_int,
                             cb: *u8)
         -> libc::c_int;
@@ -843,7 +844,7 @@ extern mod rustrt {
     unsafe fn rust_uv_addrinfo_as_sockaddr_in6(input: *addrinfo)
         -> *sockaddr_in6;
     unsafe fn rust_uv_malloc_buf_base_of(sug_size: libc::size_t) -> *u8;
-    unsafe fn rust_uv_free_base_of_buf(++buf: uv_buf_t);
+    unsafe fn rust_uv_free_base_of_buf(buf: uv_buf_t);
     unsafe fn rust_uv_get_stream_handle_from_connect_req(
         connect_req: *uv_connect_t)
         -> *uv_stream_t;
@@ -864,8 +865,8 @@ extern mod rustrt {
         -> *libc::c_void;
     unsafe fn rust_uv_set_data_for_req(req: *libc::c_void,
                                        data: *libc::c_void);
-    unsafe fn rust_uv_get_base_from_buf(++buf: uv_buf_t) -> *u8;
-    unsafe fn rust_uv_get_len_from_buf(++buf: uv_buf_t) -> libc::size_t;
+    unsafe fn rust_uv_get_base_from_buf(buf: uv_buf_t) -> *u8;
+    unsafe fn rust_uv_get_len_from_buf(buf: uv_buf_t) -> libc::size_t;
 
     // sizeof testing helpers
     unsafe fn rust_uv_helper_uv_tcp_t_size() -> libc::c_uint;
@@ -1258,7 +1259,7 @@ mod test {
 
     extern fn on_read_cb(stream: *uv_stream_t,
                         nread: libc::ssize_t,
-                        ++buf: uv_buf_t) {
+                        buf: uv_buf_t) {
         unsafe {
             let nread = nread as int;
             debug!("CLIENT entering on_read_cb nred: %d",
@@ -1444,7 +1445,7 @@ mod test {
 
     extern fn on_server_read_cb(client_stream_ptr: *uv_stream_t,
                                nread: libc::ssize_t,
-                               ++buf: uv_buf_t) {
+                               buf: uv_buf_t) {
         unsafe {
             let nread = nread as int;
             if (nread > 0) {
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 2216226ecb3..c8fc04eaea1 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1168,7 +1168,7 @@ pub type struct_field = spanned<struct_field_>;
 #[auto_decode]
 #[deriving(Eq)]
 pub enum struct_field_kind {
-    named_field(ident, struct_mutability, visibility),
+    named_field(ident, visibility),
     unnamed_field   // element of a tuple-like struct
 }
 
@@ -1221,17 +1221,6 @@ pub enum item_ {
 #[auto_encode]
 #[auto_decode]
 #[deriving(Eq)]
-pub enum struct_mutability { struct_mutable, struct_immutable }
-
-impl to_bytes::IterBytes for struct_mutability {
-    fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
-        (*self as u8).iter_bytes(lsb0, f)
-    }
-}
-
-#[auto_encode]
-#[auto_decode]
-#[deriving(Eq)]
 pub struct foreign_item {
     ident: ident,
     attrs: ~[attribute],
@@ -1291,6 +1280,21 @@ mod test {
 
     #[test] fn test_marksof () {
         let stopname = uints_to_name(&~[12,14,78]);
+        assert_eq!(s,~[]);
+        xorPush(&mut s,14);
+        assert_eq!(s,~[14]);
+        xorPush(&mut s,15);
+        assert_eq!(s,~[14,15]);
+        xorPush (&mut s,16);
+        assert_eq! (s,~[14,15,16]);
+        xorPush (&mut s,16);
+        assert_eq! (s,~[14,15]);
+        xorPush (&mut s,15);
+        assert_eq! (s,~[14]);
+    }
+
+    #[test] fn test_marksof () {
+        let stopname = uints_to_name(&~[12,14,78]);
         let name1 = uints_to_name(&~[4,9,7]);
         assert_eq!(marksof (MT,stopname),~[]);
         assert_eq! (marksof (Mark (4,@Mark(98,@MT)),stopname),~[4,98]);
@@ -1347,3 +1351,12 @@ mod test {
 }
 
 */
+//
+// Local Variables:
+// mode: rust
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// End:
+//
diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs
index a6094903d7b..77277dea814 100644
--- a/src/libsyntax/ast_util.rs
+++ b/src/libsyntax/ast_util.rs
@@ -285,7 +285,7 @@ pub fn split_trait_methods(trait_methods: &[trait_method])
 
 pub fn struct_field_visibility(field: ast::struct_field) -> visibility {
     match field.node.kind {
-        ast::named_field(_, _, visibility) => visibility,
+        ast::named_field(_, visibility) => visibility,
         ast::unnamed_field => ast::public
     }
 }
@@ -461,7 +461,7 @@ pub fn id_visitor(vfn: @fn(node_id)) -> visit::vt<()> {
                 }
             }
 
-            for vec::each(d.inputs) |arg| {
+            for d.inputs.each |arg| {
                 vfn(arg.id)
             }
         },
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs
index bdf0a2a1dd0..5bd4f89a3b3 100644
--- a/src/libsyntax/ext/auto_encode.rs
+++ b/src/libsyntax/ext/auto_encode.rs
@@ -914,19 +914,15 @@ struct field {
 
 fn mk_struct_fields(fields: &[@ast::struct_field]) -> ~[field] {
     do fields.map |field| {
-        let (ident, mutbl) = match field.node.kind {
-            ast::named_field(ident, mutbl, _) => (ident, mutbl),
-            _ => fail!(~"[auto_encode] does not support \
-                        unnamed fields")
+        let ident = match field.node.kind {
+            ast::named_field(ident, _) => ident,
+            _ => fail!(~"[auto_encode] does not support unnamed fields")
         };
 
         field {
             span: field.span,
             ident: ident,
-            mutbl: match mutbl {
-                ast::struct_mutable => ast::m_mutbl,
-                ast::struct_immutable => ast::m_imm,
-            },
+            mutbl: ast::m_imm,
         }
     }
 }
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 4c876669f47..3097cb799a2 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -11,6 +11,7 @@
 use ast;
 use codemap;
 use codemap::span;
+use fold;
 use ext::base::ext_ctxt;
 use ext::build;
 
@@ -54,43 +55,52 @@ pub fn mk_binary(cx: @ext_ctxt, sp: span, op: ast::binop,
     cx.next_id(); // see ast_util::op_expr_callee_id
     mk_expr(cx, sp, ast::expr_binary(op, lhs, rhs))
 }
+
+pub fn mk_deref(cx: @ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr {
+    mk_unary(cx, sp, ast::deref, e)
+}
 pub fn mk_unary(cx: @ext_ctxt, sp: span, op: ast::unop, e: @ast::expr)
              -> @ast::expr {
     cx.next_id(); // see ast_util::op_expr_callee_id
     mk_expr(cx, sp, ast::expr_unary(op, e))
 }
 pub fn mk_raw_path(sp: span, idents: ~[ast::ident]) -> @ast::Path {
-    mk_raw_path_(sp, idents, ~[])
+    mk_raw_path_(sp, idents, None, ~[])
 }
 pub fn mk_raw_path_(sp: span,
                     idents: ~[ast::ident],
+                    rp: Option<@ast::Lifetime>,
                     types: ~[@ast::Ty])
                  -> @ast::Path {
     @ast::Path { span: sp,
                  global: false,
                  idents: idents,
-                 rp: None,
+                 rp: rp,
                  types: types }
 }
 pub fn mk_raw_path_global(sp: span, idents: ~[ast::ident]) -> @ast::Path {
-    mk_raw_path_global_(sp, idents, ~[])
+    mk_raw_path_global_(sp, idents, None, ~[])
 }
 pub fn mk_raw_path_global_(sp: span,
                            idents: ~[ast::ident],
+                           rp: Option<@ast::Lifetime>,
                            types: ~[@ast::Ty]) -> @ast::Path {
     @ast::Path { span: sp,
                  global: true,
                  idents: idents,
-                 rp: None,
+                 rp: rp,
                  types: types }
 }
+pub fn mk_path_raw(cx: @ext_ctxt, sp: span, path: @ast::Path)-> @ast::expr {
+    mk_expr(cx, sp, ast::expr_path(path))
+}
 pub fn mk_path(cx: @ext_ctxt, sp: span, idents: ~[ast::ident])
             -> @ast::expr {
-    mk_expr(cx, sp, ast::expr_path(mk_raw_path(sp, idents)))
+    mk_path_raw(cx, sp, mk_raw_path(sp, idents))
 }
 pub fn mk_path_global(cx: @ext_ctxt, sp: span, idents: ~[ast::ident])
                    -> @ast::expr {
-    mk_expr(cx, sp, ast::expr_path(mk_raw_path_global(sp, idents)))
+    mk_path_raw(cx, sp, mk_raw_path_global(sp, idents))
 }
 pub fn mk_access_(cx: @ext_ctxt, sp: span, p: @ast::expr, m: ast::ident)
                -> @ast::expr {
@@ -354,44 +364,69 @@ pub fn mk_stmt(cx: @ext_ctxt, span: span, expr: @ast::expr) -> @ast::stmt {
     let stmt_ = ast::stmt_semi(expr, cx.next_id());
     @codemap::spanned { node: stmt_, span: span }
 }
+
+pub fn mk_ty_mt(ty: @ast::Ty, mutbl: ast::mutability) -> ast::mt {
+    ast::mt {
+        ty: ty,
+        mutbl: mutbl
+    }
+}
+
+pub fn mk_ty(cx: @ext_ctxt,
+             span: span,
+             ty: ast::ty_) -> @ast::Ty {
+    @ast::Ty {
+        id: cx.next_id(),
+        span: span,
+        node: ty
+    }
+}
+
 pub fn mk_ty_path(cx: @ext_ctxt,
                   span: span,
                   idents: ~[ ast::ident ])
                -> @ast::Ty {
     let ty = build::mk_raw_path(span, idents);
-    let ty = ast::ty_path(ty, cx.next_id());
-    let ty = @ast::Ty { id: cx.next_id(), node: ty, span: span };
-    ty
+    mk_ty_path_path(cx, span, ty)
 }
+
 pub fn mk_ty_path_global(cx: @ext_ctxt,
                          span: span,
                          idents: ~[ ast::ident ])
                       -> @ast::Ty {
     let ty = build::mk_raw_path_global(span, idents);
-    let ty = ast::ty_path(ty, cx.next_id());
-    let ty = @ast::Ty { id: cx.next_id(), node: ty, span: span };
-    ty
+    mk_ty_path_path(cx, span, ty)
+}
+
+pub fn mk_ty_path_path(cx: @ext_ctxt,
+                       span: span,
+                       path: @ast::Path)
+                      -> @ast::Ty {
+    let ty = ast::ty_path(path, cx.next_id());
+    mk_ty(cx, span, ty)
 }
+
 pub fn mk_ty_rptr(cx: @ext_ctxt,
                   span: span,
                   ty: @ast::Ty,
+                  lifetime: Option<@ast::Lifetime>,
                   mutbl: ast::mutability)
                -> @ast::Ty {
-    @ast::Ty {
-        id: cx.next_id(),
-        span: span,
-        node: ast::ty_rptr(
-            None,
-            ast::mt { ty: ty, mutbl: mutbl }
-        ),
-    }
+    mk_ty(cx, span,
+          ast::ty_rptr(lifetime, mk_ty_mt(ty, mutbl)))
+}
+pub fn mk_ty_uniq(cx: @ext_ctxt, span: span, ty: @ast::Ty) -> @ast::Ty {
+    mk_ty(cx, span, ast::ty_uniq(mk_ty_mt(ty, ast::m_imm)))
+}
+pub fn mk_ty_box(cx: @ext_ctxt, span: span,
+                 ty: @ast::Ty, mutbl: ast::mutability) -> @ast::Ty {
+    mk_ty(cx, span, ast::ty_box(mk_ty_mt(ty, mutbl)))
 }
+
+
+
 pub fn mk_ty_infer(cx: @ext_ctxt, span: span) -> @ast::Ty {
-    @ast::Ty {
-        id: cx.next_id(),
-        node: ast::ty_infer,
-        span: span,
-    }
+    mk_ty(cx, span, ast::ty_infer)
 }
 pub fn mk_trait_ref_global(cx: @ext_ctxt,
                            span: span,
@@ -482,3 +517,20 @@ pub fn mk_unreachable(cx: @ext_ctxt, span: span) -> @ast::expr {
 pub fn mk_unreachable_arm(cx: @ext_ctxt, span: span) -> ast::arm {
     mk_arm(cx, span, ~[mk_pat_wild(cx, span)], mk_unreachable(cx, span))
 }
+
+//
+// Duplication functions
+//
+// These functions just duplicate AST nodes.
+//
+
+pub fn duplicate_expr(cx: @ext_ctxt, expr: @ast::expr) -> @ast::expr {
+    let folder = fold::default_ast_fold();
+    let folder = @fold::AstFoldFns {
+        new_id: |_| cx.next_id(),
+        ..*folder
+    };
+    let folder = fold::make_fold(folder);
+    folder.fold_expr(expr)
+}
+
diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs
index d996bca60a3..1c33fe35070 100644
--- a/src/libsyntax/ext/deriving/clone.rs
+++ b/src/libsyntax/ext/deriving/clone.rs
@@ -13,7 +13,6 @@ use codemap::span;
 use ext::base::ext_ctxt;
 use ext::build;
 use ext::deriving::generic::*;
-use core::option::{None,Some};
 
 
 pub fn expand_deriving_clone(cx: @ext_ctxt,
@@ -22,13 +21,16 @@ pub fn expand_deriving_clone(cx: @ext_ctxt,
                              in_items: ~[@item])
                           -> ~[@item] {
     let trait_def = TraitDef {
-        path: ~[~"core", ~"clone", ~"Clone"],
+        path: Path::new(~[~"core", ~"clone", ~"Clone"]),
         additional_bounds: ~[],
+        generics: LifetimeBounds::empty(),
         methods: ~[
             MethodDef {
                 name: ~"clone",
-                nargs: 0,
-                output_type: None, // return Self
+                generics: LifetimeBounds::empty(),
+                self_ty: borrowed_explicit_self(),
+                args: ~[],
+                ret_ty: Self,
                 const_nonmatching: false,
                 combine_substructure: cs_clone
             }
@@ -66,7 +68,8 @@ fn cs_clone(cx: @ext_ctxt, span: span,
             ctor_ident = ~[ variant.node.name ];
             all_fields = af;
         },
-        EnumNonMatching(*) => cx.bug("Non-matching enum variants in `deriving(Clone)`")
+        EnumNonMatching(*) => cx.span_bug(span, "Non-matching enum variants in `deriving(Clone)`"),
+        StaticEnum(*) | StaticStruct(*) => cx.span_bug(span, "Static method in `deriving(Clone)`")
     }
 
     match all_fields {
diff --git a/src/libsyntax/ext/deriving/cmp/eq.rs b/src/libsyntax/ext/deriving/cmp/eq.rs
index c0060cc67dc..e431e1f78bf 100644
--- a/src/libsyntax/ext/deriving/cmp/eq.rs
+++ b/src/libsyntax/ext/deriving/cmp/eq.rs
@@ -8,15 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
 use ast::{meta_item, item, expr};
 use codemap::span;
 use ext::base::ext_ctxt;
 use ext::build;
 use ext::deriving::generic::*;
 
-use core::option::Some;
-
 pub fn expand_deriving_eq(cx: @ext_ctxt,
                           span: span,
                           mitem: @meta_item,
@@ -24,28 +21,32 @@ pub fn expand_deriving_eq(cx: @ext_ctxt,
     // structures are equal if all fields are equal, and non equal, if
     // any fields are not equal or if the enum variants are different
     fn cs_eq(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
-        cs_and(|cx, span, _| build::mk_bool(cx, span, false),
+        cs_and(|cx, span, _, _| build::mk_bool(cx, span, false),
                                  cx, span, substr)
     }
     fn cs_ne(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
-        cs_or(|cx, span, _| build::mk_bool(cx, span, true),
+        cs_or(|cx, span, _, _| build::mk_bool(cx, span, true),
               cx, span, substr)
     }
+
     macro_rules! md (
         ($name:expr, $f:ident) => {
             MethodDef {
                 name: $name,
-                output_type: Some(~[~"bool"]),
-                nargs: 1,
+                generics: LifetimeBounds::empty(),
+                self_ty: borrowed_explicit_self(),
+                args: ~[borrowed_self()],
+                ret_ty: Literal(Path::new(~[~"bool"])),
                 const_nonmatching: true,
                 combine_substructure: $f
             },
         }
-    )
+    );
 
     let trait_def = TraitDef {
-        path: ~[~"core", ~"cmp", ~"Eq"],
+        path: Path::new(~[~"core", ~"cmp", ~"Eq"]),
         additional_bounds: ~[],
+        generics: LifetimeBounds::empty(),
         methods: ~[
             md!(~"eq", cs_eq),
             md!(~"ne", cs_ne)
diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs
index 398e27eb3e3..5998fc7145d 100644
--- a/src/libsyntax/ext/deriving/cmp/ord.rs
+++ b/src/libsyntax/ext/deriving/cmp/ord.rs
@@ -14,29 +14,33 @@ use codemap::span;
 use ext::base::ext_ctxt;
 use ext::build;
 use ext::deriving::generic::*;
-use core::option::Some;
-
-macro_rules! md {
-    ($name:expr, $less:expr, $equal:expr) => {
-        MethodDef {
-            name: $name,
-            output_type: Some(~[~"bool"]),
-            nargs: 1,
-            const_nonmatching: false,
-            combine_substructure: |cx, span, substr|
-                    cs_ord($less, $equal, cx, span, substr)
-        }
-    }
-}
 
 pub fn expand_deriving_ord(cx: @ext_ctxt,
                            span: span,
                            mitem: @meta_item,
                            in_items: ~[@item]) -> ~[@item] {
+    macro_rules! md (
+        ($name:expr, $less:expr, $equal:expr) => {
+            MethodDef {
+                name: $name,
+                generics: LifetimeBounds::empty(),
+                self_ty: borrowed_explicit_self(),
+                args: ~[borrowed_self()],
+                ret_ty: Literal(Path::new(~[~"bool"])),
+                const_nonmatching: false,
+                combine_substructure: |cx, span, substr|
+                    cs_ord($less, $equal, cx, span, substr)
+            }
+        }
+    );
+
+
+
     let trait_def = TraitDef {
-        path: ~[~"core", ~"cmp", ~"Ord"],
+        path: Path::new(~[~"core", ~"cmp", ~"Ord"]),
         // XXX: Ord doesn't imply Eq yet
-        additional_bounds: ~[~[~"core", ~"cmp", ~"Eq"]],
+        additional_bounds: ~[Literal(Path::new(~[~"core", ~"cmp", ~"Eq"]))],
+        generics: LifetimeBounds::empty(),
         methods: ~[
             md!(~"lt", true,  false),
             md!(~"le", true,  true),
@@ -97,19 +101,19 @@ fn cs_ord(less: bool, equal: bool,
             }
 
             let cmp = build::mk_method_call(cx, span,
-                                            self_f, cx.ident_of(~"eq"), other_fs);
+                                            self_f, cx.ident_of(~"eq"), other_fs.to_owned());
             let subexpr = build::mk_simple_block(cx, span, subexpr);
             let elseif = expr_if(cmp, subexpr, Some(false_blk_expr));
             let elseif = build::mk_expr(cx, span, elseif);
 
             let cmp = build::mk_method_call(cx, span,
-                                            self_f, binop, other_fs);
+                                            self_f, binop, other_fs.to_owned());
             let if_ = expr_if(cmp, true_blk, Some(elseif));
 
             build::mk_expr(cx, span, if_)
         },
         base,
-        |cx, span, args| {
+        |cx, span, args, _| {
             // nonmatching enums, order by the order the variants are
             // written
             match args {
diff --git a/src/libsyntax/ext/deriving/cmp/totaleq.rs b/src/libsyntax/ext/deriving/cmp/totaleq.rs
index fc8ec103a60..068a7bc06b1 100644
--- a/src/libsyntax/ext/deriving/cmp/totaleq.rs
+++ b/src/libsyntax/ext/deriving/cmp/totaleq.rs
@@ -15,26 +15,27 @@ use ext::base::ext_ctxt;
 use ext::build;
 use ext::deriving::generic::*;
 
-use core::option::Some;
-
 pub fn expand_deriving_totaleq(cx: @ext_ctxt,
                           span: span,
                           mitem: @meta_item,
                           in_items: ~[@item]) -> ~[@item] {
 
     fn cs_equals(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
-        cs_and(|cx, span, _| build::mk_bool(cx, span, false),
+        cs_and(|cx, span, _, _| build::mk_bool(cx, span, false),
                cx, span, substr)
     }
 
     let trait_def = TraitDef {
-        path: ~[~"core", ~"cmp", ~"TotalEq"],
+        path: Path::new(~[~"core", ~"cmp", ~"TotalEq"]),
         additional_bounds: ~[],
+        generics: LifetimeBounds::empty(),
         methods: ~[
             MethodDef {
                 name: ~"equals",
-                output_type: Some(~[~"bool"]),
-                nargs: 1,
+                generics: LifetimeBounds::empty(),
+                self_ty: borrowed_explicit_self(),
+                args: ~[borrowed_self()],
+                ret_ty: Literal(Path::new(~[~"bool"])),
                 const_nonmatching: true,
                 combine_substructure: cs_equals
             }
diff --git a/src/libsyntax/ext/deriving/cmp/totalord.rs b/src/libsyntax/ext/deriving/cmp/totalord.rs
index a098a7463d3..ac873c5bd12 100644
--- a/src/libsyntax/ext/deriving/cmp/totalord.rs
+++ b/src/libsyntax/ext/deriving/cmp/totalord.rs
@@ -14,20 +14,22 @@ use ext::base::ext_ctxt;
 use ext::build;
 use ext::deriving::generic::*;
 use core::cmp::{Ordering, Equal, Less, Greater};
-use core::option::Some;
 
 pub fn expand_deriving_totalord(cx: @ext_ctxt,
                                 span: span,
                                 mitem: @meta_item,
                                 in_items: ~[@item]) -> ~[@item] {
     let trait_def = TraitDef {
-        path: ~[~"core", ~"cmp", ~"TotalOrd"],
+        path: Path::new(~[~"core", ~"cmp", ~"TotalOrd"]),
         additional_bounds: ~[],
+        generics: LifetimeBounds::empty(),
         methods: ~[
             MethodDef {
                 name: ~"cmp",
-                output_type: Some(~[~"core", ~"cmp", ~"Ordering"]),
-                nargs: 1,
+                generics: LifetimeBounds::empty(),
+                self_ty: borrowed_explicit_self(),
+                args: ~[borrowed_self()],
+                ret_ty: Literal(Path::new(~[~"core", ~"cmp", ~"Ordering"])),
                 const_nonmatching: false,
                 combine_substructure: cs_cmp
             }
@@ -64,7 +66,7 @@ pub fn cs_cmp(cx: @ext_ctxt, span: span,
             build::mk_call_global(cx, span, lexical_ord, ~[old, new])
         },
         ordering_const(cx, span, Equal),
-        |cx, span, list| {
+        |cx, span, list, _| {
             match list {
                 // an earlier nonmatching variant is Less than a
                 // later one
diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs
index fe270abc2e4..2bdfe51c50e 100644
--- a/src/libsyntax/ext/deriving/decodable.rs
+++ b/src/libsyntax/ext/deriving/decodable.rs
@@ -66,6 +66,7 @@ fn create_derived_decodable_impl(
             cx.ident_of(~"serialize"),
             cx.ident_of(~"Decodable")
         ],
+        None,
         ~[
             build::mk_simple_ty_path(cx, span, cx.ident_of(~"__D"))
         ]
@@ -77,7 +78,7 @@ fn create_derived_decodable_impl(
         generics,
         methods,
         trait_path,
-        generic_ty_params,
+        Generics { ty_params: generic_ty_params, lifetimes: opt_vec::Empty },
         opt_vec::Empty
     )
 }
@@ -96,6 +97,7 @@ fn create_decode_method(
         cx,
         span,
         build::mk_simple_ty_path(cx, span, cx.ident_of(~"__D")),
+        None,
         ast::m_mutbl
     );
     let d_ident = cx.ident_of(~"__d");
@@ -278,7 +280,7 @@ fn expand_deriving_decodable_struct_method(
     let mut fields = ~[];
     for struct_def.fields.each |struct_field| {
         match struct_field.node.kind {
-            named_field(ident, _, _) => {
+            named_field(ident, _) => {
                 fields.push(create_read_struct_field(cx, span, i, ident));
             }
             unnamed_field => {
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index 8f8139790ad..54e5687f415 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -66,6 +66,7 @@ fn create_derived_encodable_impl(
             cx.ident_of(~"serialize"),
             cx.ident_of(~"Encodable")
         ],
+        None,
         ~[
             build::mk_simple_ty_path(cx, span, cx.ident_of(~"__E"))
         ]
@@ -77,7 +78,7 @@ fn create_derived_encodable_impl(
         generics,
         methods,
         trait_path,
-        generic_ty_params,
+        Generics { ty_params: generic_ty_params, lifetimes: opt_vec::Empty },
         opt_vec::Empty
     )
 }
@@ -94,6 +95,7 @@ fn create_encode_method(
         cx,
         span,
         build::mk_simple_ty_path(cx, span, cx.ident_of(~"__E")),
+        None,
         ast::m_mutbl
     );
     let e_arg = build::mk_arg(cx, span, cx.ident_of(~"__e"), e_arg_type);
@@ -209,7 +211,7 @@ fn expand_deriving_encodable_struct_method(
     let mut statements = ~[];
     for struct_def.fields.each |struct_field| {
         match struct_field.node.kind {
-            named_field(ident, _, _) => {
+            named_field(ident, _) => {
                 // Create the accessor for this field.
                 let self_field = build::mk_access(
                     cx,
@@ -303,7 +305,7 @@ fn expand_deriving_encodable_enum_method(
     // Create the arms of the match in the method body.
     let arms = do enum_definition.variants.mapi |i, variant| {
         // Create the matching pattern.
-        let pat = create_enum_variant_pattern(cx, span, variant, ~"__self");
+        let (pat, fields) = create_enum_variant_pattern(cx, span, variant, ~"__self", ast::m_imm);
 
         // Feed the discriminant to the encode function.
         let mut stmts = ~[];
@@ -311,11 +313,7 @@ fn expand_deriving_encodable_enum_method(
         // Feed each argument in this variant to the encode function
         // as well.
         let variant_arg_len = variant_arg_count(cx, span, variant);
-        for uint::range(0, variant_arg_len) |j| {
-            // Create the expression for this field.
-            let field_ident = cx.ident_of(~"__self_" + j.to_str());
-            let field = build::mk_path(cx, span, ~[ field_ident ]);
-
+        for fields.eachi |j, &(_, field)| {
             // Call the substructure method.
             let expr = call_substructure_encode_method(cx, span, field);
 
diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs
index 05941f4cbd6..d785f3816de 100644
--- a/src/libsyntax/ext/deriving/generic.rs
+++ b/src/libsyntax/ext/deriving/generic.rs
@@ -16,23 +16,22 @@ access to the fields of the 4 different sorts of structs and enum
 variants, as well as creating the method and impl ast instances.
 
 Supported features (fairly exhaustive):
-- Methods taking any number of parameters of type `&Self`, including
-  none other than `self`. (`MethodDef.nargs`)
-- Methods returning `Self` or a non-parameterised type
-  (e.g. `bool` or `core::cmp::Ordering`). (`MethodDef.output_type`)
-- Generating `impl`s for types with type parameters
+- Methods taking any number of parameters of any type, and returning
+  any type, other than vectors, bottom and closures.
+- Generating `impl`s for types with type parameters and lifetimes
   (e.g. `Option<T>`), the parameters are automatically given the
-  current trait as a bound.
+  current trait as a bound. (This includes separate type parameters
+  and lifetimes for methods.)
 - Additional bounds on the type parameters, e.g. the `Ord` instance
   requires an explicit `Eq` bound at the
   moment. (`TraitDef.additional_bounds`)
 
-(Key unsupported things: methods with arguments of non-`&Self` type,
-traits with parameters, methods returning parameterised types, static
-methods.)
+Unsupported: FIXME #6257: calling methods on borrowed pointer fields,
+e.g. deriving TotalEq/TotalOrd/Clone don't work on `struct A(&int)`,
+because of how the auto-dereferencing happens.
 
 The most important thing for implementers is the `Substructure` and
-`SubstructureFields` objects. The latter groups 3 possibilities of the
+`SubstructureFields` objects. The latter groups 5 possibilities of the
 arguments:
 
 - `Struct`, when `Self` is a struct (including tuple structs, e.g
@@ -42,42 +41,57 @@ arguments:
 - `EnumNonMatching` when `Self` is an enum and the arguments are not
   the same variant (e.g. `None`, `Some(1)` and `None`). If
   `const_nonmatching` is true, this will contain an empty list.
+- `StaticEnum` and `StaticStruct` for static methods, where the type
+  being derived upon is either a enum or struct respectively. (Any
+  argument with type Self is just grouped among the non-self
+  arguments.)
 
 In the first two cases, the values from the corresponding fields in
 all the arguments are grouped together. In the `EnumNonMatching` case
 this isn't possible (different variants have different fields), so the
-fields are grouped by which argument they come from.
+fields are grouped by which argument they come from. There are no
+fields with values in the static cases, so these are treated entirely
+differently.
 
-All of the cases have `Option<ident>` in several places associated
+The non-static cases have `Option<ident>` in several places associated
 with field `expr`s. This represents the name of the field it is
 associated with. It is only not `None` when the associated field has
 an identifier in the source code. For example, the `x`s in the
 following snippet
 
-    struct A { x : int }
+~~~
+struct A { x : int }
 
-    struct B(int);
+struct B(int);
 
-    enum C {
-        C0(int),
-        C1 { x: int }
-    }
+enum C {
+    C0(int),
+    C1 { x: int }
+}
 
 The `int`s in `B` and `C0` don't have an identifier, so the
 `Option<ident>`s would be `None` for them.
 
+In the static cases, the structure is summarised, either into the
+number of fields or a list of field idents (for tuple structs and
+record structs, respectively), or a list of these, for enums (one for
+each variant). For empty struct and empty enum variants, it is
+represented as a count of 0.
+
 # Examples
 
 The following simplified `Eq` is used for in-code examples:
 
-    trait Eq {
-        fn eq(&self, other: &Self);
-    }
-    impl Eq for int {
-        fn eq(&self, other: &int) -> bool {
-            *self == *other
-        }
+~~~
+trait Eq {
+    fn eq(&self, other: &Self);
+}
+impl Eq for int {
+    fn eq(&self, other: &int) -> bool {
+        *self == *other
     }
+}
+~~~
 
 Some examples of the values of `SubstructureFields` follow, using the
 above `Eq`, `A`, `B` and `C`.
@@ -86,65 +100,85 @@ above `Eq`, `A`, `B` and `C`.
 
 When generating the `expr` for the `A` impl, the `SubstructureFields` is
 
-    Struct(~[(Some(<ident of x>),
-             <expr for self.x>,
-             ~[<expr for other.x])])
+~~~
+Struct(~[(Some(<ident of x>),
+         <expr for &self.x>,
+         ~[<expr for &other.x])])
+~~~
 
 For the `B` impl, called with `B(a)` and `B(b)`,
 
-    Struct(~[(None,
-              <expr for a>
-              ~[<expr for b>])])
+~~~
+Struct(~[(None,
+          <expr for &a>
+          ~[<expr for &b>])])
+~~~
 
 ## Enums
 
 When generating the `expr` for a call with `self == C0(a)` and `other
 == C0(b)`, the SubstructureFields is
 
-    EnumMatching(0, <ast::variant for C0>,
-                 ~[None,
-                   <expr for a>,
-                   ~[<expr for b>]])
+~~~
+EnumMatching(0, <ast::variant for C0>,
+             ~[None,
+               <expr for &a>,
+               ~[<expr for &b>]])
+~~~
 
 For `C1 {x}` and `C1 {x}`,
 
-    EnumMatching(1, <ast::variant for C1>,
-                 ~[Some(<ident of x>),
-                   <expr for self.x>,
-                   ~[<expr for other.x>]])
+~~~
+EnumMatching(1, <ast::variant for C1>,
+             ~[Some(<ident of x>),
+               <expr for &self.x>,
+               ~[<expr for &other.x>]])
+~~~
 
 For `C0(a)` and `C1 {x}` ,
 
-    EnumNonMatching(~[(0, <ast::variant for B0>,
-                       ~[(None, <expr for a>)]),
-                      (1, <ast::variant for B1>,
-                       ~[(Some(<ident of x>),
-                          <expr for other.x>)])])
+~~~
+EnumNonMatching(~[(0, <ast::variant for B0>,
+                   ~[(None, <expr for &a>)]),
+                  (1, <ast::variant for B1>,
+                   ~[(Some(<ident of x>),
+                      <expr for &other.x>)])])
+~~~
+
+(and vice versa, but with the order of the outermost list flipped.)
 
-(and vice verse, but with the order of the outermost list flipped.)
+## Static
+
+A static method on the above would result in,
+
+~~~~
+StaticStruct(<ast::struct_def of A>, Right(~[<ident of x>]))
+
+StaticStruct(<ast::struct_def of B>, Left(1))
+
+StaticEnum(<ast::enum_def of C>, ~[(<ident of C0>, Left(1)),
+                                   (<ident of C1>, Right(~[<ident of x>]))])
+~~~
 
 */
 
 use ast;
+use ast::{enum_def, expr, ident, Generics, struct_def};
 
-use ast::{
-    and, binop, deref, enum_def, expr, expr_match, ident, impure_fn,
-    item, Generics, m_imm, meta_item, method, named_field, or,
-    pat_wild, public, struct_def, sty_region, ty_rptr, ty_path,
-    variant};
-
-use ast_util;
 use ext::base::ext_ctxt;
 use ext::build;
 use ext::deriving::*;
 use codemap::{span,respan};
 use opt_vec;
 
+pub use self::ty::*;
+mod ty;
+
 pub fn expand_deriving_generic(cx: @ext_ctxt,
                                span: span,
-                               _mitem: @meta_item,
-                               in_items: ~[@item],
-                               trait_def: &TraitDef) -> ~[@item] {
+                               _mitem: @ast::meta_item,
+                               in_items: ~[@ast::item],
+                               trait_def: &TraitDef) -> ~[@ast::item] {
     let expand_enum: ExpandDerivingEnumDefFn =
         |cx, span, enum_def, type_ident, generics| {
         trait_def.expand_enum_def(cx, span, enum_def, type_ident, generics)
@@ -160,25 +194,38 @@ pub fn expand_deriving_generic(cx: @ext_ctxt,
 }
 
 pub struct TraitDef<'self> {
-    /// Path of the trait
-    path: ~[~str],
-    /// Additional bounds required of any type parameters, other than
-    /// the current trait
-    additional_bounds: ~[~[~str]],
+    /// Path of the trait, including any type parameters
+    path: Path,
+    /// Additional bounds required of any type parameters of the type,
+    /// other than the current trait
+    additional_bounds: ~[Ty],
+
+    /// Any extra lifetimes and/or bounds, e.g. `D: std::serialize::Decoder`
+    generics: LifetimeBounds,
+
     methods: ~[MethodDef<'self>]
 }
 
+
 pub struct MethodDef<'self> {
     /// name of the method
     name: ~str,
-    /// The path of return type of the method, e.g. `~[~"core",
-    /// ~"cmp", ~"Eq"]`. `None` for `Self`.
-    output_type: Option<~[~str]>,
-    /// Number of arguments other than `self` (all of type `&Self`)
-    nargs: uint,
+    /// List of generics, e.g. `R: core::rand::Rng`
+    generics: LifetimeBounds,
+
+    /// Whether there is a self argument (outer Option) i.e. whether
+    /// this is a static function, and whether it is a pointer (inner
+    /// Option)
+    self_ty: Option<Option<PtrTy>>,
+
+    /// Arguments other than the self argument
+    args: ~[Ty],
+
+    /// Return type
+    ret_ty: Ty,
 
     /// if the value of the nonmatching enums is independent of the
-    /// actual enums, i.e. can use _ => .. match.
+    /// actual enum variants, i.e. can use _ => .. match.
     const_nonmatching: bool,
 
     combine_substructure: CombineSubstructureFunc<'self>
@@ -186,18 +233,24 @@ pub struct MethodDef<'self> {
 
 /// All the data about the data structure/method being derived upon.
 pub struct Substructure<'self> {
+    /// ident of self
     type_ident: ident,
+    /// ident of the method
     method_ident: ident,
-    fields: &'self SubstructureFields
+    /// dereferenced access to any Self or Ptr(Self, _) arguments
+    self_args: &'self [@expr],
+    /// verbatim access to any other arguments
+    nonself_args: &'self [@expr],
+    fields: &'self SubstructureFields<'self>
 }
 
 /// A summary of the possible sets of fields. See above for details
 /// and examples
-pub enum SubstructureFields {
+pub enum SubstructureFields<'self> {
     /**
-    Vec of `(field ident, self, [others])` where the field ident is
-    the ident of the current field (`None` for all fields in tuple
-    structs)
+    Vec of `(field ident, self_or_other)` where the field
+    ident is the ident of the current field (`None` for all fields in tuple
+    structs).
     */
     Struct(~[(Option<ident>, @expr, ~[@expr])]),
 
@@ -206,17 +259,23 @@ pub enum SubstructureFields {
     fields: `(field ident, self, [others])`, where the field ident is
     only non-`None` in the case of a struct variant.
     */
-    EnumMatching(uint, variant, ~[(Option<ident>, @expr, ~[@expr])]),
+    EnumMatching(uint, ast::variant, ~[(Option<ident>, @expr, ~[@expr])]),
 
     /**
     non-matching variants of the enum, [(variant index, ast::variant,
     [field ident, fields])] (i.e. all fields for self are in the
     first tuple, for other1 are in the second tuple, etc.)
     */
-    EnumNonMatching(~[(uint, variant, ~[(Option<ident>, @expr)])])
+    EnumNonMatching(~[(uint, ast::variant, ~[(Option<ident>, @expr)])]),
+
+    /// A static method where Self is a struct
+    StaticStruct(&'self ast::struct_def, Either<uint, ~[ident]>),
+    /// A static method where Self is an enum
+    StaticEnum(&'self ast::enum_def, ~[(ident, Either<uint, ~[ident]>)])
 }
 
 
+
 /**
 Combine the values of all the fields together. The last argument is
 all the fields of all the structures, see above for details.
@@ -225,31 +284,34 @@ pub type CombineSubstructureFunc<'self> =
     &'self fn(@ext_ctxt, span, &Substructure) -> @expr;
 
 /**
-Deal with non-matching enum variants, the argument is a list
+Deal with non-matching enum variants, the arguments are a list
 representing each variant: (variant index, ast::variant instance,
-[variant fields])
+[variant fields]), and a list of the nonself args of the type
 */
 pub type EnumNonMatchFunc<'self> =
-    &'self fn(@ext_ctxt, span, ~[(uint, variant, ~[(Option<ident>, @expr)])]) -> @expr;
-
+    &'self fn(@ext_ctxt, span,
+              ~[(uint, ast::variant,
+                 ~[(Option<ident>, @expr)])],
+              &[@expr]) -> @expr;
 
 
 impl<'self> TraitDef<'self> {
     fn create_derived_impl(&self, cx: @ext_ctxt, span: span,
                            type_ident: ident, generics: &Generics,
-                           methods: ~[@method]) -> @item {
-        let trait_path = build::mk_raw_path_global(
-            span,
-            do self.path.map |&s| { cx.ident_of(s) });
+                           methods: ~[@ast::method]) -> @ast::item {
+        let trait_path = self.path.to_path(cx, span, type_ident, generics);
+
+        let trait_generics = self.generics.to_generics(cx, span, type_ident, generics);
 
         let additional_bounds = opt_vec::from(
-            do self.additional_bounds.map |v| {
-                do v.map |&s| { cx.ident_of(s) }
+            do self.additional_bounds.map |p| {
+                p.to_path(cx, span, type_ident, generics)
             });
+
         create_derived_impl(cx, span,
                             type_ident, generics,
                             methods, trait_path,
-                            opt_vec::Empty,
+                            trait_generics,
                             additional_bounds)
     }
 
@@ -257,22 +319,28 @@ impl<'self> TraitDef<'self> {
                          span: span,
                          struct_def: &struct_def,
                          type_ident: ident,
-                         generics: &Generics)
-    -> @item {
-        let is_tuple = is_struct_tuple(struct_def);
-
+                         generics: &Generics) -> @ast::item {
         let methods = do self.methods.map |method_def| {
-            let body = if is_tuple {
-                method_def.expand_struct_tuple_method_body(cx, span,
-                                                           struct_def,
-                                                           type_ident)
+            let (self_ty, self_args, nonself_args, tys) =
+                method_def.split_self_nonself_args(cx, span, type_ident, generics);
+
+            let body = if method_def.is_static() {
+                method_def.expand_static_struct_method_body(
+                    cx, span,
+                    struct_def,
+                    type_ident,
+                    self_args, nonself_args)
             } else {
                 method_def.expand_struct_method_body(cx, span,
                                                      struct_def,
-                                                     type_ident)
+                                                     type_ident,
+                                                     self_args, nonself_args)
             };
 
-            method_def.create_method(cx, span, type_ident, generics, body)
+            method_def.create_method(cx, span,
+                                     type_ident, generics,
+                                     self_ty, tys,
+                                     body)
         };
 
         self.create_derived_impl(cx, span, type_ident, generics, methods)
@@ -282,13 +350,28 @@ impl<'self> TraitDef<'self> {
                        cx: @ext_ctxt, span: span,
                        enum_def: &enum_def,
                        type_ident: ident,
-                       generics: &Generics) -> @item {
+                       generics: &Generics) -> @ast::item {
         let methods = do self.methods.map |method_def| {
-            let body = method_def.expand_enum_method_body(cx, span,
-                                                          enum_def,
-                                                          type_ident);
+            let (self_ty, self_args, nonself_args, tys) =
+                method_def.split_self_nonself_args(cx, span, type_ident, generics);
+
+            let body = if method_def.is_static() {
+                method_def.expand_static_enum_method_body(
+                    cx, span,
+                    enum_def,
+                    type_ident,
+                    self_args, nonself_args)
+            } else {
+                method_def.expand_enum_method_body(cx, span,
+                                                   enum_def,
+                                                   type_ident,
+                                                   self_args, nonself_args)
+            };
 
-            method_def.create_method(cx, span, type_ident, generics, body)
+            method_def.create_method(cx, span,
+                                     type_ident, generics,
+                                     self_ty, tys,
+                                     body)
         };
 
         self.create_derived_impl(cx, span, type_ident, generics, methods)
@@ -300,266 +383,241 @@ impl<'self> MethodDef<'self> {
                                 cx: @ext_ctxt,
                                 span: span,
                                 type_ident: ident,
+                                self_args: &[@expr],
+                                nonself_args: &[@expr],
                                 fields: &SubstructureFields)
         -> @expr {
         let substructure = Substructure {
             type_ident: type_ident,
             method_ident: cx.ident_of(self.name),
+            self_args: self_args,
+            nonself_args: nonself_args,
             fields: fields
         };
         (self.combine_substructure)(cx, span,
                                     &substructure)
     }
 
-    fn get_output_type_path(&self, cx: @ext_ctxt, span: span,
-                              generics: &Generics, type_ident: ident) -> @ast::Path {
-        match self.output_type {
-            None => { // Self, add any type parameters
-                let out_ty_params = do vec::build |push| {
-                    for generics.ty_params.each |ty_param| {
-                        push(build::mk_ty_path(cx, span, ~[ ty_param.ident ]));
-                    }
-                };
+    fn get_ret_ty(&self, cx: @ext_ctxt, span: span,
+                     generics: &Generics, type_ident: ident) -> @ast::Ty {
+        self.ret_ty.to_ty(cx, span, type_ident, generics)
+    }
+
+    fn is_static(&self) -> bool {
+        self.self_ty.is_none()
+    }
+
+    fn split_self_nonself_args(&self, cx: @ext_ctxt, span: span,
+                             type_ident: ident, generics: &Generics)
+        -> (ast::self_ty, ~[@expr], ~[@expr], ~[(ident, @ast::Ty)]) {
+
+        let mut self_args = ~[], nonself_args = ~[], arg_tys = ~[];
+        let mut ast_self_ty = respan(span, ast::sty_static);
+        let mut nonstatic = false;
+
+        match self.self_ty {
+            Some(self_ptr) => {
+                let (self_expr, self_ty) = ty::get_explicit_self(cx, span, self_ptr);
 
-                build::mk_raw_path_(span, ~[ type_ident ], out_ty_params)
+                ast_self_ty = self_ty;
+                self_args.push(self_expr);
+                nonstatic = true;
             }
-            Some(str_path) => {
-                let p = do str_path.map |&s| { cx.ident_of(s) };
-                build::mk_raw_path_global(span, p)
+            _ => {}
+        }
+
+        for self.args.eachi |i, ty| {
+            let ast_ty = ty.to_ty(cx, span, type_ident, generics);
+            let ident = cx.ident_of(fmt!("__arg_%u", i));
+            arg_tys.push((ident, ast_ty));
+
+            let arg_expr = build::mk_path(cx, span, ~[ident]);
+
+            match *ty {
+                // for static methods, just treat any Self
+                // arguments as a normal arg
+                Self if nonstatic  => {
+                    self_args.push(arg_expr);
+                }
+                Ptr(~Self, _) if nonstatic => {
+                    self_args.push(build::mk_deref(cx, span, arg_expr))
+                }
+                _ => {
+                    nonself_args.push(arg_expr);
+                }
             }
         }
+
+        (ast_self_ty, self_args, nonself_args, arg_tys)
     }
 
     fn create_method(&self, cx: @ext_ctxt, span: span,
                      type_ident: ident,
-                     generics: &Generics, body: @expr) -> @method {
-        // Create the `Self` type of the `other` parameters.
-        let arg_path_type = create_self_type_with_params(cx,
-                                                         span,
-                                                         type_ident,
-                                                         generics);
-        let arg_type = ty_rptr(
-            None,
-            ast::mt { ty: arg_path_type, mutbl: m_imm }
-        );
-        let arg_type = @ast::Ty {
-            id: cx.next_id(),
-            node: arg_type,
-            span: span,
-        };
-
-        // create the arguments
-        let other_idents = create_other_idents(cx, self.nargs);
-        let args = do other_idents.map |&id| {
-            build::mk_arg(cx, span, id, arg_type)
+                     generics: &Generics,
+                     self_ty: ast::self_ty,
+                     arg_types: ~[(ident, @ast::Ty)],
+                     body: @expr) -> @ast::method {
+        // create the generics that aren't for Self
+        let fn_generics = self.generics.to_generics(cx, span, type_ident, generics);
+
+        let args = do arg_types.map |&(id, ty)| {
+            build::mk_arg(cx, span, id, ty)
         };
 
-        let output_type = self.get_output_type_path(cx, span, generics, type_ident);
-        let output_type = ty_path(output_type, cx.next_id());
-        let output_type = @ast::Ty {
-            id: cx.next_id(),
-            node: output_type,
-            span: span,
-        };
+        let ret_type = self.get_ret_ty(cx, span, generics, type_ident);
 
         let method_ident = cx.ident_of(self.name);
-        let fn_decl = build::mk_fn_decl(args, output_type);
+        let fn_decl = build::mk_fn_decl(args, ret_type);
         let body_block = build::mk_simple_block(cx, span, body);
 
+
         // Create the method.
-        let self_ty = respan(span, sty_region(None, m_imm));
         @ast::method {
             ident: method_ident,
             attrs: ~[],
-            generics: ast_util::empty_generics(),
+            generics: fn_generics,
             self_ty: self_ty,
-            purity: impure_fn,
+            purity: ast::impure_fn,
             decl: fn_decl,
             body: body_block,
             id: cx.next_id(),
             span: span,
             self_id: cx.next_id(),
-            vis: public
+            vis: ast::public
         }
     }
 
     /**
-    ```
+    ~~~
     #[deriving(Eq)]
-    struct A(int, int);
+    struct A { x: int, y: int }
 
     // equivalent to:
-
     impl Eq for A {
-        fn eq(&self, __other_1: &A) -> bool {
+        fn eq(&self, __arg_1: &A) -> bool {
             match *self {
-                (ref self_1, ref self_2) => {
-                    match *__other_1 {
-                        (ref __other_1_1, ref __other_1_2) => {
-                            self_1.eq(__other_1_1) && self_2.eq(__other_1_2)
+                A {x: ref __self_0_0, y: ref __self_0_1} => {
+                    match *__arg_1 {
+                        A {x: ref __self_1_0, y: ref __self_1_1} => {
+                            __self_0_0.eq(__self_1_0) && __self_0_1.eq(__self_1_1)
                         }
                     }
                 }
             }
         }
     }
-    ```
+    ~~~
     */
-    fn expand_struct_tuple_method_body(&self,
-                                           cx: @ext_ctxt,
-                                               span: span,
-                                               struct_def: &struct_def,
-                                           type_ident: ident) -> @expr {
-        let self_str = ~"self";
-        let other_strs = create_other_strs(self.nargs);
-        let num_fields = struct_def.fields.len();
-
-
-        let fields = do struct_def.fields.mapi |i, _| {
-            let other_fields = do other_strs.map |&other_str| {
-                let other_field_ident = cx.ident_of(fmt!("%s_%u", other_str, i));
-                build::mk_path(cx, span, ~[ other_field_ident ])
-            };
-
-            let self_field_ident = cx.ident_of(fmt!("%s_%u", self_str, i));
-            let self_field = build::mk_path(cx, span, ~[ self_field_ident ]);
+    fn expand_struct_method_body(&self,
+                                 cx: @ext_ctxt,
+                                 span: span,
+                                 struct_def: &struct_def,
+                                 type_ident: ident,
+                                 self_args: &[@expr],
+                                 nonself_args: &[@expr])
+        -> @expr {
 
-            (None, self_field, other_fields)
+        let mut raw_fields = ~[], // ~[[fields of self], [fields of next Self arg], [etc]]
+                patterns = ~[];
+        for uint::range(0, self_args.len()) |i| {
+            let (pat, ident_expr) = create_struct_pattern(cx, span,
+                                                          type_ident, struct_def,
+                                                          fmt!("__self_%u", i), ast::m_imm);
+            patterns.push(pat);
+            raw_fields.push(ident_expr);
         };
 
-        let mut match_body = self.call_substructure_method(cx, span, type_ident, &Struct(fields));
-
-        let type_path = build::mk_raw_path(span, ~[type_ident]);
-
-        // create the matches from inside to out (i.e. other_{self.nargs} to other_1)
-        for other_strs.each_reverse |&other_str| {
-            match_body = create_deref_match(cx, span, type_path,
-                                            other_str, num_fields,
-                                            match_body)
-        }
-
-        // create the match on self
-        return create_deref_match(cx, span, type_path,
-                                  ~"self", num_fields, match_body);
-
-        /**
-        Creates a match expression against a tuple that needs to
-        be dereferenced, but nothing else
+        // transpose raw_fields
+        let fields = match raw_fields {
+            [self_arg, .. rest] => {
+                do self_arg.mapi |i, &(opt_id, field)| {
+                    let other_fields = do rest.map |l| {
+                        match &l[i] {
+                            &(_, ex) => ex
+                        }
+                    };
+                    (opt_id, field, other_fields)
+                }
+            }
+            [] => { cx.span_bug(span, ~"No self arguments to non-static \
+                                        method in generic `deriving`") }
+        };
 
-        ```
-        match *`to_match` {
-            (`to_match`_1, ..., `to_match`_`num_fields`) => `match_body`
-        }
-        ```
-        */
-        fn create_deref_match(cx: @ext_ctxt,
-                              span: span,
-                              type_path: @ast::Path,
-                              to_match: ~str,
-                              num_fields: uint,
-                              match_body: @expr) -> @expr {
-            let match_subpats = create_subpatterns(cx, span, to_match, num_fields);
+        // body of the inner most destructuring match
+        let mut body = self.call_substructure_method(
+            cx, span,
+            type_ident,
+            self_args,
+            nonself_args,
+            &Struct(fields));
+
+        // make a series of nested matches, to destructure the
+        // structs. This is actually right-to-left, but it shoudn't
+        // matter.
+        for vec::each2(self_args, patterns) |&arg_expr, &pat| {
             let match_arm = ast::arm {
-                pats: ~[ build::mk_pat_enum(cx, span, type_path, match_subpats) ],
+                pats: ~[ pat ],
                 guard: None,
-                body: build::mk_simple_block(cx, span, match_body),
+                body: build::mk_simple_block(cx, span, body)
             };
 
-            let deref_expr = build::mk_unary(cx, span, deref,
-                                             build::mk_path(cx, span,
-                                                            ~[ cx.ident_of(to_match)]));
-            let match_expr = build::mk_expr(cx, span, expr_match(deref_expr, ~[match_arm]));
-
-            match_expr
+            body = build::mk_expr(cx, span, ast::expr_match(arg_expr, ~[match_arm]))
         }
+        body
     }
 
-    /**
-    ```
-    #[deriving(Eq)]
-    struct A { x: int, y: int }
-
-    // equivalent to:
-
-    impl Eq for A {
-        fn eq(&self, __other_1: &A) -> bool {
-            self.x.eq(&__other_1.x) &&
-                self.y.eq(&__other_1.y)
-        }
-    }
-    ```
-    */
-    fn expand_struct_method_body(&self,
-                                     cx: @ext_ctxt,
-                                     span: span,
-                                     struct_def: &struct_def,
-                                     type_ident: ident)
+    fn expand_static_struct_method_body(&self,
+                                        cx: @ext_ctxt,
+                                        span: span,
+                                        struct_def: &struct_def,
+                                        type_ident: ident,
+                                        self_args: &[@expr],
+                                        nonself_args: &[@expr])
         -> @expr {
-        let self_ident = cx.ident_of(~"self");
-        let other_idents = create_other_idents(cx, self.nargs);
-
-        let fields = do struct_def.fields.map |struct_field| {
-            match struct_field.node.kind {
-                named_field(ident, _, _) => {
-                    // Create the accessor for this field in the other args.
-                    let other_fields = do other_idents.map |&id| {
-                        build::mk_access(cx, span, ~[id], ident)
-                    };
-                    let other_field_refs = do other_fields.map |&other_field| {
-                        build::mk_addr_of(cx, span, other_field)
-                    };
-
-                    // Create the accessor for this field in self.
-                    let self_field =
-                        build::mk_access(
-                            cx, span,
-                            ~[ self_ident ],
-                            ident);
+        let summary = summarise_struct(cx, span, struct_def);
 
-                    (Some(ident), self_field, other_field_refs)
-                }
-                unnamed_field => {
-                    cx.span_unimpl(span, ~"unnamed fields with `deriving_generic`");
-                }
-            }
-        };
-
-        self.call_substructure_method(cx, span, type_ident, &Struct(fields))
+        self.call_substructure_method(cx, span,
+                                      type_ident,
+                                      self_args, nonself_args,
+                                      &StaticStruct(struct_def, summary))
     }
 
     /**
-    ```
+    ~~~
     #[deriving(Eq)]
     enum A {
         A1
         A2(int)
     }
 
-    // is equivalent to
+    // is equivalent to (with const_nonmatching == false)
 
     impl Eq for A {
-        fn eq(&self, __other_1: &A) {
+        fn eq(&self, __arg_1: &A) {
             match *self {
-                A1 => match *__other_1 {
-                    A1 => true,
-                    A2(ref __other_1_1) => false
+                A1 => match *__arg_1 {
+                    A1 => true
+                    A2(ref __arg_1_1) => false
                 },
-                A2(self_1) => match *__other_1 {
+                A2(self_1) => match *__arg_1 {
                     A1 => false,
-                    A2(ref __other_1_1) => self_1.eq(__other_1_1)
+                    A2(ref __arg_1_1) => self_1.eq(__arg_1_1)
                 }
             }
         }
     }
-    ```
+    ~~~
     */
     fn expand_enum_method_body(&self,
                                cx: @ext_ctxt,
                                span: span,
                                enum_def: &enum_def,
-                               type_ident: ident)
+                               type_ident: ident,
+                               self_args: &[@expr],
+                               nonself_args: &[@expr])
         -> @expr {
         self.build_enum_match(cx, span, enum_def, type_ident,
+                              self_args, nonself_args,
                               None, ~[], 0)
     }
 
@@ -567,13 +625,13 @@ impl<'self> MethodDef<'self> {
     /**
     Creates the nested matches for an enum definition recursively, i.e.
 
-    ```
+    ~~~
     match self {
        Variant1 => match other { Variant1 => matching, Variant2 => nonmatching, ... },
        Variant2 => match other { Variant1 => nonmatching, Variant2 => matching, ... },
        ...
     }
-    ```
+    ~~~
 
     It acts in the most naive way, so every branch (and subbranch,
     subsubbranch, etc) exists, not just the ones where all the variants in
@@ -589,15 +647,17 @@ impl<'self> MethodDef<'self> {
                         cx: @ext_ctxt, span: span,
                         enum_def: &enum_def,
                         type_ident: ident,
+                        self_args: &[@expr],
+                        nonself_args: &[@expr],
                         matching: Option<uint>,
-                        matches_so_far: ~[(uint, variant,
+                        matches_so_far: ~[(uint, ast::variant,
                                            ~[(Option<ident>, @expr)])],
                         match_count: uint) -> @expr {
-        if match_count == self.nargs + 1 {
+        if match_count == self_args.len() {
             // we've matched against all arguments, so make the final
             // expression at the bottom of the match tree
             match matches_so_far {
-                [] => cx.bug(~"no self match on an enum in `deriving_generic`"),
+                [] => cx.span_bug(span, ~"no self match on an enum in generic `deriving`"),
                 _ => {
                     // we currently have a vec of vecs, where each
                     // subvec is the fields of one of the arguments,
@@ -637,16 +697,17 @@ impl<'self> MethodDef<'self> {
                             substructure = EnumNonMatching(matches_so_far);
                         }
                     }
-                    self.call_substructure_method(cx, span, type_ident, &substructure)
+                    self.call_substructure_method(cx, span, type_ident,
+                                                  self_args, nonself_args,
+                                                  &substructure)
                 }
             }
 
         } else {  // there are still matches to create
-            let (current_match_ident, current_match_str) = if match_count == 0 {
-                (cx.ident_of(~"self"), ~"__self")
+            let current_match_str = if match_count == 0 {
+                ~"__self"
             } else {
-                let s = fmt!("__other_%u", matches_so_far.len() - 1);
-                (cx.ident_of(s), s)
+                fmt!("__arg_%u", match_count)
             };
 
             let mut arms = ~[];
@@ -654,80 +715,50 @@ impl<'self> MethodDef<'self> {
             // this is used as a stack
             let mut matches_so_far = matches_so_far;
 
-            macro_rules! mk_arm(
-                ($pat:expr, $expr:expr) => {
-                    {
-                        let blk = build::mk_simple_block(cx, span, $expr);
-                        let arm = ast::arm {
-                            pats: ~[$ pat ],
-                            guard: None,
-                            body: blk
-                        };
-                        arm
-                    }
-                }
-            )
-
             // the code for nonmatching variants only matters when
             // we've seen at least one other variant already
             if self.const_nonmatching && match_count > 0 {
                 // make a matching-variant match, and a _ match.
                 let index = match matching {
                     Some(i) => i,
-                    None => cx.span_bug(span, ~"Non-matching variants when required to\
-                                                be matching in `deriving_generic`")
+                    None => cx.span_bug(span, ~"Non-matching variants when required to \
+                                                be matching in generic `deriving`")
                 };
 
                 // matching-variant match
                 let variant = &enum_def.variants[index];
-                let pattern = create_enum_variant_pattern(cx, span,
-                                                          variant,
-                                                          current_match_str);
-
-                let idents = do vec::build |push| {
-                    for each_variant_arg_ident(cx, span, variant) |i, field_id| {
-                        let id = cx.ident_of(fmt!("%s_%u", current_match_str, i));
-                        push((field_id, build::mk_path(cx, span, ~[ id ])));
-                    }
-                };
+                let (pattern, idents) = create_enum_variant_pattern(cx, span,
+                                                                    variant,
+                                                                    current_match_str,
+                                                                    ast::m_imm);
 
                 matches_so_far.push((index, *variant, idents));
                 let arm_expr = self.build_enum_match(cx, span,
                                                      enum_def,
                                                      type_ident,
+                                                     self_args, nonself_args,
                                                      matching,
                                                      matches_so_far,
                                                      match_count + 1);
                 matches_so_far.pop();
-                let arm = mk_arm!(pattern, arm_expr);
-                arms.push(arm);
+                arms.push(build::mk_arm(cx, span, ~[ pattern ], arm_expr));
 
                 if enum_def.variants.len() > 1 {
-                    // _ match, if necessary
-                    let wild_pat = @ast::pat {
-                        id: cx.next_id(),
-                        node: pat_wild,
-                        span: span
-                    };
-
                     let wild_expr = self.call_substructure_method(cx, span, type_ident,
+                                                                  self_args, nonself_args,
                                                                   &EnumNonMatching(~[]));
-                    let wild_arm = mk_arm!(wild_pat, wild_expr);
+                    let wild_arm = build::mk_arm(cx, span,
+                                                 ~[ build::mk_pat_wild(cx, span) ],
+                                                 wild_expr);
                     arms.push(wild_arm);
                 }
             } else {
                 // create an arm matching on each variant
                 for enum_def.variants.eachi |index, variant| {
-                    let pattern = create_enum_variant_pattern(cx, span,
-                                                              variant,
-                                                              current_match_str);
-
-                    let idents = do vec::build |push| {
-                        for each_variant_arg_ident(cx, span, variant) |i, field_id| {
-                            let id = cx.ident_of(fmt!("%s_%u", current_match_str, i));
-                            push((field_id, build::mk_path(cx, span, ~[ id ])));
-                        }
-                    };
+                    let (pattern, idents) = create_enum_variant_pattern(cx, span,
+                                                                       variant,
+                                                                       current_match_str,
+                                                                       ast::m_imm);
 
                     matches_so_far.push((index, *variant, idents));
                     let new_matching =
@@ -739,44 +770,71 @@ impl<'self> MethodDef<'self> {
                     let arm_expr = self.build_enum_match(cx, span,
                                                          enum_def,
                                                          type_ident,
+                                                         self_args, nonself_args,
                                                          new_matching,
                                                          matches_so_far,
                                                          match_count + 1);
                     matches_so_far.pop();
 
-                    let arm = mk_arm!(pattern, arm_expr);
+                    let arm = build::mk_arm(cx, span, ~[ pattern ], arm_expr);
                     arms.push(arm);
                 }
             }
-            let deref_expr = build::mk_unary(cx, span, deref,
-                                             build::mk_path(cx, span,
-                                                            ~[ current_match_ident ]));
-            let match_expr = build::mk_expr(cx, span,
-                                            expr_match(deref_expr, arms));
 
-            match_expr
+            // match foo { arm, arm, arm, ... }
+            build::mk_expr(cx, span,
+                           ast::expr_match(self_args[match_count], arms))
         }
     }
+
+    fn expand_static_enum_method_body(&self,
+                               cx: @ext_ctxt,
+                               span: span,
+                               enum_def: &enum_def,
+                               type_ident: ident,
+                               self_args: &[@expr],
+                               nonself_args: &[@expr])
+        -> @expr {
+        let summary = do enum_def.variants.map |v| {
+            let ident = v.node.name;
+            let summary = match v.node.kind {
+                ast::tuple_variant_kind(ref args) => Left(args.len()),
+                ast::struct_variant_kind(struct_def) => {
+                    summarise_struct(cx, span, struct_def)
+                }
+            };
+            (ident, summary)
+        };
+        self.call_substructure_method(cx,
+                                      span, type_ident,
+                                      self_args, nonself_args,
+                                      &StaticEnum(enum_def, summary))
+    }
 }
 
-/// Create variable names (as strings) to refer to the non-self
-/// parameters
-fn create_other_strs(n: uint) -> ~[~str] {
-    do vec::build |push| {
-        for uint::range(0, n) |i| {
-            push(fmt!("__other_%u", i));
+fn summarise_struct(cx: @ext_ctxt, span: span,
+                    struct_def: &struct_def) -> Either<uint, ~[ident]> {
+    let mut named_idents = ~[];
+    let mut unnamed_count = 0;
+    for struct_def.fields.each |field| {
+        match field.node.kind {
+            ast::named_field(ident, _) => named_idents.push(ident),
+            ast::unnamed_field => unnamed_count += 1,
         }
     }
-}
-/// Like `create_other_strs`, but returns idents for the strings
-fn create_other_idents(cx: @ext_ctxt, n: uint) -> ~[ident] {
-    do create_other_strs(n).map |&s| {
-        cx.ident_of(s)
+
+    match (unnamed_count > 0, named_idents.is_empty()) {
+        (true, false) => cx.span_bug(span,
+                                     "A struct with named and unnamed \
+                                      fields in generic `deriving`"),
+        // named fields
+        (_, false) => Right(named_idents),
+        // tuple structs (includes empty structs)
+        (_, _)     => Left(unnamed_count)
     }
 }
 
 
-
 /* helpful premade recipes */
 
 /**
@@ -786,7 +844,7 @@ left-to-right (`true`) or right-to-left (`false`).
 pub fn cs_fold(use_foldl: bool,
                f: &fn(@ext_ctxt, span,
                       old: @expr,
-                      self_f: @expr, other_fs: ~[@expr]) -> @expr,
+                      self_f: @expr, other_fs: &[@expr]) -> @expr,
                base: @expr,
                enum_nonmatch_f: EnumNonMatchFunc,
                cx: @ext_ctxt, span: span,
@@ -803,7 +861,11 @@ pub fn cs_fold(use_foldl: bool,
                 }
             }
         },
-        EnumNonMatching(all_enums) => enum_nonmatch_f(cx, span, all_enums)
+        EnumNonMatching(all_enums) => enum_nonmatch_f(cx, span,
+                                                      all_enums, substructure.nonself_args),
+        StaticEnum(*) | StaticStruct(*) => {
+            cx.span_bug(span, "Static function in `deriving`")
+        }
     }
 }
 
@@ -812,11 +874,12 @@ pub fn cs_fold(use_foldl: bool,
 Call the method that is being derived on all the fields, and then
 process the collected results. i.e.
 
-```
-f(cx, span, ~[self_1.method(__other_1_1, __other_2_1),
-              self_2.method(__other_1_2, __other_2_2)])
-```
+~~~
+f(cx, span, ~[self_1.method(__arg_1_1, __arg_2_1),
+              self_2.method(__arg_1_2, __arg_2_2)])
+~~~
 */
+#[inline(always)]
 pub fn cs_same_method(f: &fn(@ext_ctxt, span, ~[@expr]) -> @expr,
                       enum_nonmatch_f: EnumNonMatchFunc,
                       cx: @ext_ctxt, span: span,
@@ -833,7 +896,11 @@ pub fn cs_same_method(f: &fn(@ext_ctxt, span, ~[@expr]) -> @expr,
 
             f(cx, span, called)
         },
-        EnumNonMatching(all_enums) => enum_nonmatch_f(cx, span, all_enums)
+        EnumNonMatching(all_enums) => enum_nonmatch_f(cx, span,
+                                                      all_enums, substructure.nonself_args),
+        StaticEnum(*) | StaticStruct(*) => {
+            cx.span_bug(span, "Static function in `deriving`")
+        }
     }
 }
 
@@ -842,6 +909,7 @@ Fold together the results of calling the derived method on all the
 fields. `use_foldl` controls whether this is done left-to-right
 (`true`) or right-to-left (`false`).
 */
+#[inline(always)]
 pub fn cs_same_method_fold(use_foldl: bool,
                            f: &fn(@ext_ctxt, span, @expr, @expr) -> @expr,
                            base: @expr,
@@ -869,7 +937,8 @@ pub fn cs_same_method_fold(use_foldl: bool,
 Use a given binop to combine the result of calling the derived method
 on all the fields.
 */
-pub fn cs_binop(binop: binop, base: @expr,
+#[inline(always)]
+pub fn cs_binop(binop: ast::binop, base: @expr,
                 enum_nonmatch_f: EnumNonMatchFunc,
                 cx: @ext_ctxt, span: span,
                 substructure: &Substructure) -> @expr {
@@ -887,18 +956,20 @@ pub fn cs_binop(binop: binop, base: @expr,
 }
 
 /// cs_binop with binop == or
+#[inline(always)]
 pub fn cs_or(enum_nonmatch_f: EnumNonMatchFunc,
              cx: @ext_ctxt, span: span,
              substructure: &Substructure) -> @expr {
-    cs_binop(or, build::mk_bool(cx, span, false),
+    cs_binop(ast::or, build::mk_bool(cx, span, false),
              enum_nonmatch_f,
              cx, span, substructure)
 }
 /// cs_binop with binop == and
+#[inline(always)]
 pub fn cs_and(enum_nonmatch_f: EnumNonMatchFunc,
               cx: @ext_ctxt, span: span,
               substructure: &Substructure) -> @expr {
-    cs_binop(and, build::mk_bool(cx, span, true),
+    cs_binop(ast::and, build::mk_bool(cx, span, true),
              enum_nonmatch_f,
              cx, span, substructure)
 }
diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs
index f03306ea07a..3d66506d6ca 100644
--- a/src/libsyntax/ext/deriving/iter_bytes.rs
+++ b/src/libsyntax/ext/deriving/iter_bytes.rs
@@ -1,4 +1,4 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
 //
@@ -8,25 +8,37 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use ast;
-use ast::*;
+use ast::{meta_item, item, expr};
+use codemap::span;
 use ext::base::ext_ctxt;
 use ext::build;
-use ext::deriving::*;
-use codemap::{span, spanned};
-use ast_util;
-use opt_vec;
+use ext::deriving::generic::*;
 
 pub fn expand_deriving_iter_bytes(cx: @ext_ctxt,
                                   span: span,
-                                  _mitem: @meta_item,
-                                  in_items: ~[@item])
-                               -> ~[@item] {
-    expand_deriving(cx,
-                    span,
-                    in_items,
-                    expand_deriving_iter_bytes_struct_def,
-                    expand_deriving_iter_bytes_enum_def)
+                                  mitem: @meta_item,
+                                  in_items: ~[@item]) -> ~[@item] {
+    let trait_def = TraitDef {
+        path: Path::new(~[~"core", ~"to_bytes", ~"IterBytes"]),
+        additional_bounds: ~[],
+        generics: LifetimeBounds::empty(),
+        methods: ~[
+            MethodDef {
+                name: ~"iter_bytes",
+                generics: LifetimeBounds::empty(),
+                self_ty: borrowed_explicit_self(),
+                args: ~[
+                    Literal(Path::new(~[~"bool"])),
+                    Literal(Path::new(~[~"core", ~"to_bytes", ~"Cb"]))
+                ],
+                ret_ty: nil_ty(),
+                const_nonmatching: false,
+                combine_substructure: iter_bytes_substructure
+            }
+        ]
+    };
+
+    expand_deriving_generic(cx, span, mitem, in_items, &trait_def)
 }
 
 pub fn expand_deriving_obsolete(cx: @ext_ctxt,
@@ -39,217 +51,43 @@ pub fn expand_deriving_obsolete(cx: @ext_ctxt,
     in_items
 }
 
-fn create_derived_iter_bytes_impl(cx: @ext_ctxt,
-                                  span: span,
-                                  type_ident: ident,
-                                  generics: &Generics,
-                                  method: @method)
-                               -> @item {
-    let methods = [ method ];
-    let trait_path = ~[
-        cx.ident_of(~"core"),
-        cx.ident_of(~"to_bytes"),
-        cx.ident_of(~"IterBytes")
-    ];
-    let trait_path = build::mk_raw_path_global(span, trait_path);
-    create_derived_impl(cx, span, type_ident, generics, methods, trait_path,
-                        opt_vec::Empty, opt_vec::Empty)
-}
-
-// Creates a method from the given set of statements conforming to the
-// signature of the `iter_bytes` method.
-fn create_iter_bytes_method(cx: @ext_ctxt,
-                            span: span,
-                            statements: ~[@stmt])
-                         -> @method {
-    // Create the `lsb0` parameter.
-    let bool_ident = cx.ident_of(~"bool");
-    let lsb0_arg_type = build::mk_simple_ty_path(cx, span, bool_ident);
-    let lsb0_ident = cx.ident_of(~"__lsb0");
-    let lsb0_arg = build::mk_arg(cx, span, lsb0_ident, lsb0_arg_type);
-
-    // Create the `f` parameter.
-    let core_ident = cx.ident_of(~"core");
-    let to_bytes_ident = cx.ident_of(~"to_bytes");
-    let cb_ident = cx.ident_of(~"Cb");
-    let core_to_bytes_cb_ident = ~[ core_ident, to_bytes_ident, cb_ident ];
-    let f_arg_type = build::mk_ty_path(cx, span, core_to_bytes_cb_ident);
-    let f_ident = cx.ident_of(~"__f");
-    let f_arg = build::mk_arg(cx, span, f_ident, f_arg_type);
-
-    // Create the type of the return value.
-    let output_type = @ast::Ty { id: cx.next_id(), node: ty_nil, span: span };
-
-    // Create the function declaration.
-    let inputs = ~[ lsb0_arg, f_arg ];
-    let fn_decl = build::mk_fn_decl(inputs, output_type);
-
-    // Create the body block.
-    let body_block = build::mk_block_(cx, span, statements);
-
-    // Create the method.
-    let self_ty = spanned { node: sty_region(None, m_imm), span: span };
-    let method_ident = cx.ident_of(~"iter_bytes");
-    @ast::method {
-        ident: method_ident,
-        attrs: ~[],
-        generics: ast_util::empty_generics(),
-        self_ty: self_ty,
-        purity: impure_fn,
-        decl: fn_decl,
-        body: body_block,
-        id: cx.next_id(),
-        span: span,
-        self_id: cx.next_id(),
-        vis: public
-    }
-}
-
-fn call_substructure_iter_bytes_method(cx: @ext_ctxt,
-                                       span: span,
-                                       self_field: @expr)
-                                    -> @stmt {
-    // Gather up the parameters we want to chain along.
-    let lsb0_ident = cx.ident_of(~"__lsb0");
-    let f_ident = cx.ident_of(~"__f");
-    let lsb0_expr = build::mk_path(cx, span, ~[ lsb0_ident ]);
-    let f_expr = build::mk_path(cx, span, ~[ f_ident ]);
-
-    // Call the substructure method.
-    let iter_bytes_ident = cx.ident_of(~"iter_bytes");
-    let self_call = build::mk_method_call(cx,
-                                          span,
-                                          self_field,
-                                          iter_bytes_ident,
-                                          ~[ lsb0_expr, f_expr ]);
-
-    // Create a statement out of this expression.
-    build::mk_stmt(cx, span, self_call)
-}
-
-fn expand_deriving_iter_bytes_struct_def(cx: @ext_ctxt,
-                                         span: span,
-                                         struct_def: &struct_def,
-                                         type_ident: ident,
-                                         generics: &Generics)
-                                      -> @item {
-    // Create the method.
-    let method = expand_deriving_iter_bytes_struct_method(cx,
-                                                          span,
-                                                          struct_def);
-
-    // Create the implementation.
-    return create_derived_iter_bytes_impl(cx,
-                                          span,
-                                          type_ident,
-                                          generics,
-                                          method);
-}
-
-fn expand_deriving_iter_bytes_enum_def(cx: @ext_ctxt,
-                                       span: span,
-                                       enum_definition: &enum_def,
-                                       type_ident: ident,
-                                       generics: &Generics)
-                                    -> @item {
-    // Create the method.
-    let method = expand_deriving_iter_bytes_enum_method(cx,
-                                                        span,
-                                                        enum_definition);
-
-    // Create the implementation.
-    return create_derived_iter_bytes_impl(cx,
-                                          span,
-                                          type_ident,
-                                          generics,
-                                          method);
-}
-
-fn expand_deriving_iter_bytes_struct_method(cx: @ext_ctxt,
-                                            span: span,
-                                            struct_def: &struct_def)
-                                         -> @method {
-    let self_ident = cx.ident_of(~"self");
-
-    // Create the body of the method.
-    let mut statements = ~[];
-    for struct_def.fields.each |struct_field| {
-        match struct_field.node.kind {
-            named_field(ident, _, _) => {
-                // Create the accessor for this field.
-                let self_field = build::mk_access(cx,
-                                                  span,
-                                                  ~[ self_ident ],
-                                                  ident);
-
-                // Call the substructure method.
-                let stmt = call_substructure_iter_bytes_method(cx,
-                                                               span,
-                                                               self_field);
-                statements.push(stmt);
-            }
-            unnamed_field => {
-                cx.span_unimpl(span,
-                               ~"unnamed fields with `deriving(IterBytes)`");
-            }
-        }
-    }
-
-    // Create the method itself.
-    return create_iter_bytes_method(cx, span, statements);
-}
-
-fn expand_deriving_iter_bytes_enum_method(cx: @ext_ctxt,
-                                          span: span,
-                                          enum_definition: &enum_def)
-                                       -> @method {
-    // Create the arms of the match in the method body.
-    let arms = do enum_definition.variants.mapi |i, variant| {
-        // Create the matching pattern.
-        let pat = create_enum_variant_pattern(cx, span, variant, ~"__self");
-
-        // Determine the discriminant. We will feed this value to the byte
-        // iteration function.
-        let discriminant;
-        match variant.node.disr_expr {
-            Some(copy disr_expr) => discriminant = disr_expr,
-            None => discriminant = build::mk_uint(cx, span, i),
-        }
-
-        // Feed the discriminant to the byte iteration function.
-        let mut stmts = ~[];
-        let discrim_stmt = call_substructure_iter_bytes_method(cx,
-                                                               span,
-                                                               discriminant);
-        stmts.push(discrim_stmt);
-
-        // Feed each argument in this variant to the byte iteration function
-        // as well.
-        for uint::range(0, variant_arg_count(cx, span, variant)) |j| {
-            // Create the expression for this field.
-            let field_ident = cx.ident_of(~"__self_" + j.to_str());
-            let field = build::mk_path(cx, span, ~[ field_ident ]);
-
-            // Call the substructure method.
-            let stmt = call_substructure_iter_bytes_method(cx, span, field);
-            stmts.push(stmt);
+fn iter_bytes_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
+    let lsb0_f = match substr.nonself_args {
+        [l, f] => ~[l, f],
+        _ => cx.span_bug(span, "Incorrect number of arguments in `deriving(IterBytes)`")
+    };
+    let iter_bytes_ident = substr.method_ident;
+    let call_iterbytes = |thing_expr| {
+        build::mk_stmt(
+            cx, span,
+            build::mk_method_call(cx, span,
+                                  thing_expr, iter_bytes_ident,
+                                  copy lsb0_f))
+    };
+    let mut stmts = ~[];
+    let fields;
+    match *substr.fields {
+        Struct(ref fs) => {
+            fields = fs
         }
+        EnumMatching(copy index, ref variant, ref fs) => {
+            // Determine the discriminant. We will feed this value to the byte
+            // iteration function.
+            let discriminant = match variant.node.disr_expr {
+                Some(copy d)=> d,
+                None => build::mk_uint(cx, span, index)
+            };
 
-        // Create the pattern body.
-        let match_body_block = build::mk_block_(cx, span, stmts);
+            stmts.push(call_iterbytes(discriminant));
 
-        // Create the arm.
-        ast::arm {
-            pats: ~[ pat ],
-            guard: None,
-            body: match_body_block,
+            fields = fs;
         }
-    };
+        _ => cx.span_bug(span, "Impossible substructure in `deriving(IterBytes)`")
+    }
 
-    // Create the method body.
-    let self_match_expr = expand_enum_or_struct_match(cx, span, arms);
-    let self_match_stmt = build::mk_stmt(cx, span, self_match_expr);
+    for fields.each |&(_, field, _)| {
+        stmts.push(call_iterbytes(field));
+    }
 
-    // Create the method.
-    create_iter_bytes_method(cx, span, ~[ self_match_stmt ])
+    build::mk_block(cx, span, ~[], stmts, None)
 }
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index 5aeeef2b17a..2bd45e1466c 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -12,14 +12,7 @@
 /// #[deriving(IterBytes)] extensions.
 
 use ast;
-use ast::{Ty, bind_by_ref, deref, enum_def};
-use ast::{expr, expr_match, ident, item, item_};
-use ast::{item_enum, item_impl, item_struct, Generics};
-use ast::{m_imm, meta_item, method};
-use ast::{named_field, pat, pat_ident, public};
-use ast::{struct_def, struct_variant_kind};
-use ast::{tuple_variant_kind};
-use ast::{ty_path, unnamed_field, variant};
+use ast::{Ty, enum_def, expr, ident, item, Generics, meta_item, struct_def};
 use ext::base::ext_ctxt;
 use ext::build;
 use codemap::{span, respan};
@@ -30,6 +23,8 @@ pub mod clone;
 pub mod iter_bytes;
 pub mod encodable;
 pub mod decodable;
+pub mod rand;
+pub mod to_str;
 
 #[path="cmp/eq.rs"]
 pub mod eq;
@@ -78,23 +73,25 @@ pub fn expand_meta_deriving(cx: @ext_ctxt,
                     meta_name_value(tname, _) |
                     meta_list(tname, _) |
                     meta_word(tname) => {
+                        macro_rules! expand(($func:path) => ($func(cx, titem.span,
+                                                                   titem, in_items)));
                         match *tname {
-                            ~"Clone" => clone::expand_deriving_clone(cx,
-                                titem.span, titem, in_items),
-                            ~"IterBytes" => iter_bytes::expand_deriving_iter_bytes(cx,
-                                titem.span, titem, in_items),
-                            ~"Encodable" => encodable::expand_deriving_encodable(cx,
-                                titem.span, titem, in_items),
-                            ~"Decodable" => decodable::expand_deriving_decodable(cx,
-                                titem.span, titem, in_items),
-                            ~"Eq" => eq::expand_deriving_eq(cx, titem.span,
-                                                             titem, in_items),
-                            ~"TotalEq" => totaleq::expand_deriving_totaleq(cx, titem.span,
-                                                                           titem, in_items),
-                            ~"Ord" => ord::expand_deriving_ord(cx, titem.span,
-                                                               titem, in_items),
-                            ~"TotalOrd" => totalord::expand_deriving_totalord(cx, titem.span,
-                                                                              titem, in_items),
+                            ~"Clone" => expand!(clone::expand_deriving_clone),
+
+                            ~"IterBytes" => expand!(iter_bytes::expand_deriving_iter_bytes),
+
+                            ~"Encodable" => expand!(encodable::expand_deriving_encodable),
+                            ~"Decodable" => expand!(decodable::expand_deriving_decodable),
+
+                            ~"Eq" => expand!(eq::expand_deriving_eq),
+                            ~"TotalEq" => expand!(totaleq::expand_deriving_totaleq),
+                            ~"Ord" => expand!(ord::expand_deriving_ord),
+                            ~"TotalOrd" => expand!(totalord::expand_deriving_totalord),
+
+                            ~"Rand" => expand!(rand::expand_deriving_rand),
+
+                            ~"ToStr" => expand!(to_str::expand_deriving_to_str),
+
                             tname => {
                                 cx.span_err(titem.span, fmt!("unknown \
                                     `deriving` trait: `%s`", tname));
@@ -118,14 +115,14 @@ pub fn expand_deriving(cx: @ext_ctxt,
     for in_items.each |item| {
         result.push(copy *item);
         match item.node {
-            item_struct(struct_def, ref generics) => {
+            ast::item_struct(struct_def, ref generics) => {
                 result.push(expand_deriving_struct_def(cx,
                                                        span,
                                                        struct_def,
                                                        item.ident,
                                                        generics));
             }
-            item_enum(ref enum_definition, ref generics) => {
+            ast::item_enum(ref enum_definition, ref generics) => {
                 result.push(expand_deriving_enum_def(cx,
                                                      span,
                                                      enum_definition,
@@ -138,7 +135,7 @@ pub fn expand_deriving(cx: @ext_ctxt,
     result
 }
 
-fn create_impl_item(cx: @ext_ctxt, span: span, item: item_) -> @item {
+fn create_impl_item(cx: @ext_ctxt, span: span, item: ast::item_) -> @item {
     let doc_attr = respan(span,
                           ast::lit_str(@~"Automatically derived."));
     let doc_attr = respan(span, ast::meta_name_value(@~"doc", doc_attr));
@@ -154,7 +151,7 @@ fn create_impl_item(cx: @ext_ctxt, span: span, item: item_) -> @item {
         attrs: ~[doc_attr],
         id: cx.next_id(),
         node: item,
-        vis: public,
+        vis: ast::public,
         span: span,
     }
 }
@@ -173,22 +170,29 @@ pub fn create_self_type_with_params(cx: @ext_ctxt,
         self_ty_params.push(self_ty_param);
     }
 
+    let lifetime = if generics.lifetimes.is_empty() {
+        None
+    } else {
+        Some(@*generics.lifetimes.get(0))
+    };
+
+
     // Create the type of `self`.
     let self_type = build::mk_raw_path_(span,
                                         ~[ type_ident ],
+                                        lifetime,
                                         self_ty_params);
-    let self_type = ty_path(self_type, cx.next_id());
-    @ast::Ty { id: cx.next_id(), node: self_type, span: span }
+    build::mk_ty_path_path(cx, span, self_type)
 }
 
 pub fn create_derived_impl(cx: @ext_ctxt,
                            span: span,
                            type_ident: ident,
                            generics: &Generics,
-                           methods: &[@method],
+                           methods: &[@ast::method],
                            trait_path: @ast::Path,
-                           mut impl_ty_params: opt_vec::OptVec<ast::TyParam>,
-                           bounds_paths: opt_vec::OptVec<~[ident]>)
+                           mut impl_generics:  Generics,
+                           bounds_paths: opt_vec::OptVec<@ast::Path>)
                         -> @item {
     /*!
      *
@@ -204,21 +208,22 @@ pub fn create_derived_impl(cx: @ext_ctxt,
      */
 
     // Copy the lifetimes
-    let impl_lifetimes = generics.lifetimes.map(|l| {
-        build::mk_lifetime(cx, l.span, l.ident)
-    });
+    for generics.lifetimes.each |l| {
+        impl_generics.lifetimes.push(copy *l)
+    };
 
     // Create the type parameters.
     for generics.ty_params.each |ty_param| {
+        // extra restrictions on the generics parameters to the type being derived upon
         let mut bounds = do bounds_paths.map |&bound_path| {
-            build::mk_trait_ty_param_bound_global(cx, span, bound_path)
+            build::mk_trait_ty_param_bound_(cx, bound_path)
         };
 
         let this_trait_bound =
             build::mk_trait_ty_param_bound_(cx, trait_path);
         bounds.push(this_trait_bound);
 
-        impl_ty_params.push(build::mk_ty_param(cx, ty_param.ident, @bounds));
+        impl_generics.ty_params.push(build::mk_ty_param(cx, ty_param.ident, @bounds));
     }
 
     // Create the reference to the trait.
@@ -231,8 +236,7 @@ pub fn create_derived_impl(cx: @ext_ctxt,
                                                  generics);
 
     // Create the impl item.
-    let impl_item = item_impl(Generics {lifetimes: impl_lifetimes,
-                                        ty_params: impl_ty_params},
+    let impl_item = ast::item_impl(impl_generics,
                               Some(trait_ref),
                               self_type,
                               methods.map(|x| *x));
@@ -240,106 +244,128 @@ pub fn create_derived_impl(cx: @ext_ctxt,
 }
 
 pub fn create_subpatterns(cx: @ext_ctxt,
-                      span: span,
-                      prefix: ~str,
-                      n: uint)
-                   -> ~[@pat] {
-    let mut subpats = ~[];
-    for uint::range(0, n) |_i| {
-        // Create the subidentifier.
-        let index = subpats.len();
-        let ident = cx.ident_of(fmt!("%s_%u", prefix, index));
-
-        // Create the subpattern.
-        let subpath = build::mk_raw_path(span, ~[ ident ]);
-        let subpat = pat_ident(bind_by_ref(m_imm), subpath, None);
-        let subpat = build::mk_pat(cx, span, subpat);
-        subpats.push(subpat);
+                          span: span,
+                          field_paths: ~[@ast::Path],
+                          mutbl: ast::mutability)
+                   -> ~[@ast::pat] {
+    do field_paths.map |&path| {
+        build::mk_pat(cx, span,
+                      ast::pat_ident(ast::bind_by_ref(mutbl), path, None))
     }
-    return subpats;
 }
 
-pub fn is_struct_tuple(struct_def: &struct_def) -> bool {
-    struct_def.fields.len() > 0 && struct_def.fields.all(|f| {
-        match f.node.kind {
-            named_field(*) => false,
-            unnamed_field => true
-        }
-    })
+#[deriving(Eq)] // dogfooding!
+enum StructType {
+    Unknown, Record, Tuple
+}
+
+pub fn create_struct_pattern(cx: @ext_ctxt,
+                             span: span,
+                             struct_ident: ident,
+                             struct_def: &struct_def,
+                             prefix: ~str,
+                             mutbl: ast::mutability)
+    -> (@ast::pat, ~[(Option<ident>, @expr)]) {
+    if struct_def.fields.is_empty() {
+        return (
+            build::mk_pat_ident_with_binding_mode(
+                cx, span, struct_ident, ast::bind_infer),
+            ~[]);
+    }
+
+    let matching_path = build::mk_raw_path(span, ~[ struct_ident ]);
+
+    let mut paths = ~[], ident_expr = ~[];
+
+    let mut struct_type = Unknown;
+
+    for struct_def.fields.eachi |i, struct_field| {
+        let opt_id = match struct_field.node.kind {
+            ast::named_field(ident, _) if (struct_type == Unknown ||
+                                           struct_type == Record) => {
+                struct_type = Record;
+                Some(ident)
+            }
+            ast::unnamed_field if (struct_type == Unknown ||
+                                   struct_type == Tuple) => {
+                struct_type = Tuple;
+                None
+            }
+            _ => {
+                cx.span_bug(span, "A struct with named and unnamed fields in `deriving`");
+            }
+        };
+        let path = build::mk_raw_path(span,
+                                      ~[ cx.ident_of(fmt!("%s_%u", prefix, i)) ]);
+        paths.push(path);
+        ident_expr.push((opt_id, build::mk_path_raw(cx, span, path)));
+    }
+
+    let subpats = create_subpatterns(cx, span, paths, mutbl);
+
+    // struct_type is definitely not Unknown, since struct_def.fields
+    // must be nonempty to reach here
+    let pattern = if struct_type == Record {
+        let field_pats = do vec::build |push| {
+            for vec::each2(subpats, ident_expr) |&pat, &(id, _)| {
+                // id is guaranteed to be Some
+                push(ast::field_pat { ident: id.get(), pat: pat })
+            }
+        };
+        build::mk_pat_struct(cx, span, matching_path, field_pats)
+    } else {
+        build::mk_pat_enum(cx, span, matching_path, subpats)
+    };
+
+    (pattern, ident_expr)
 }
 
 pub fn create_enum_variant_pattern(cx: @ext_ctxt,
-                               span: span,
-                               variant: &variant,
-                               prefix: ~str)
-                            -> @pat {
+                                   span: span,
+                                   variant: &ast::variant,
+                                   prefix: ~str,
+                                   mutbl: ast::mutability)
+    -> (@ast::pat, ~[(Option<ident>, @expr)]) {
+
     let variant_ident = variant.node.name;
     match variant.node.kind {
-        tuple_variant_kind(ref variant_args) => {
-            if variant_args.len() == 0 {
-                return build::mk_pat_ident_with_binding_mode(
-                    cx, span, variant_ident, ast::bind_infer);
+        ast::tuple_variant_kind(ref variant_args) => {
+            if variant_args.is_empty() {
+                return (build::mk_pat_ident_with_binding_mode(
+                    cx, span, variant_ident, ast::bind_infer), ~[]);
             }
 
             let matching_path = build::mk_raw_path(span, ~[ variant_ident ]);
-            let subpats = create_subpatterns(cx,
-                                             span,
-                                             prefix,
-                                             variant_args.len());
 
-            return build::mk_pat_enum(cx, span, matching_path, subpats);
-        }
-        struct_variant_kind(struct_def) => {
-            let matching_path = build::mk_raw_path(span, ~[ variant_ident ]);
-            let subpats = create_subpatterns(cx,
-                                             span,
-                                             prefix,
-                                             struct_def.fields.len());
-
-            let field_pats = do struct_def.fields.mapi |i, struct_field| {
-                let ident = match struct_field.node.kind {
-                    named_field(ident, _, _) => ident,
-                    unnamed_field => {
-                        cx.span_bug(span, ~"unexpected unnamed field");
-                    }
-                };
-                ast::field_pat { ident: ident, pat: subpats[i] }
-            };
+            let mut paths = ~[], ident_expr = ~[];
+            for uint::range(0, variant_args.len()) |i| {
+                let path = build::mk_raw_path(span,
+                                              ~[ cx.ident_of(fmt!("%s_%u", prefix, i)) ]);
 
-            build::mk_pat_struct(cx, span, matching_path, field_pats)
-        }
-    }
-}
+                paths.push(path);
+                ident_expr.push((None, build::mk_path_raw(cx, span, path)));
+            }
 
-pub fn variant_arg_count(_cx: @ext_ctxt, _span: span, variant: &variant) -> uint {
-    match variant.node.kind {
-        tuple_variant_kind(ref args) => args.len(),
-        struct_variant_kind(ref struct_def) => struct_def.fields.len(),
-    }
-}
+            let subpats = create_subpatterns(cx, span, paths, mutbl);
 
-/// Iterate through the idents of the variant arguments. The field is
-/// unnamed (i.e. it's not a struct-like enum), then `None`.
-pub fn each_variant_arg_ident(_cx: @ext_ctxt, _span: span,
-                              variant: &variant, it: &fn(uint, Option<ident>) -> bool) {
-    match variant.node.kind {
-        tuple_variant_kind(ref args) => {
-            for uint::range(0, args.len()) |i| {
-                if !it(i, None) { break }
-            }
+            (build::mk_pat_enum(cx, span, matching_path, subpats),
+             ident_expr)
         }
-        struct_variant_kind(ref struct_def) => {
-            for struct_def.fields.eachi |i, f| {
-                let id = match f.node.kind {
-                    named_field(ident, _, _) => Some(ident),
-                    unnamed_field => None
-                };
-                if !it(i, id) { break }
-            }
+        ast::struct_variant_kind(struct_def) => {
+            create_struct_pattern(cx, span,
+                                  variant_ident, struct_def,
+                                  prefix,
+                                  mutbl)
         }
     }
 }
 
+pub fn variant_arg_count(_cx: @ext_ctxt, _span: span, variant: &ast::variant) -> uint {
+    match variant.node.kind {
+        ast::tuple_variant_kind(ref args) => args.len(),
+        ast::struct_variant_kind(ref struct_def) => struct_def.fields.len(),
+    }
+}
 
 pub fn expand_enum_or_struct_match(cx: @ext_ctxt,
                                span: span,
@@ -347,7 +373,7 @@ pub fn expand_enum_or_struct_match(cx: @ext_ctxt,
                             -> @expr {
     let self_ident = cx.ident_of(~"self");
     let self_expr = build::mk_path(cx, span, ~[ self_ident ]);
-    let self_expr = build::mk_unary(cx, span, deref, self_expr);
-    let self_match_expr = expr_match(self_expr, arms);
+    let self_expr = build::mk_unary(cx, span, ast::deref, self_expr);
+    let self_match_expr = ast::expr_match(self_expr, arms);
     build::mk_expr(cx, span, self_match_expr)
 }
diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs
new file mode 100644
index 00000000000..604686f442f
--- /dev/null
+++ b/src/libsyntax/ext/deriving/rand.rs
@@ -0,0 +1,141 @@
+// Copyright 2012-2013 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.
+
+use ast;
+use ast::{meta_item, item, expr, ident};
+use codemap::span;
+use ext::base::ext_ctxt;
+use ext::build;
+use ext::deriving::generic::*;
+
+pub fn expand_deriving_rand(cx: @ext_ctxt,
+                            span: span,
+                            mitem: @meta_item,
+                            in_items: ~[@item])
+    -> ~[@item] {
+    let trait_def = TraitDef {
+        path: Path::new(~[~"core", ~"rand", ~"Rand"]),
+        additional_bounds: ~[],
+        generics: LifetimeBounds::empty(),
+        methods: ~[
+            MethodDef {
+                name: ~"rand",
+                generics: LifetimeBounds {
+                    lifetimes: ~[],
+                    bounds: ~[(~"R",
+                               ~[ Path::new(~[~"core", ~"rand", ~"Rng"]) ])]
+                },
+                self_ty: None,
+                args: ~[
+                    Ptr(~Literal(Path::new_local(~"R")),
+                        Borrowed(None, ast::m_mutbl))
+                ],
+                ret_ty: Self,
+                const_nonmatching: false,
+                combine_substructure: rand_substructure
+            }
+        ]
+    };
+
+    expand_deriving_generic(cx, span, mitem, in_items, &trait_def)
+}
+
+fn rand_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
+    let rng = match substr.nonself_args {
+        [rng] => ~[ rng ],
+        _ => cx.bug("Incorrect number of arguments to `rand` in `deriving(Rand)`")
+    };
+    let rand_ident = ~[
+        cx.ident_of(~"core"),
+        cx.ident_of(~"rand"),
+        cx.ident_of(~"Rand"),
+        cx.ident_of(~"rand")
+    ];
+    let rand_call = || {
+        build::mk_call_global(cx,
+                              span,
+                              copy rand_ident,
+                              ~[ build::duplicate_expr(cx, rng[0]) ])
+    };
+
+    return match *substr.fields {
+        StaticStruct(_, ref summary) => {
+            rand_thing(cx, span, substr.type_ident, summary, rand_call)
+        }
+        StaticEnum(_, ref variants) => {
+            if variants.is_empty() {
+                cx.span_fatal(span, "`Rand` cannot be derived for enums with no variants");
+            }
+
+            let variant_count = build::mk_uint(cx, span, variants.len());
+
+            // need to specify the uint-ness of the random number
+            let u32_ty = build::mk_ty_path(cx, span, ~[cx.ident_of(~"uint")]);
+            let r_ty = build::mk_ty_path(cx, span, ~[cx.ident_of(~"R")]);
+            let rand_name = build::mk_raw_path_(span, copy rand_ident, None, ~[ u32_ty, r_ty ]);
+            let rand_name = build::mk_path_raw(cx, span, rand_name);
+
+            let rv_call = build::mk_call_(cx,
+                                          span,
+                                          rand_name,
+                                          ~[ build::duplicate_expr(cx, rng[0]) ]);
+
+            // rand() % variants.len()
+            let rand_variant = build::mk_binary(cx, span, ast::rem,
+                                                rv_call, variant_count);
+
+            let mut arms = do variants.mapi |i, id_sum| {
+                let i_expr = build::mk_uint(cx, span, i);
+                let pat = build::mk_pat_lit(cx, span, i_expr);
+
+                match *id_sum {
+                    (ident, ref summary) => {
+                        build::mk_arm(cx, span,
+                                      ~[ pat ],
+                                      rand_thing(cx, span, ident, summary, rand_call))
+                    }
+                }
+            };
+
+            // _ => {} at the end. Should never occur
+            arms.push(build::mk_unreachable_arm(cx, span));
+
+            build::mk_expr(cx, span,
+                           ast::expr_match(rand_variant, arms))
+        }
+        _ => cx.bug("Non-static method in `deriving(Rand)`")
+    };
+
+    fn rand_thing(cx: @ext_ctxt, span: span,
+                  ctor_ident: ident,
+                  summary: &Either<uint, ~[ident]>,
+                  rand_call: &fn() -> @expr) -> @expr {
+        let ctor_ident = ~[ ctor_ident ];
+        match *summary {
+            Left(copy count) => {
+                if count == 0 {
+                    build::mk_path(cx, span, ctor_ident)
+                } else {
+                    let exprs = vec::from_fn(count, |_| rand_call());
+                    build::mk_call(cx, span, ctor_ident, exprs)
+                }
+            }
+            Right(ref fields) => {
+                let rand_fields = do fields.map |ident| {
+                    build::Field {
+                        ident: *ident,
+                        ex: rand_call()
+                    }
+                };
+                build::mk_struct_e(cx, span, ctor_ident, rand_fields)
+            }
+        }
+    }
+}
diff --git a/src/libsyntax/ext/deriving/to_str.rs b/src/libsyntax/ext/deriving/to_str.rs
new file mode 100644
index 00000000000..2c7d449585f
--- /dev/null
+++ b/src/libsyntax/ext/deriving/to_str.rs
@@ -0,0 +1,54 @@
+// Copyright 2012-2013 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.
+
+use ast::{meta_item, item, expr};
+use codemap::span;
+use ext::base::ext_ctxt;
+use ext::build;
+use ext::deriving::generic::*;
+
+pub fn expand_deriving_to_str(cx: @ext_ctxt,
+                              span: span,
+                              mitem: @meta_item,
+                              in_items: ~[@item])
+    -> ~[@item] {
+    let trait_def = TraitDef {
+        path: Path::new(~[~"core", ~"to_str", ~"ToStr"]),
+        additional_bounds: ~[],
+        generics: LifetimeBounds::empty(),
+        methods: ~[
+            MethodDef {
+                name: ~"to_str",
+                generics: LifetimeBounds::empty(),
+                self_ty: borrowed_explicit_self(),
+                args: ~[],
+                ret_ty: Ptr(~Literal(Path::new_local(~"str")), Owned),
+                const_nonmatching: false,
+                combine_substructure: to_str_substructure
+            }
+        ]
+    };
+
+    expand_deriving_generic(cx, span, mitem, in_items, &trait_def)
+}
+
+fn to_str_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) -> @expr {
+    match substr.self_args {
+        [self_obj] => {
+            let self_addr = build::mk_addr_of(cx, span, self_obj);
+            build::mk_call_global(cx, span,
+                                  ~[cx.ident_of(~"core"),
+                                    cx.ident_of(~"sys"),
+                                    cx.ident_of(~"log_str")],
+                                  ~[self_addr])
+        }
+        _ => cx.span_bug(span, ~"Invalid number of arguments in `deriving(ToStr)`")
+    }
+}
\ No newline at end of file
diff --git a/src/libsyntax/ext/deriving/ty.rs b/src/libsyntax/ext/deriving/ty.rs
new file mode 100644
index 00000000000..6195a3a6424
--- /dev/null
+++ b/src/libsyntax/ext/deriving/ty.rs
@@ -0,0 +1,242 @@
+// Copyright 2013 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 mini version of ast::Ty, which is easier to use, and features an
+explicit `Self` type to use when specifying impls to be derived.
+*/
+
+use ast;
+use ast::{expr,Generics,ident};
+use ext::base::ext_ctxt;
+use ext::build;
+use codemap::{span,respan};
+use opt_vec;
+
+/// The types of pointers
+#[deriving(Eq)]
+pub enum PtrTy {
+    Owned, // ~
+    Managed(ast::mutability), // @[mut]
+    Borrowed(Option<~str>, ast::mutability), // &['lifetime] [mut]
+}
+
+/// A path, e.g. `::core::option::Option::<int>` (global). Has support
+/// for type parameters and a lifetime.
+#[deriving(Eq)]
+pub struct Path {
+    path: ~[~str],
+    lifetime: Option<~str>,
+    params: ~[~Ty],
+    global: bool
+}
+
+pub impl Path {
+    fn new(path: ~[~str]) -> Path {
+        Path::new_(path, None, ~[], true)
+    }
+    fn new_local(path: ~str) -> Path {
+        Path::new_(~[ path ], None, ~[], false)
+    }
+    fn new_(path: ~[~str], lifetime: Option<~str>, params: ~[~Ty], global: bool) -> Path {
+        Path {
+            path: path,
+            lifetime: lifetime,
+            params: params,
+            global: global
+        }
+    }
+
+    fn to_ty(&self, cx: @ext_ctxt, span: span,
+             self_ty: ident, self_generics: &Generics) -> @ast::Ty {
+                build::mk_ty_path_path(cx, span,
+                                       self.to_path(cx, span,
+                                                    self_ty, self_generics))
+    }
+    fn to_path(&self, cx: @ext_ctxt, span: span,
+               self_ty: ident, self_generics: &Generics) -> @ast::Path {
+        let idents = self.path.map(|s| cx.ident_of(*s) );
+        let lt = mk_lifetime(cx, span, self.lifetime);
+        let tys = self.params.map(|t| t.to_ty(cx, span, self_ty, self_generics));
+
+        if self.global {
+            build::mk_raw_path_global_(span, idents, lt, tys)
+        } else {
+            build::mk_raw_path_(span, idents, lt, tys)
+        }
+    }
+}
+
+/// A type. Supports pointers (except for *), Self, and literals
+#[deriving(Eq)]
+pub enum Ty {
+    Self,
+    // &/~/@ Ty
+    Ptr(~Ty, PtrTy),
+    // mod::mod::Type<[lifetime], [Params...]>, including a plain type
+    // parameter, and things like `int`
+    Literal(Path),
+    // includes nil
+    Tuple(~[Ty])
+}
+
+pub fn borrowed_ptrty() -> PtrTy {
+    Borrowed(None, ast::m_imm)
+}
+pub fn borrowed(ty: ~Ty) -> Ty {
+    Ptr(ty, borrowed_ptrty())
+}
+
+pub fn borrowed_explicit_self() -> Option<Option<PtrTy>> {
+    Some(Some(borrowed_ptrty()))
+}
+
+pub fn borrowed_self() -> Ty {
+    borrowed(~Self)
+}
+
+pub fn nil_ty() -> Ty {
+    Tuple(~[])
+}
+
+fn mk_lifetime(cx: @ext_ctxt, span: span, lt: Option<~str>) -> Option<@ast::Lifetime> {
+    match lt {
+        Some(s) => Some(@build::mk_lifetime(cx, span, cx.ident_of(s))),
+        None => None
+    }
+}
+
+pub impl Ty {
+    fn to_ty(&self, cx: @ext_ctxt, span: span,
+             self_ty: ident, self_generics: &Generics) -> @ast::Ty {
+        match *self {
+            Ptr(ref ty, ref ptr) => {
+                let raw_ty = ty.to_ty(cx, span, self_ty, self_generics);
+                match *ptr {
+                    Owned => {
+                        build::mk_ty_uniq(cx, span, raw_ty)
+                    }
+                    Managed(copy mutbl) => {
+                        build::mk_ty_box(cx, span, raw_ty, mutbl)
+                    }
+                    Borrowed(copy lt, copy mutbl) => {
+                        let lt = mk_lifetime(cx, span, lt);
+                        build::mk_ty_rptr(cx, span, raw_ty, lt, mutbl)
+                    }
+                }
+            }
+            Literal(ref p) => { p.to_ty(cx, span, self_ty, self_generics) }
+            Self  => {
+                build::mk_ty_path_path(cx, span, self.to_path(cx, span, self_ty, self_generics))
+            }
+            Tuple(ref fields) => {
+                let ty = if fields.is_empty() {
+                    ast::ty_nil
+                } else {
+                    ast::ty_tup(fields.map(|f| f.to_ty(cx, span, self_ty, self_generics)))
+                };
+
+                build::mk_ty(cx, span, ty)
+            }
+        }
+    }
+
+    fn to_path(&self, cx: @ext_ctxt, span: span,
+               self_ty: ident, self_generics: &Generics) -> @ast::Path {
+        match *self {
+            Self => {
+                let self_params = do self_generics.ty_params.map |ty_param| {
+                    build::mk_ty_path(cx, span, ~[ ty_param.ident ])
+                };
+                let lifetime = if self_generics.lifetimes.is_empty() {
+                    None
+                } else {
+                    Some(@*self_generics.lifetimes.get(0))
+                };
+
+                build::mk_raw_path_(span, ~[self_ty], lifetime,
+                                    opt_vec::take_vec(self_params))
+            }
+            Literal(ref p) => {
+                p.to_path(cx, span, self_ty, self_generics)
+            }
+            Ptr(*) => { cx.span_bug(span, ~"Pointer in a path in generic `deriving`") }
+            Tuple(*) => { cx.span_bug(span, ~"Tuple in a path in generic `deriving`") }
+        }
+    }
+}
+
+
+fn mk_ty_param(cx: @ext_ctxt, span: span, name: ~str, bounds: ~[Path],
+               self_ident: ident, self_generics: &Generics) -> ast::TyParam {
+    let bounds = opt_vec::from(
+        do bounds.map |b| {
+            let path = b.to_path(cx, span, self_ident, self_generics);
+            build::mk_trait_ty_param_bound_(cx, path)
+        });
+    build::mk_ty_param(cx, cx.ident_of(name), @bounds)
+}
+
+fn mk_generics(lifetimes: ~[ast::Lifetime],  ty_params: ~[ast::TyParam]) -> Generics {
+    Generics {
+        lifetimes: opt_vec::from(lifetimes),
+        ty_params: opt_vec::from(ty_params)
+    }
+}
+
+/// Lifetimes and bounds on type paramers
+pub struct LifetimeBounds {
+    lifetimes: ~[~str],
+    bounds: ~[(~str, ~[Path])]
+}
+
+pub impl LifetimeBounds {
+    fn empty() -> LifetimeBounds {
+        LifetimeBounds {
+            lifetimes: ~[], bounds: ~[]
+        }
+    }
+    fn to_generics(&self, cx: @ext_ctxt, span: span,
+                   self_ty: ident, self_generics: &Generics) -> Generics {
+        let lifetimes = do self.lifetimes.map |&lt| {
+            build::mk_lifetime(cx, span, cx.ident_of(lt))
+        };
+        let ty_params = do self.bounds.map |&(name, bounds)| {
+            mk_ty_param(cx, span, name, bounds, self_ty, self_generics)
+        };
+        mk_generics(lifetimes, ty_params)
+    }
+}
+
+
+pub fn get_explicit_self(cx: @ext_ctxt, span: span, self_ptr: Option<PtrTy>)
+    -> (@expr, ast::self_ty) {
+    let self_path = build::mk_path(cx, span, ~[cx.ident_of(~"self")]);
+    match self_ptr {
+        None => {
+            (self_path, respan(span, ast::sty_value))
+        }
+        Some(ptr) => {
+            let self_ty = respan(
+                span,
+                match ptr {
+                    Owned => ast::sty_uniq(ast::m_imm),
+                    Managed(mutbl) => ast::sty_box(mutbl),
+                    Borrowed(lt, mutbl) => {
+                        let lt = lt.map(|s| @build::mk_lifetime(cx, span,
+                                                                cx.ident_of(*s)));
+                        ast::sty_region(lt, mutbl)
+                    }
+                });
+            let self_expr = build::mk_deref(cx, span, self_path);
+            (self_expr, self_ty)
+        }
+    }
+}
diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs
index e876972fe68..7ac3ea4789d 100644
--- a/src/libsyntax/ext/pipes/pipec.rs
+++ b/src/libsyntax/ext/pipes/pipec.rs
@@ -64,6 +64,7 @@ impl gen_send for message {
 
             let mut body = ~"{\n";
             body += fmt!("use super::%s;\n", name);
+            body += ~"let mut pipe = pipe;\n";
 
             if this.proto.is_bounded() {
                 let (sp, rp) = match (this.dir, next.dir) {
@@ -73,12 +74,12 @@ impl gen_send for message {
                   (recv, recv) => (~"c", ~"s")
                 };
 
-                body += ~"let b = pipe.reuse_buffer();\n";
+                body += ~"let mut b = pipe.reuse_buffer();\n";
                 body += fmt!("let %s = ::core::pipes::SendPacketBuffered(\
-                              &(b.buffer.data.%s));\n",
+                              &mut (b.buffer.data.%s));\n",
                              sp, next.name);
                 body += fmt!("let %s = ::core::pipes::RecvPacketBuffered(\
-                              &(b.buffer.data.%s));\n",
+                              &mut (b.buffer.data.%s));\n",
                              rp, next.name);
             }
             else {
@@ -366,7 +367,7 @@ impl gen_init for protocol {
                         fmt!("data.%s.set_buffer(buffer)",
                              s.name))),
                 ext_cx.parse_expr(fmt!(
-                    "::core::ptr::to_unsafe_ptr(&(data.%s))",
+                    "::core::ptr::to_mut_unsafe_ptr(&mut (data.%s))",
                     self.states[0].name))));
 
         quote_expr!({
@@ -410,10 +411,8 @@ impl gen_init for protocol {
 
             @spanned {
                 node: ast::struct_field_ {
-                    kind: ast::named_field(
-                            cx.ident_of(s.name),
-                            ast::struct_immutable,
-                            ast::inherited),
+                    kind: ast::named_field(cx.ident_of(s.name),
+                                           ast::inherited),
                     id: cx.next_id(),
                     ty: fty,
                     attrs: ~[],
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 229a8664d0c..d181dd87e38 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -859,3 +859,4 @@ impl AstFoldExtensions for @ast_fold {
 pub fn make_fold(afp: ast_fold_fns) -> @ast_fold {
     afp as @ast_fold
 }
+
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 810efd39177..0543295eb4e 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -45,7 +45,7 @@ use ast::{pat_tup, pat_uniq, pat_wild, private};
 use ast::{rem, required};
 use ast::{ret_style, return_val, self_ty, shl, shr, stmt, stmt_decl};
 use ast::{stmt_expr, stmt_semi, stmt_mac, struct_def, struct_field};
-use ast::{struct_immutable, struct_mutable, struct_variant_kind, subtract};
+use ast::{struct_variant_kind, subtract};
 use ast::{sty_box, sty_region, sty_static, sty_uniq, sty_value};
 use ast::{token_tree, trait_method, trait_ref, tt_delim, tt_seq, tt_tok};
 use ast::{tt_nonterminal, tuple_variant_kind, Ty, ty_, ty_bot, ty_box};
@@ -390,8 +390,8 @@ pub impl Parser {
     // parse a ty_closure type
     fn parse_ty_closure(&self,
                         sigil: ast::Sigil,
-                        region: Option<@ast::Lifetime>) -> ty_
-    {
+                        region: Option<@ast::Lifetime>)
+                        -> ty_ {
         /*
 
         (&|~|@) ['r] [pure|unsafe] [once] fn <'lt> (S) -> T
@@ -773,20 +773,17 @@ pub impl Parser {
         return ty_rptr(opt_lifetime, mt);
     }
 
-    // parse an optional mode.
-    // XXX: Remove after snapshot.
+    // parse an optional, obsolete argument mode.
     fn parse_arg_mode(&self) {
         if self.eat(&token::BINOP(token::MINUS)) {
             self.obsolete(*self.span, ObsoleteMode);
         } else if self.eat(&token::ANDAND) {
-            // Ignore.
+            self.obsolete(*self.span, ObsoleteMode);
         } else if self.eat(&token::BINOP(token::PLUS)) {
             if self.eat(&token::BINOP(token::PLUS)) {
-                // ++ mode is obsolete, but we need a snapshot
-                // to stop parsing it.
-                // Ignore.
+                self.obsolete(*self.span, ObsoleteMode);
             } else {
-                // Ignore.
+                self.obsolete(*self.span, ObsoleteMode);
             }
         } else {
             // Ignore.
@@ -2528,10 +2525,10 @@ pub impl Parser {
     fn parse_name_and_ty(&self,
                          pr: visibility,
                          attrs: ~[attribute]) -> @struct_field {
-        let mut is_mutbl = struct_immutable;
         let lo = self.span.lo;
         if self.eat_keyword(&~"mut") {
-            is_mutbl = struct_mutable;
+            // Do nothing, for backwards compatibility.
+            // XXX: Remove after snapshot.
         }
         if !is_plain_ident(&*self.token) {
             self.fatal(~"expected ident");
@@ -2540,7 +2537,7 @@ pub impl Parser {
         self.expect(&token::COLON);
         let ty = self.parse_ty(false);
         @spanned(lo, self.last_span.hi, ast::struct_field_ {
-            kind: named_field(name, is_mutbl, pr),
+            kind: named_field(name, pr),
             id: self.get_id(),
             ty: ty,
             attrs: attrs,
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 6f3d6604d5b..f12fb21992e 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -703,14 +703,11 @@ pub fn print_struct(s: @ps,
         for struct_def.fields.each |field| {
             match field.node.kind {
                 ast::unnamed_field => fail!(~"unexpected unnamed field"),
-                ast::named_field(ident, mutability, visibility) => {
+                ast::named_field(ident, visibility) => {
                     hardbreak_if_not_bol(s);
                     maybe_print_comment(s, field.span.lo);
                     print_outer_attributes(s, field.node.attrs);
                     print_visibility(s, visibility);
-                    if mutability == ast::struct_mutable {
-                        word_nbsp(s, ~"mut");
-                    }
                     print_ident(s, ident);
                     word_nbsp(s, ~":");
                     print_type(s, field.node.ty);
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs
index e3a87277622..23084c34209 100644
--- a/src/libsyntax/util/interner.rs
+++ b/src/libsyntax/util/interner.rs
@@ -84,7 +84,7 @@ pub impl<T:Eq + IterBytes + Hash + Const + Copy> Interner<T> {
 * for another case of this. */
 macro_rules! interner_key (
     () => (cast::transmute::<(uint, uint),
-           &fn(+v: @@::parse::token::ident_interner)>(
+           &fn(v: @@::parse::token::ident_interner)>(
         (-3 as uint, 0u)))
 )
 
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index 885b40c0a50..90328928122 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -829,13 +829,6 @@ rust_get_rt_env() {
     return task->kernel->env;
 }
 
-typedef void *(*nullary_fn)();
-
-extern "C" CDECL void
-rust_call_nullary_fn(nullary_fn f) {
-    f();
-}
-
 #ifndef _WIN32
 pthread_key_t sched_key;
 #else
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index 1c3f6370ded..6be41251f1b 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -222,7 +222,6 @@ rust_uv_ip4_addrp
 rust_uv_ip6_addrp
 rust_uv_free_ip4_addr
 rust_uv_free_ip6_addr
-rust_call_nullary_fn
 rust_initialize_global_state
 rust_dbg_next_port
 rust_new_memory_region
diff --git a/src/test/auxiliary/cci_class_6.rs b/src/test/auxiliary/cci_class_6.rs
index b09606ea1e2..7ad617cebdb 100644
--- a/src/test/auxiliary/cci_class_6.rs
+++ b/src/test/auxiliary/cci_class_6.rs
@@ -23,7 +23,7 @@ pub mod kitties {
         fn meow_count(&mut self) -> uint { self.meows }
     }
 
-    pub fn cat<U>(in_x : uint, in_y : int, +in_info: ~[U]) -> cat<U> {
+    pub fn cat<U>(in_x : uint, in_y : int, in_info: ~[U]) -> cat<U> {
         cat {
             meows: in_x,
             how_hungry: in_y,
diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs
index e216215ace7..cb494ec9d20 100644
--- a/src/test/bench/core-map.rs
+++ b/src/test/bench/core-map.rs
@@ -103,7 +103,7 @@ fn main() {
     let mut rand = vec::with_capacity(n_keys);
 
     {
-        let rng = core::rand::IsaacRng::new_seeded([1, 1, 1, 1, 1, 1, 1]);
+        let mut rng = core::rand::IsaacRng::new_seeded([1, 1, 1, 1, 1, 1, 1]);
         let mut set = HashSet::new();
         while set.len() != n_keys {
             let next = rng.next() as uint;
diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs
index b3e3d295c0f..bae21c6d4a3 100644
--- a/src/test/bench/core-set.rs
+++ b/src/test/bench/core-set.rs
@@ -31,8 +31,13 @@ fn timed(result: &mut float, op: &fn()) {
 }
 
 pub impl Results {
-    fn bench_int<T:Set<uint>, R: rand::Rng>(&mut self, rng: &R, num_keys: uint,
-                               rand_cap: uint, f: &fn() -> T) {
+    fn bench_int<T:Set<uint>,
+                 R: rand::Rng>(
+                 &mut self,
+                 rng: &mut R,
+                 num_keys: uint,
+                 rand_cap: uint,
+                 f: &fn() -> T) {
         {
             let mut set = f();
             do timed(&mut self.sequential_ints) {
@@ -69,8 +74,12 @@ pub impl Results {
         }
     }
 
-    fn bench_str<T:Set<~str>, R: rand::Rng>(&mut self, rng: &R, num_keys: uint,
-                                            f: &fn() -> T) {
+    fn bench_str<T:Set<~str>,
+                 R:rand::Rng>(
+                 &mut self,
+                 rng: &mut R,
+                 num_keys: uint,
+                 f: &fn() -> T) {
         {
             let mut set = f();
             do timed(&mut self.sequential_strings) {
@@ -155,25 +164,25 @@ fn main() {
     let max = 200000;
 
     {
-        let rng = rand::IsaacRng::new_seeded(seed);
+        let mut rng = rand::IsaacRng::new_seeded(seed);
         let mut results = empty_results();
-        results.bench_int(&rng, num_keys, max, || HashSet::new::<uint>());
-        results.bench_str(&rng, num_keys, || HashSet::new::<~str>());
+        results.bench_int(&mut rng, num_keys, max, || HashSet::new::<uint>());
+        results.bench_str(&mut rng, num_keys, || HashSet::new::<~str>());
         write_results("core::hashmap::HashSet", &results);
     }
 
     {
-        let rng = rand::IsaacRng::new_seeded(seed);
+        let mut rng = rand::IsaacRng::new_seeded(seed);
         let mut results = empty_results();
-        results.bench_int(&rng, num_keys, max, || TreeSet::new::<uint>());
-        results.bench_str(&rng, num_keys, || TreeSet::new::<~str>());
+        results.bench_int(&mut rng, num_keys, max, || TreeSet::new::<uint>());
+        results.bench_str(&mut rng, num_keys, || TreeSet::new::<~str>());
         write_results("std::treemap::TreeSet", &results);
     }
 
     {
-        let rng = rand::IsaacRng::new_seeded(seed);
+        let mut rng = rand::IsaacRng::new_seeded(seed);
         let mut results = empty_results();
-        results.bench_int(&rng, num_keys, max, || BitvSet::new());
+        results.bench_int(&mut rng, num_keys, max, || BitvSet::new());
         write_results("std::bitv::BitvSet", &results);
     }
 }
diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs
index 1af3538a021..95a83af93d5 100644
--- a/src/test/bench/core-std.rs
+++ b/src/test/bench/core-std.rs
@@ -33,12 +33,15 @@ fn main() {
 fn maybe_run_test(argv: &[~str], name: ~str, test: &fn()) {
     let mut run_test = false;
 
-    if os::getenv(~"RUST_BENCH").is_some() { run_test = true }
-    else if argv.len() > 0 {
+    if os::getenv(~"RUST_BENCH").is_some() {
+        run_test = true
+    } else if argv.len() > 0 {
         run_test = argv.contains(&~"all") || argv.contains(&name)
     }
 
-    if !run_test { return }
+    if !run_test {
+        return
+    }
 
     let start = precise_time_s();
     test();
@@ -69,7 +72,7 @@ fn read_line() {
 }
 
 fn vec_plus() {
-    let r = rand::rng();
+    let mut r = rand::rng();
 
     let mut v = ~[];
     let mut i = 0;
@@ -86,7 +89,7 @@ fn vec_plus() {
 }
 
 fn vec_append() {
-    let r = rand::rng();
+    let mut r = rand::rng();
 
     let mut v = ~[];
     let mut i = 0;
@@ -103,7 +106,7 @@ fn vec_append() {
 }
 
 fn vec_push_all() {
-    let r = rand::rng();
+    let mut r = rand::rng();
 
     let mut v = ~[];
     for uint::range(0, 1500) |i| {
diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs
index c8555ab1286..1842a8ff42e 100644
--- a/src/test/bench/graph500-bfs.rs
+++ b/src/test/bench/graph500-bfs.rs
@@ -32,19 +32,20 @@ type graph = ~[~[node_id]];
 type bfs_result = ~[node_id];
 
 fn make_edges(scale: uint, edgefactor: uint) -> ~[(node_id, node_id)] {
-    let r = rand::XorShiftRng::new();
-
-    fn choose_edge<R: rand::Rng>(i: node_id, j: node_id, scale: uint, r: &R)
-        -> (node_id, node_id) {
+    let mut r = rand::XorShiftRng::new();
 
+    fn choose_edge<R: rand::Rng>(i: node_id,
+                                 j: node_id,
+                                 scale: uint,
+                                 r: &mut R)
+                                 -> (node_id, node_id) {
         let A = 0.57;
         let B = 0.19;
         let C = 0.19;
 
         if scale == 0u {
             (i, j)
-        }
-        else {
+        } else {
             let i = i * 2i64;
             let j = j * 2i64;
             let scale = scale - 1u;
@@ -73,7 +74,7 @@ fn make_edges(scale: uint, edgefactor: uint) -> ~[(node_id, node_id)] {
     }
 
     do vec::from_fn((1u << scale) * edgefactor) |_i| {
-        choose_edge(0i64, 0i64, scale, &r)
+        choose_edge(0i64, 0i64, scale, &mut r)
     }
 }
 
@@ -103,7 +104,7 @@ fn make_graph(N: uint, edges: ~[(node_id, node_id)]) -> graph {
 
 fn gen_search_keys(graph: &[~[node_id]], n: uint) -> ~[node_id] {
     let mut keys = HashSet::new();
-    let r = rand::rng();
+    let mut r = rand::rng();
 
     while keys.len() < n {
         let k = r.gen_uint_range(0u, graph.len());
@@ -272,7 +273,7 @@ fn pbfs(graph: &arc::ARC<graph>, key: node_id) -> bfs_result {
         colors = do par::mapi(*color_vec) {
             let colors = arc::clone(&color);
             let graph = arc::clone(graph);
-            let result: ~fn(+x: uint, +y: &color) -> color = |i, c| {
+            let result: ~fn(x: uint, y: &color) -> color = |i, c| {
                 let colors = arc::get(&colors);
                 let graph = arc::get(&graph);
                 match *c {
@@ -394,7 +395,7 @@ fn validate(edges: ~[(node_id, node_id)],
 
     let status = do par::alli(tree) {
         let edges = copy edges;
-        let result: ~fn(+x: uint, v: &i64) -> bool = |u, v| {
+        let result: ~fn(x: uint, v: &i64) -> bool = |u, v| {
             let u = u as node_id;
             if *v == -1i64 || u == root {
                 true
diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs
index 6cda0a1945a..95758b3fe64 100644
--- a/src/test/bench/msgsend-pipes-shared.rs
+++ b/src/test/bench/msgsend-pipes-shared.rs
@@ -65,15 +65,15 @@ fn run(args: &[~str]) {
     let mut worker_results = ~[];
     for uint::range(0, workers) |_i| {
         let to_child = to_child.clone();
-        do task::task().future_result(|+r| {
-            worker_results.push(r);
-        }).spawn || {
+        let mut builder = task::task();
+        builder.future_result(|r| worker_results.push(r));
+        do builder.spawn {
             for uint::range(0, size / workers) |_i| {
                 //error!("worker %?: sending %? bytes", i, num_bytes);
                 to_child.send(bytes(num_bytes));
             }
             //error!("worker %? exiting", i);
-        };
+        }
     }
     do task::spawn || {
         server(&from_parent, &to_parent);
diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs
index a8fb29a47e2..e213a44b49a 100644
--- a/src/test/bench/msgsend-pipes.rs
+++ b/src/test/bench/msgsend-pipes.rs
@@ -62,9 +62,9 @@ fn run(args: &[~str]) {
     for uint::range(0, workers) |_i| {
         let (from_parent_, to_child) = stream();
         from_parent.add(from_parent_);
-        do task::task().future_result(|+r| {
-            worker_results.push(r);
-        }).spawn || {
+        let mut builder = task::task();
+        builder.future_result(|r| worker_results.push(r));
+        do builder.spawn {
             for uint::range(0, size / workers) |_i| {
                 //error!("worker %?: sending %? bytes", i, num_bytes);
                 to_child.send(bytes(num_bytes));
diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs
index 853b057277d..2d234634cc8 100644
--- a/src/test/bench/msgsend-ring-mutex-arcs.rs
+++ b/src/test/bench/msgsend-ring-mutex-arcs.rs
@@ -45,10 +45,7 @@ fn init() -> (pipe,pipe) {
 }
 
 
-fn thread_ring(i: uint,
-               count: uint,
-               +num_chan: pipe,
-               +num_port: pipe) {
+fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) {
     let mut num_chan = Some(num_chan);
     let mut num_port = Some(num_port);
     // Send/Receive lots of messages.
@@ -103,7 +100,9 @@ fn main() {
     thread_ring(0, msg_per_task, num_chan.take(), num_port);
 
     // synchronize
-    for futures.each |f| { f.get() };
+    for futures.each_mut |f| {
+        f.get()
+    }
 
     let stop = time::precise_time_s();
 
diff --git a/src/test/bench/msgsend-ring-pipes.rs b/src/test/bench/msgsend-ring-pipes.rs
index 1288ac29078..aef5c18499a 100644
--- a/src/test/bench/msgsend-ring-pipes.rs
+++ b/src/test/bench/msgsend-ring-pipes.rs
@@ -35,8 +35,8 @@ macro_rules! move_out (
 
 fn thread_ring(i: uint,
                count: uint,
-               +num_chan: ring::client::num,
-               +num_port: ring::server::num) {
+               num_chan: ring::client::num,
+               num_port: ring::server::num) {
     let mut num_chan = Some(num_chan);
     let mut num_port = Some(num_port);
     // Send/Receive lots of messages.
@@ -96,7 +96,9 @@ fn main() {
     thread_ring(0, msg_per_task, num_chan.take(), num_port);
 
     // synchronize
-    for futures.each |f| { f.get() };
+    for futures.each_mut |f| {
+        let _ = f.get();
+    }
 
     let stop = time::precise_time_s();
 
diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs
index 2cf0fbfc397..02415c4bcfc 100644
--- a/src/test/bench/msgsend-ring-rw-arcs.rs
+++ b/src/test/bench/msgsend-ring-rw-arcs.rs
@@ -46,10 +46,7 @@ fn init() -> (pipe,pipe) {
 }
 
 
-fn thread_ring(i: uint,
-               count: uint,
-               +num_chan: pipe,
-               +num_port: pipe) {
+fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) {
     let mut num_chan = Some(num_chan);
     let mut num_port = Some(num_port);
     // Send/Receive lots of messages.
@@ -104,7 +101,9 @@ fn main() {
     thread_ring(0, msg_per_task, num_chan.take(), num_port);
 
     // synchronize
-    for futures.each |f| { f.get() };
+    for futures.each_mut |f| {
+        let _ = f.get();
+    }
 
     let stop = time::precise_time_s();
 
diff --git a/src/test/bench/noise.rs b/src/test/bench/noise.rs
index 0da3a2e5d68..992ce73a4bf 100644
--- a/src/test/bench/noise.rs
+++ b/src/test/bench/noise.rs
@@ -13,7 +13,7 @@ fn lerp(a: f32, b: f32, v: f32) -> f32 { a * (1.0 - v) + b * v }
 #[inline(always)]
 fn smooth(v: f32) -> f32 { v * v * (3.0 - 2.0 * v) }
 
-fn random_gradient<R:Rng>(r: &R) -> Vec2 {
+fn random_gradient<R:Rng>(r: &mut R) -> Vec2 {
     let v = 2.0 * float::consts::pi * r.gen();
     Vec2 {
         x: float::cos(v) as f32,
@@ -33,11 +33,15 @@ struct Noise2DContext {
 
 pub impl Noise2DContext {
     fn new() -> Noise2DContext {
-        let r = rand::rng();
+        let mut r = rand::rng();
         let mut rgradients = [ Vec2 { x: 0.0, y: 0.0 }, ..256 ];
-        for int::range(0, 256) |i| { rgradients[i] = random_gradient(&r); }
+        for int::range(0, 256) |i| {
+            rgradients[i] = random_gradient(&mut r);
+        }
         let mut permutations = [ 0, ..256 ];
-        for int::range(0, 256) |i| { permutations[i] = i; }
+        for int::range(0, 256) |i| {
+            permutations[i] = i;
+        }
         r.shuffle_mut(permutations);
 
         Noise2DContext {
@@ -53,7 +57,11 @@ pub impl Noise2DContext {
     }
 
     #[inline]
-    fn get_gradients(&self, gradients: &mut [Vec2, ..4], origins: &mut [Vec2, ..4], x: f32, y: f32) {
+    fn get_gradients(&self,
+                     gradients: &mut [Vec2, ..4],
+                     origins: &mut [Vec2, ..4],
+                     x: f32,
+                     y: f32) {
         let x0f = f32::floor(x);
         let y0f = f32::floor(y);
         let x0 = x0f as int;
diff --git a/src/test/bench/pingpong.rs b/src/test/bench/pingpong.rs
index 09e663325ed..cfad253cfed 100644
--- a/src/test/bench/pingpong.rs
+++ b/src/test/bench/pingpong.rs
@@ -117,8 +117,9 @@ pub fn spawn_service_recv<T:Owned,Tb:Owned>(
     client
 }
 
-fn switch<T:Owned,Tb:Owned,U>(+endp: core::pipes::RecvPacketBuffered<T, Tb>,
-                      f: &fn(+v: Option<T>) -> U) -> U {
+fn switch<T:Owned,Tb:Owned,U>(endp: core::pipes::RecvPacketBuffered<T, Tb>,
+                              f: &fn(v: Option<T>) -> U)
+                              -> U {
     f(core::pipes::try_recv(endp))
 }
 
diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs
index 0fcf8341ac8..7316b68f8bd 100644
--- a/src/test/bench/shootout-fasta.rs
+++ b/src/test/bench/shootout-fasta.rs
@@ -63,7 +63,10 @@ fn make_random_fasta(wr: @io::Writer,
                      genelist: ~[AminoAcids],
                      n: int) {
     wr.write_line(~">" + id + ~" " + desc);
-    let rng = @mut MyRandom {last: rand::rng().next()};
+    let mut rng = rand::rng();
+    let rng = @mut MyRandom {
+        last: rng.next()
+    };
     let mut op: ~str = ~"";
     for uint::range(0u, n as uint) |_i| {
         str::push_char(&mut op, select_random(myrandom_next(rng, 100u32),
diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs
index acb8a6bcbee..b7ae331c8f3 100644
--- a/src/test/bench/shootout-pfib.rs
+++ b/src/test/bench/shootout-pfib.rs
@@ -26,7 +26,6 @@ use core::int::range;
 use core::comm::*;
 use core::io::WriterUtil;
 
-use core::result;
 use core::result::{Ok, Err};
 
 fn fib(n: int) -> int {
@@ -67,7 +66,7 @@ fn parse_opts(argv: ~[~str]) -> Config {
     }
 }
 
-fn stress_task(&&id: int) {
+fn stress_task(id: int) {
     let mut i = 0;
     loop {
         let n = 15;
@@ -80,13 +79,15 @@ fn stress_task(&&id: int) {
 fn stress(num_tasks: int) {
     let mut results = ~[];
     for range(0, num_tasks) |i| {
-        do task::task().future_result(|+r| {
-            results.push(r);
-        }).spawn {
+        let mut builder = task::task();
+        builder.future_result(|r| results.push(r));
+        do builder.spawn {
             stress_task(i);
         }
     }
-    for results.each |r| { r.recv(); }
+    for results.each |r| {
+        r.recv();
+    }
 }
 
 fn main() {
diff --git a/src/test/bench/task-perf-linked-failure.rs b/src/test/bench/task-perf-linked-failure.rs
index 90c9d6b33e4..6015f21be72 100644
--- a/src/test/bench/task-perf-linked-failure.rs
+++ b/src/test/bench/task-perf-linked-failure.rs
@@ -46,9 +46,12 @@ fn grandchild_group(num_tasks: uint) {
     // Master grandchild task exits early.
 }
 
-fn spawn_supervised_blocking(myname: &str, +f: ~fn()) {
+fn spawn_supervised_blocking(myname: &str, f: ~fn()) {
     let mut res = None;
-    task::task().future_result(|+r| res = Some(r)).supervised().spawn(f);
+    let mut builder = task::task();
+    builder.future_result(|r| res = Some(r));
+    builder.supervised();
+    builder.spawn(f);
     error!("%s group waiting", myname);
     let x = res.unwrap().recv();
     assert!(x == task::Success);
diff --git a/src/test/bench/task-perf-spawnalot.rs b/src/test/bench/task-perf-spawnalot.rs
index 8c5bbe257bd..e6da898a034 100644
--- a/src/test/bench/task-perf-spawnalot.rs
+++ b/src/test/bench/task-perf-spawnalot.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f(&&n: uint) {
+fn f(n: uint) {
     let mut i = 0u;
     while i < n {
         task::try(|| g() );
diff --git a/src/test/compile-fail/block-coerce-no.rs b/src/test/compile-fail/block-coerce-no.rs
index bdde5144b04..df9eb9fdda6 100644
--- a/src/test/compile-fail/block-coerce-no.rs
+++ b/src/test/compile-fail/block-coerce-no.rs
@@ -12,9 +12,9 @@
 // other tycons.
 
 fn coerce(b: &fn()) -> extern fn() {
-    fn lol(+f: extern fn(+v: &fn()) -> extern fn(),
-           +g: &fn()) -> extern fn() { return f(g); }
-    fn fn_id(+f: extern fn()) -> extern fn() { return f }
+    fn lol(f: extern fn(v: &fn()) -> extern fn(),
+           g: &fn()) -> extern fn() { return f(g); }
+    fn fn_id(f: extern fn()) -> extern fn() { return f }
     return lol(fn_id, b);
     //~^ ERROR mismatched types
 }
diff --git a/src/test/compile-fail/borrowck-pat-enum.rs b/src/test/compile-fail/borrowck-pat-enum.rs
index c50357e8b9c..f1cca89b227 100644
--- a/src/test/compile-fail/borrowck-pat-enum.rs
+++ b/src/test/compile-fail/borrowck-pat-enum.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn match_ref(&&v: Option<int>) -> int {
+fn match_ref(v: Option<int>) -> int {
     match v {
       Some(ref i) => {
         *i
@@ -17,7 +17,7 @@ fn match_ref(&&v: Option<int>) -> int {
     }
 }
 
-fn match_ref_unused(&&v: Option<int>) {
+fn match_ref_unused(v: Option<int>) {
     match v {
       Some(_) => {}
       None => {}
diff --git a/src/test/compile-fail/borrowck-unary-move.rs b/src/test/compile-fail/borrowck-unary-move.rs
index 107e478004a..cf752986511 100644
--- a/src/test/compile-fail/borrowck-unary-move.rs
+++ b/src/test/compile-fail/borrowck-unary-move.rs
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn foo(+x: ~int) -> int {
+fn foo(x: ~int) -> int {
     let y = &*x;
     free(x); //~ ERROR cannot move out of `*x` because it is borrowed
     *y
 }
 
-fn free(+_x: ~int) {
+fn free(_x: ~int) {
 }
 
 fn main() {
diff --git a/src/test/compile-fail/disallowed-deconstructing-destructing-struct.rs b/src/test/compile-fail/disallowed-deconstructing-destructing-struct.rs
index 9019d338d09..fa34c056794 100644
--- a/src/test/compile-fail/disallowed-deconstructing-destructing-struct.rs
+++ b/src/test/compile-fail/disallowed-deconstructing-destructing-struct.rs
@@ -18,7 +18,7 @@ impl Drop for X {
     }
 }
 
-fn unwrap(+x: X) -> ~str {
+fn unwrap(x: X) -> ~str {
     let X { x: y } = x; //~ ERROR deconstructing struct not allowed in pattern
     y
 }
diff --git a/src/test/compile-fail/elided-test.rs b/src/test/compile-fail/elided-test.rs
index eaae721e0e5..b62214b12f9 100644
--- a/src/test/compile-fail/elided-test.rs
+++ b/src/test/compile-fail/elided-test.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: entry function not found
+// error-pattern: main function not found
 
 // Since we're not compiling a test runner this function should be elided
 // and the build will fail because main doesn't exist
diff --git a/src/test/compile-fail/issue-2766-a.rs b/src/test/compile-fail/issue-2766-a.rs
index 5e3eb9ef09b..5b55cc772fd 100644
--- a/src/test/compile-fail/issue-2766-a.rs
+++ b/src/test/compile-fail/issue-2766-a.rs
@@ -15,10 +15,10 @@ pub mod stream {
         use core::pipes;
 
         pub impl<T:Owned> Stream<T> {
-            pub fn recv() -> extern fn(+v: Stream<T>) -> ::stream::Stream<T> {
+            pub fn recv() -> extern fn(v: Stream<T>) -> ::stream::Stream<T> {
               // resolve really should report just one error here.
               // Change the test case when it changes.
-              pub fn recv(+pipe: Stream<T>) -> ::stream::Stream<T> { //~ ERROR attempt to use a type argument out of scope
+              pub fn recv(pipe: Stream<T>) -> ::stream::Stream<T> { //~ ERROR attempt to use a type argument out of scope
                 //~^ ERROR use of undeclared type name
                 //~^^ ERROR attempt to use a type argument out of scope
                 //~^^^ ERROR use of undeclared type name
diff --git a/src/test/compile-fail/issue-2995.rs b/src/test/compile-fail/issue-2995.rs
index 5c48416667f..3e771eef970 100644
--- a/src/test/compile-fail/issue-2995.rs
+++ b/src/test/compile-fail/issue-2995.rs
@@ -11,3 +11,5 @@
 fn bad (p: *int) {
     let _q: &int = p as &int; //~ ERROR non-scalar cast
 }
+
+fn main() { }
\ No newline at end of file
diff --git a/src/test/compile-fail/issue-3296.rs b/src/test/compile-fail/issue-3296.rs
index 00425825e3f..062ee8fd01e 100644
--- a/src/test/compile-fail/issue-3296.rs
+++ b/src/test/compile-fail/issue-3296.rs
@@ -18,7 +18,7 @@ struct Foo {
     a: ()
 }
 
-fn deserialize_foo<__D: std::serialization::deserializer>(&&__d: __D) {
+fn deserialize_foo<__D: std::serialization::deserializer>(__d: __D) {
 }
 
 fn main() { let des = Deserializer(); let foo = deserialize_foo(des); }
diff --git a/src/test/compile-fail/liveness-use-after-send.rs b/src/test/compile-fail/liveness-use-after-send.rs
index fdc0392a74c..23d3fff01cf 100644
--- a/src/test/compile-fail/liveness-use-after-send.rs
+++ b/src/test/compile-fail/liveness-use-after-send.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn send<T:Owned>(ch: _chan<T>, +data: T) {
+fn send<T:Owned>(ch: _chan<T>, data: T) {
     debug!(ch);
     debug!(data);
     fail!();
diff --git a/src/test/compile-fail/multiple-main.rs b/src/test/compile-fail/main-wrong-location.rs
index ef8cd58abf9..90ef7843d4b 100644
--- a/src/test/compile-fail/multiple-main.rs
+++ b/src/test/compile-fail/main-wrong-location.rs
@@ -8,10 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main() {
-}
-
-mod foo {
-    fn main() { //~ ERROR multiple 'main' functions
-    }
-}
+mod m {
+    // An inferred main entry point (that doesn't use #[main])
+    // must appear at the top of the crate
+    fn main() { } //~ NOTE here is a function named 'main'
+}
\ No newline at end of file
diff --git a/src/test/compile-fail/missing-main.rs b/src/test/compile-fail/missing-main.rs
index 4f1b604b507..4bfdaf69480 100644
--- a/src/test/compile-fail/missing-main.rs
+++ b/src/test/compile-fail/missing-main.rs
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern:entry function not found
+// error-pattern:main function not found
 fn mian() { }
diff --git a/src/test/compile-fail/mutable-huh-ptr-assign.rs b/src/test/compile-fail/mutable-huh-ptr-assign.rs
index 6b3fd4f7153..c907eb4be49 100644
--- a/src/test/compile-fail/mutable-huh-ptr-assign.rs
+++ b/src/test/compile-fail/mutable-huh-ptr-assign.rs
@@ -11,7 +11,7 @@
 extern mod std;
 
 fn main() {
-    unsafe fn f(&&v: *const int) {
+    unsafe fn f(v: *const int) {
         *v = 1 //~ ERROR cannot assign
     }
 
diff --git a/src/test/compile-fail/simd-type.rs b/src/test/compile-fail/simd-type.rs
new file mode 100644
index 00000000000..8387b2bc723
--- /dev/null
+++ b/src/test/compile-fail/simd-type.rs
@@ -0,0 +1,13 @@
+#[simd]
+struct vec4<T>(T, T, T, T); //~ ERROR SIMD vector cannot be generic
+
+#[simd]
+struct empty; //~ ERROR SIMD vector cannot be empty
+
+#[simd]
+struct i64f64(i64, f64); //~ ERROR SIMD vector should be homogeneous
+
+#[simd]
+struct int4(int, int, int, int); //~ ERROR SIMD vector element type should be machine type
+
+fn main() {}
diff --git a/src/test/compile-fail/tag-variant-disr-dup.rs b/src/test/compile-fail/tag-variant-disr-dup.rs
index be53b6a0ba3..216779fac7c 100644
--- a/src/test/compile-fail/tag-variant-disr-dup.rs
+++ b/src/test/compile-fail/tag-variant-disr-dup.rs
@@ -19,3 +19,5 @@ enum color {
     black = 0x000000,
     white = 0x000000,
 }
+
+fn main() { }
\ No newline at end of file
diff --git a/src/test/compile-fail/unique-vec-res.rs b/src/test/compile-fail/unique-vec-res.rs
index a3c51e2b7b1..003e8ccf309 100644
--- a/src/test/compile-fail/unique-vec-res.rs
+++ b/src/test/compile-fail/unique-vec-res.rs
@@ -21,7 +21,7 @@ impl Drop for r {
     }
 }
 
-fn f<T>(+_i: ~[T], +_j: ~[T]) {
+fn f<T>(_i: ~[T], _j: ~[T]) {
 }
 
 fn main() {
diff --git a/src/test/run-fail/morestack3.rs b/src/test/run-fail/morestack3.rs
index 14fc40a43cc..012e9d19b12 100644
--- a/src/test/run-fail/morestack3.rs
+++ b/src/test/run-fail/morestack3.rs
@@ -14,7 +14,7 @@
 
 extern mod std;
 
-fn getbig_and_fail(&&i: int) {
+fn getbig_and_fail(i: int) {
     let _r = and_then_get_big_again(5);
     if i != 0 {
         getbig_and_fail(i - 1);
diff --git a/src/test/run-fail/morestack4.rs b/src/test/run-fail/morestack4.rs
index e4585393703..6fc187491cf 100644
--- a/src/test/run-fail/morestack4.rs
+++ b/src/test/run-fail/morestack4.rs
@@ -14,7 +14,7 @@
 
 extern mod std;
 
-fn getbig_and_fail(&&i: int) {
+fn getbig_and_fail(i: int) {
     let r = and_then_get_big_again(5);
     if i != 0 {
         getbig_and_fail(i - 1);
diff --git a/src/test/run-fail/unwind-move.rs b/src/test/run-fail/unwind-move.rs
index 51e2eaa44fa..8f1b34d17cd 100644
--- a/src/test/run-fail/unwind-move.rs
+++ b/src/test/run-fail/unwind-move.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // error-pattern:fail
-fn f(+_a: @int) {
+fn f(_a: @int) {
     fail!();
 }
 
diff --git a/src/test/run-pass/argument-passing.rs b/src/test/run-pass/argument-passing.rs
index d61c1214633..8c84187ff6f 100644
--- a/src/test/run-pass/argument-passing.rs
+++ b/src/test/run-pass/argument-passing.rs
@@ -10,9 +10,11 @@
 
 // xfail-fast
 
-struct X { x: int }
+struct X {
+    x: int
+}
 
-fn f1(a: &mut X, b: &mut int, +c: int) -> int {
+fn f1(a: &mut X, b: &mut int, c: int) -> int {
     let r = a.x + *b + c;
     a.x = 0;
     *b = 10;
diff --git a/src/test/run-pass/auto-ref-sliceable.rs b/src/test/run-pass/auto-ref-sliceable.rs
index 03e847e237d..f74d78f99d0 100644
--- a/src/test/run-pass/auto-ref-sliceable.rs
+++ b/src/test/run-pass/auto-ref-sliceable.rs
@@ -9,11 +9,11 @@
 // except according to those terms.
 
 trait Pushable<T> {
-    fn push_val(&mut self, +t: T);
+    fn push_val(&mut self, t: T);
 }
 
 impl<T> Pushable<T> for ~[T] {
-    fn push_val(&mut self, +t: T) {
+    fn push_val(&mut self, t: T) {
         self.push(t);
     }
 }
diff --git a/src/test/run-pass/bind-by-move.rs b/src/test/run-pass/bind-by-move.rs
index d3d0e48f5b0..8752102c3a5 100644
--- a/src/test/run-pass/bind-by-move.rs
+++ b/src/test/run-pass/bind-by-move.rs
@@ -11,7 +11,7 @@
 // xfail-fast
 extern mod std;
 use std::arc;
-fn dispose(+_x: arc::ARC<bool>) { unsafe { } }
+fn dispose(_x: arc::ARC<bool>) { unsafe { } }
 
 pub fn main() {
     let p = arc::ARC(true);
diff --git a/src/test/run-pass/borrowck-lend-args.rs b/src/test/run-pass/borrowck-lend-args.rs
index 0d51993e226..a912e1ef65c 100644
--- a/src/test/run-pass/borrowck-lend-args.rs
+++ b/src/test/run-pass/borrowck-lend-args.rs
@@ -10,7 +10,7 @@
 
 fn borrow(_v: &int) {}
 
-fn borrow_from_arg_imm_ref(&&v: ~int) {
+fn borrow_from_arg_imm_ref(v: ~int) {
     borrow(v);
 }
 
@@ -18,7 +18,7 @@ fn borrow_from_arg_mut_ref(v: &mut ~int) {
     borrow(*v);
 }
 
-fn borrow_from_arg_copy(+v: ~int) {
+fn borrow_from_arg_copy(v: ~int) {
     borrow(v);
 }
 
diff --git a/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs b/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs
index 6929a98d9e1..8f66faab014 100644
--- a/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs
+++ b/src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs
@@ -14,7 +14,7 @@ fn want_slice(v: &[int]) -> int {
     return sum;
 }
 
-fn has_mut_vec(+v: ~[int]) -> int {
+fn has_mut_vec(v: ~[int]) -> int {
     want_slice(v)
 }
 
diff --git a/src/test/run-pass/borrowck-newtype-issue-2573.rs b/src/test/run-pass/borrowck-newtype-issue-2573.rs
index 7724836b5db..5f0c7cad619 100644
--- a/src/test/run-pass/borrowck-newtype-issue-2573.rs
+++ b/src/test/run-pass/borrowck-newtype-issue-2573.rs
@@ -25,7 +25,7 @@ impl frob for foo {
 }
 
 // Override default mode so that we are passing by value
-fn really_impure(++bar: baz) {
+fn really_impure(bar: baz) {
     bar.baz = 3;
 }
 
diff --git a/src/test/run-pass/capture_nil.rs b/src/test/run-pass/capture_nil.rs
index 99d8fab4bba..817891c1146 100644
--- a/src/test/run-pass/capture_nil.rs
+++ b/src/test/run-pass/capture_nil.rs
@@ -26,7 +26,7 @@
 
 use core::comm::*;
 
-fn foo(&&x: ()) -> Port<()> {
+fn foo(x: ()) -> Port<()> {
     let (p, c) = stream::<()>();
     do task::spawn() {
         c.send(x);
diff --git a/src/test/run-pass/child-outlives-parent.rs b/src/test/run-pass/child-outlives-parent.rs
index 50c6b821143..4eb3cea3a25 100644
--- a/src/test/run-pass/child-outlives-parent.rs
+++ b/src/test/run-pass/child-outlives-parent.rs
@@ -12,6 +12,8 @@
 
 extern mod std;
 
-fn child2(&&s: ~str) { }
+fn child2(s: ~str) { }
 
-pub fn main() { let x = task::spawn(|| child2(~"hi") ); }
+pub fn main() {
+    let x = task::spawn(|| child2(~"hi"));
+}
diff --git a/src/test/run-pass/class-poly-methods.rs b/src/test/run-pass/class-poly-methods.rs
index adcab8b40aa..9774d8d1488 100644
--- a/src/test/run-pass/class-poly-methods.rs
+++ b/src/test/run-pass/class-poly-methods.rs
@@ -22,7 +22,7 @@ pub impl<U> cat<U> {
     fn meow_count(&mut self) -> uint { self.meows }
 }
 
-fn cat<U>(in_x : uint, in_y : int, +in_info: ~[U]) -> cat<U> {
+fn cat<U>(in_x : uint, in_y : int, in_info: ~[U]) -> cat<U> {
     cat {
         meows: in_x,
         how_hungry: in_y,
diff --git a/src/test/run-pass/cleanup-copy-mode.rs b/src/test/run-pass/cleanup-copy-mode.rs
index b334f32f344..cb378da13ea 100644
--- a/src/test/run-pass/cleanup-copy-mode.rs
+++ b/src/test/run-pass/cleanup-copy-mode.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 // xfail-win32
-fn adder(+x: @int, +y: @int) -> int { return *x + *y; }
+fn adder(x: @int, y: @int) -> int { return *x + *y; }
 fn failer() -> @int { fail!(); }
 pub fn main() {
     assert!(result::is_err(&task::try(|| {
diff --git a/src/test/run-pass/deriving-rand.rs b/src/test/run-pass/deriving-rand.rs
new file mode 100644
index 00000000000..dd4664e7446
--- /dev/null
+++ b/src/test/run-pass/deriving-rand.rs
@@ -0,0 +1,39 @@
+// xfail-fast #6330
+// Copyright 2013 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.
+
+#[deriving(Rand)]
+struct A;
+
+#[deriving(Rand)]
+struct B(int, int);
+
+#[deriving(Rand)]
+struct C {
+    x: f64,
+    y: (u8, u8)
+}
+
+#[deriving(Rand)]
+enum D {
+    D0,
+    D1(uint),
+    D2 { x: (), y: () }
+}
+
+fn main() {
+    // check there's no segfaults
+    for 20.times {
+        rand::random::<A>();
+        rand::random::<B>();
+        rand::random::<C>();
+        rand::random::<D>();
+    }
+}
\ No newline at end of file
diff --git a/src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs b/src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs
new file mode 100644
index 00000000000..b0b03d8419b
--- /dev/null
+++ b/src/test/run-pass/deriving-self-lifetime-totalord-totaleq.rs
@@ -0,0 +1,32 @@
+// xfail-test FIXME #6257
+
+// Copyright 2013 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.
+
+use core::cmp::{Less,Equal,Greater};
+
+#[deriving(TotalEq,TotalOrd)]
+struct A<'self> {
+    x: &'self int
+}
+
+fn main() {
+    let a = A { x: &1 }, b = A { x: &2 };
+
+    assert!(a.equals(&a));
+    assert!(b.equals(&b));
+
+
+    assert_eq!(a.cmp(&a), Equal);
+    assert_eq!(b.cmp(&b), Equal);
+
+    assert_eq!(a.cmp(&b), Less);
+    assert_eq!(b.cmp(&a), Greater);
+}
diff --git a/src/test/run-pass/deriving-self-lifetime.rs b/src/test/run-pass/deriving-self-lifetime.rs
new file mode 100644
index 00000000000..549a9b398a2
--- /dev/null
+++ b/src/test/run-pass/deriving-self-lifetime.rs
@@ -0,0 +1,33 @@
+// Copyright 2013 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.
+
+#[deriving(Eq,Ord)]
+struct A<'self> {
+    x: &'self int
+}
+
+fn main() {
+    let a = A { x: &1 }, b = A { x: &2 };
+
+    assert_eq!(a, a);
+    assert_eq!(b, b);
+
+
+    assert!(a < b);
+    assert!(b > a);
+
+    assert!(a <= b);
+    assert!(a <= a);
+    assert!(b <= b);
+
+    assert!(b >= a);
+    assert!(b >= b);
+    assert!(a >= a);
+}
diff --git a/src/test/run-pass/deriving-to-str.rs b/src/test/run-pass/deriving-to-str.rs
new file mode 100644
index 00000000000..4b98f9a73c5
--- /dev/null
+++ b/src/test/run-pass/deriving-to-str.rs
@@ -0,0 +1,45 @@
+// xfail-fast #6330
+// Copyright 2013 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.
+
+#[deriving(Rand,ToStr)]
+struct A;
+
+#[deriving(Rand,ToStr)]
+struct B(int, int);
+
+#[deriving(Rand,ToStr)]
+struct C {
+    x: f64,
+    y: (u8, u8)
+}
+
+#[deriving(Rand,ToStr)]
+enum D {
+    D0,
+    D1(uint),
+    D2 { x: (), y: () }
+}
+
+fn main() {
+    macro_rules! t(
+        ($ty:ty) => {{
+            let x =rand::random::<$ty>();
+            assert_eq!(x.to_str(), fmt!("%?", x));
+        }}
+    );
+
+    for 20.times {
+        t!(A);
+        t!(B);
+        t!(C);
+        t!(D);
+    }
+}
\ No newline at end of file
diff --git a/src/test/run-pass/dupe-first-attr.rc b/src/test/run-pass/dupe-first-attr.rc
index d39a2aa4476..9bd63a8d646 100644
--- a/src/test/run-pass/dupe-first-attr.rc
+++ b/src/test/run-pass/dupe-first-attr.rc
@@ -25,3 +25,5 @@ mod hello;
 
 #[cfg(target_os = "android")]
 mod hello;
+
+fn main() { }
\ No newline at end of file
diff --git a/src/test/run-pass/extern-pass-TwoU64s-ref.rs b/src/test/run-pass/extern-pass-TwoU64s-ref.rs
index 2b18dba90f7..19b99eaccc9 100644
--- a/src/test/run-pass/extern-pass-TwoU64s-ref.rs
+++ b/src/test/run-pass/extern-pass-TwoU64s-ref.rs
@@ -16,7 +16,7 @@ struct TwoU64s {
 }
 
 pub extern {
-    pub fn rust_dbg_extern_identity_TwoU64s(&&u: TwoU64s) -> TwoU64s;
+    pub fn rust_dbg_extern_identity_TwoU64s(u: TwoU64s) -> TwoU64s;
 }
 
 pub fn main() {
diff --git a/src/test/run-pass/extern-pub.rs b/src/test/run-pass/extern-pub.rs
index f9b0ccbb548..1cd709ee91b 100644
--- a/src/test/run-pass/extern-pub.rs
+++ b/src/test/run-pass/extern-pub.rs
@@ -1,7 +1,7 @@
 extern {
-    pub unsafe fn vec_reserve_shared_actual(++t: *sys::TypeDesc,
-                                            ++v: **vec::raw::VecRepr,
-                                            ++n: libc::size_t);
+    pub unsafe fn vec_reserve_shared_actual(t: *sys::TypeDesc,
+                                            v: **vec::raw::VecRepr,
+                                            n: libc::size_t);
 }
 
 pub fn main() {
diff --git a/src/test/run-pass/fn-bare-spawn.rs b/src/test/run-pass/fn-bare-spawn.rs
index 857a8cdb3d0..b78bd488bc6 100644
--- a/src/test/run-pass/fn-bare-spawn.rs
+++ b/src/test/run-pass/fn-bare-spawn.rs
@@ -14,7 +14,7 @@ fn spawn<T:Owned>(val: T, f: extern fn(T)) {
     f(val);
 }
 
-fn f(+i: int) {
+fn f(i: int) {
     assert!(i == 100);
 }
 
diff --git a/src/test/run-pass/foreign-struct.rs b/src/test/run-pass/foreign-struct.rs
index 9ac17c27ed4..2dbc60e9a14 100644
--- a/src/test/run-pass/foreign-struct.rs
+++ b/src/test/run-pass/foreign-struct.rs
@@ -18,7 +18,7 @@ mod bindgen {
 
     #[nolink]
     pub extern {
-        pub fn printf(++v: void);
+        pub fn printf(v: void);
     }
 }
 
diff --git a/src/test/run-pass/intrinsic-alignment.rs b/src/test/run-pass/intrinsic-alignment.rs
index adc085d2108..cce3d8066ec 100644
--- a/src/test/run-pass/intrinsic-alignment.rs
+++ b/src/test/run-pass/intrinsic-alignment.rs
@@ -22,6 +22,7 @@ mod rusti {
 #[cfg(target_os = "macos")]
 #[cfg(target_os = "freebsd")]
 mod m {
+    #[main]
     #[cfg(target_arch = "x86")]
     pub fn main() {
         unsafe {
@@ -30,6 +31,7 @@ mod m {
         }
     }
 
+    #[main]
     #[cfg(target_arch = "x86_64")]
     pub fn main() {
         unsafe {
@@ -41,6 +43,7 @@ mod m {
 
 #[cfg(target_os = "win32")]
 mod m {
+    #[main]
     #[cfg(target_arch = "x86")]
     pub fn main() {
         unsafe {
@@ -52,6 +55,7 @@ mod m {
 
 #[cfg(target_os = "android")]
 mod m {
+    #[main]
     #[cfg(target_arch = "arm")]
     pub fn main() {
         unsafe {
diff --git a/src/test/run-pass/intrinsic-move-val.rs b/src/test/run-pass/intrinsic-move-val.rs
index 966061a8085..9f683d20898 100644
--- a/src/test/run-pass/intrinsic-move-val.rs
+++ b/src/test/run-pass/intrinsic-move-val.rs
@@ -11,8 +11,8 @@
 mod rusti {
     #[abi = "rust-intrinsic"]
     pub extern "rust-intrinsic" {
-        pub fn move_val_init<T>(dst: &mut T, +src: T);
-        pub fn move_val<T>(dst: &mut T, +src: T);
+        pub fn move_val_init<T>(dst: &mut T, src: T);
+        pub fn move_val<T>(dst: &mut T, src: T);
     }
 }
 
diff --git a/src/test/run-pass/issue-2633-2.rs b/src/test/run-pass/issue-2633-2.rs
index 2c3b4b71bb8..71a491b8a39 100644
--- a/src/test/run-pass/issue-2633-2.rs
+++ b/src/test/run-pass/issue-2633-2.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn a_val(&&x: ~int, +y: ~int) -> int {
+fn a_val(x: ~int, y: ~int) -> int {
     *x + *y
 }
 
diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs
index f54d3d39831..acd26a88a73 100644
--- a/src/test/run-pass/issue-2718.rs
+++ b/src/test/run-pass/issue-2718.rs
@@ -53,23 +53,23 @@ pub mod pipes {
 
     // We should consider moving this to ::core::unsafe, although I
     // suspect graydon would want us to use void pointers instead.
-    pub unsafe fn uniquify<T>(+x: *T) -> ~T {
+    pub unsafe fn uniquify<T>(x: *T) -> ~T {
         unsafe { cast::transmute(x) }
     }
 
-    pub fn swap_state_acq(+dst: &mut state, src: state) -> state {
+    pub fn swap_state_acq(dst: &mut state, src: state) -> state {
         unsafe {
             transmute(rusti::atomic_xchg_acq(transmute(dst), src as int))
         }
     }
 
-    pub fn swap_state_rel(+dst: &mut state, src: state) -> state {
+    pub fn swap_state_rel(dst: &mut state, src: state) -> state {
         unsafe {
             transmute(rusti::atomic_xchg_rel(transmute(dst), src as int))
         }
     }
 
-    pub fn send<T:Owned>(mut p: send_packet<T>, +payload: T) {
+    pub fn send<T:Owned>(mut p: send_packet<T>, payload: T) {
         let mut p = p.unwrap();
         let mut p = unsafe { uniquify(p) };
         assert!((*p).payload.is_none());
@@ -229,7 +229,7 @@ pub mod pingpong {
     pub struct ping(::pipes::send_packet<pong>);
     pub struct pong(::pipes::send_packet<ping>);
 
-    pub fn liberate_ping(+p: ping) -> ::pipes::send_packet<pong> {
+    pub fn liberate_ping(p: ping) -> ::pipes::send_packet<pong> {
         unsafe {
             let addr : *::pipes::send_packet<pong> = match &p {
               &ping(ref x) => { cast::transmute(x) }
@@ -240,7 +240,7 @@ pub mod pingpong {
         }
     }
 
-    pub fn liberate_pong(+p: pong) -> ::pipes::send_packet<ping> {
+    pub fn liberate_pong(p: pong) -> ::pipes::send_packet<ping> {
         unsafe {
             let addr : *::pipes::send_packet<ping> = match &p {
               &pong(ref x) => { cast::transmute(x) }
@@ -262,14 +262,14 @@ pub mod pingpong {
         pub type ping = ::pipes::send_packet<pingpong::ping>;
         pub type pong = ::pipes::recv_packet<pingpong::pong>;
 
-        pub fn do_ping(+c: ping) -> pong {
+        pub fn do_ping(c: ping) -> pong {
             let (sp, rp) = ::pipes::entangle();
 
             ::pipes::send(c, pingpong::ping(sp));
             rp
         }
 
-        pub fn do_pong(+c: pong) -> (ping, ()) {
+        pub fn do_pong(c: pong) -> (ping, ()) {
             let packet = ::pipes::recv(c);
             if packet.is_none() {
                 fail!(~"sender closed the connection")
@@ -284,7 +284,7 @@ pub mod pingpong {
         pub type ping = ::pipes::recv_packet<pingpong::ping>;
         pub type pong = ::pipes::send_packet<pingpong::pong>;
 
-        pub fn do_ping(+c: ping) -> (pong, ()) {
+        pub fn do_ping(c: ping) -> (pong, ()) {
             let packet = ::pipes::recv(c);
             if packet.is_none() {
                 fail!(~"sender closed the connection")
@@ -292,7 +292,7 @@ pub mod pingpong {
             (pingpong::liberate_ping(packet.unwrap()), ())
         }
 
-        pub fn do_pong(+c: pong) -> ping {
+        pub fn do_pong(c: pong) -> ping {
             let (sp, rp) = ::pipes::entangle();
             ::pipes::send(c, pingpong::pong(sp));
             rp
@@ -300,14 +300,14 @@ pub mod pingpong {
     }
 }
 
-fn client(+chan: pingpong::client::ping) {
+fn client(chan: pingpong::client::ping) {
     let chan = pingpong::client::do_ping(chan);
     error!(~"Sent ping");
     let (_chan, _data) = pingpong::client::do_pong(chan);
     error!(~"Received pong");
 }
 
-fn server(+chan: pingpong::server::ping) {
+fn server(chan: pingpong::server::ping) {
     let (chan, _data) = pingpong::server::do_ping(chan);
     error!(~"Received ping");
     let _chan = pingpong::server::do_pong(chan);
diff --git a/src/test/run-pass/issue-2904.rs b/src/test/run-pass/issue-2904.rs
index 77cc6b3e1b5..112aab597f0 100644
--- a/src/test/run-pass/issue-2904.rs
+++ b/src/test/run-pass/issue-2904.rs
@@ -59,7 +59,7 @@ fn square_from_char(c: char) -> square {
     }
 }
 
-fn read_board_grid<rdr:'static + io::Reader>(+in: rdr) -> ~[~[square]] {
+fn read_board_grid<rdr:'static + io::Reader>(in: rdr) -> ~[~[square]] {
     let in = @in as @io::Reader;
     let mut grid = ~[];
     for in.each_line |line| {
diff --git a/src/test/run-pass/issue-3176.rs b/src/test/run-pass/issue-3176.rs
index 55d62a5bf8e..d22c7e82ad5 100644
--- a/src/test/run-pass/issue-3176.rs
+++ b/src/test/run-pass/issue-3176.rs
@@ -26,7 +26,8 @@ pub fn main() {
         c2.send(());
         error!("child blocks");
         let (p, c) = comm::stream();
-        (p, p3).select();
+        let mut tuple = (p, p3);
+        tuple.select();
         c.send(());
     };
     error!("parent tries");
diff --git a/src/test/run-pass/issue-3656.rs b/src/test/run-pass/issue-3656.rs
index b59810fc188..895e90beef4 100644
--- a/src/test/run-pass/issue-3656.rs
+++ b/src/test/run-pass/issue-3656.rs
@@ -24,7 +24,7 @@ struct KEYGEN {
 
 extern {
     // Bogus signature, just need to test if it compiles.
-    pub fn malloc(++data: KEYGEN);
+    pub fn malloc(data: KEYGEN);
 }
 
 pub fn main() {
diff --git a/src/test/run-pass/iter-min-max.rs b/src/test/run-pass/iter-min-max.rs
index a8831a9c5ad..5f427861e79 100644
--- a/src/test/run-pass/iter-min-max.rs
+++ b/src/test/run-pass/iter-min-max.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn is_even(&&x: uint) -> bool { (x % 2u) == 0u }
+fn is_even(x: uint) -> bool { (x % 2u) == 0u }
 
 pub fn main() {
     assert!([1u, 3u].min() == 1u);
diff --git a/src/test/run-pass/liveness-move-in-loop.rs b/src/test/run-pass/liveness-move-in-loop.rs
index 658885124c2..acdf388a8ff 100644
--- a/src/test/run-pass/liveness-move-in-loop.rs
+++ b/src/test/run-pass/liveness-move-in-loop.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn take(+x: int) -> int {x}
+fn take(x: int) -> int {x}
 
 fn the_loop() {
     let mut list = ~[];
diff --git a/src/test/run-pass/morestack5.rs b/src/test/run-pass/morestack5.rs
index 1d232cc5cbd..e1561db8b91 100644
--- a/src/test/run-pass/morestack5.rs
+++ b/src/test/run-pass/morestack5.rs
@@ -12,7 +12,7 @@
 
 extern mod std;
 
-fn getbig(&&i: int) {
+fn getbig(i: int) {
     if i != 0 {
         getbig(i - 1);
     }
diff --git a/src/test/run-pass/morestack6.rs b/src/test/run-pass/morestack6.rs
index 1f908936aef..dafdd0fba48 100644
--- a/src/test/run-pass/morestack6.rs
+++ b/src/test/run-pass/morestack6.rs
@@ -62,7 +62,7 @@ pub fn main() {
         calllink09,
         calllink10
     ];
-    let rng = rand::rng();
+    let mut rng = rand::rng();
     for fns.each |f| {
         let f = *f;
         let sz = rng.next() % 256u32 + 256u32;
diff --git a/src/test/run-pass/move-arg-2-unique.rs b/src/test/run-pass/move-arg-2-unique.rs
index dbc73c20e6b..ed3cdc81c31 100644
--- a/src/test/run-pass/move-arg-2-unique.rs
+++ b/src/test/run-pass/move-arg-2-unique.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn test(+foo: ~~[int]) { assert!((foo[0] == 10)); }
+fn test(foo: ~~[int]) { assert!((foo[0] == 10)); }
 
 pub fn main() {
     let x = ~~[10];
diff --git a/src/test/run-pass/move-arg-2.rs b/src/test/run-pass/move-arg-2.rs
index 5cc309d1a3e..fc909da8b03 100644
--- a/src/test/run-pass/move-arg-2.rs
+++ b/src/test/run-pass/move-arg-2.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn test(+foo: @~[int]) { assert!((foo[0] == 10)); }
+fn test(foo: @~[int]) { assert!((foo[0] == 10)); }
 
 pub fn main() {
     let x = @~[10];
diff --git a/src/test/run-pass/move-arg.rs b/src/test/run-pass/move-arg.rs
index ca3a5509c5c..87db5cbe2f1 100644
--- a/src/test/run-pass/move-arg.rs
+++ b/src/test/run-pass/move-arg.rs
@@ -8,6 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn test(+foo: int) { assert!((foo == 10)); }
+fn test(foo: int) { assert!((foo == 10)); }
 
 pub fn main() { let x = 10; test(x); }
diff --git a/src/test/run-pass/move-nullary-fn.rs b/src/test/run-pass/move-nullary-fn.rs
index eb4c5f871af..ab66bb93635 100644
--- a/src/test/run-pass/move-nullary-fn.rs
+++ b/src/test/run-pass/move-nullary-fn.rs
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 // Issue #922
-fn f2(+thing: @fn()) { }
+fn f2(thing: @fn()) { }
 
-fn f(+thing: @fn()) {
+fn f(thing: @fn()) {
     f2(thing);
 }
 
diff --git a/src/test/run-pass/operator-overloading.rs b/src/test/run-pass/operator-overloading.rs
index ffd6903d7f7..8c26dfa1fac 100644
--- a/src/test/run-pass/operator-overloading.rs
+++ b/src/test/run-pass/operator-overloading.rs
@@ -40,7 +40,7 @@ impl ops::Not<Point> for Point {
 }
 
 impl ops::Index<bool,int> for Point {
-    fn index(&self, +x: &bool) -> int {
+    fn index(&self, x: &bool) -> int {
         if *x { self.x } else { self.y }
     }
 }
diff --git a/src/test/run-pass/option-unwrap.rs b/src/test/run-pass/option-unwrap.rs
index 0efed2708f4..8698d1f39a8 100644
--- a/src/test/run-pass/option-unwrap.rs
+++ b/src/test/run-pass/option-unwrap.rs
@@ -23,7 +23,7 @@ impl Drop for dtor {
     }
 }
 
-fn unwrap<T>(+o: Option<T>) -> T {
+fn unwrap<T>(o: Option<T>) -> T {
     match o {
       Some(v) => v,
       None => fail!()
diff --git a/src/test/run-pass/pass-by-copy.rs b/src/test/run-pass/pass-by-copy.rs
index c3ab589b66c..c4f328940c4 100644
--- a/src/test/run-pass/pass-by-copy.rs
+++ b/src/test/run-pass/pass-by-copy.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn magic(+x: A) { debug!(x); }
-fn magic2(+x: @int) { debug!(x); }
+fn magic(x: A) { debug!(x); }
+fn magic2(x: @int) { debug!(x); }
 
 struct A { a: @int }
 
diff --git a/src/test/run-pass/pipe-bank-proto.rs b/src/test/run-pass/pipe-bank-proto.rs
index c4ce1434165..5e2be7e6d08 100644
--- a/src/test/run-pass/pipe-bank-proto.rs
+++ b/src/test/run-pass/pipe-bank-proto.rs
@@ -48,12 +48,12 @@ macro_rules! move_it (
     { $x:expr } => { unsafe { let y = *ptr::to_unsafe_ptr(&($x)); y } }
 )
 
-fn switch<T:Owned,U>(+endp: pipes::RecvPacket<T>,
-                      f: &fn(+v: Option<T>) -> U) -> U {
+fn switch<T:Owned,U>(endp: pipes::RecvPacket<T>,
+                     f: &fn(v: Option<T>) -> U) -> U {
     f(pipes::try_recv(endp))
 }
 
-fn move_it<T>(+x: T) -> T { x }
+fn move_it<T>(x: T) -> T { x }
 
 macro_rules! follow (
     {
@@ -68,7 +68,7 @@ macro_rules! follow (
     );
 )
 
-fn client_follow(+bank: bank::client::login) {
+fn client_follow(bank: bank::client::login) {
     use bank::*;
 
     let bank = client::login(bank, ~"theincredibleholk", ~"1234");
@@ -89,7 +89,7 @@ fn client_follow(+bank: bank::client::login) {
     ));
 }
 
-fn bank_client(+bank: bank::client::login) {
+fn bank_client(bank: bank::client::login) {
     use bank::*;
 
     let bank = client::login(bank, ~"theincredibleholk", ~"1234");
diff --git a/src/test/run-pass/pipe-peek.rs b/src/test/run-pass/pipe-peek.rs
index 46fbb88aef2..985eaecdc78 100644
--- a/src/test/run-pass/pipe-peek.rs
+++ b/src/test/run-pass/pipe-peek.rs
@@ -22,11 +22,11 @@ proto! oneshot (
 )
 
 pub fn main() {
-    let (c, p) = oneshot::init();
+    let mut (c, p) = oneshot::init();
 
-    assert!(!pipes::peek(&p));
+    assert!(!pipes::peek(&mut p));
 
     oneshot::client::signal(c);
 
-    assert!(pipes::peek(&p));
+    assert!(pipes::peek(&mut p));
 }
diff --git a/src/test/run-pass/pipe-pingpong-bounded.rs b/src/test/run-pass/pipe-pingpong-bounded.rs
index 69d87804b42..3c37371a537 100644
--- a/src/test/run-pass/pipe-pingpong-bounded.rs
+++ b/src/test/run-pass/pipe-pingpong-bounded.rs
@@ -40,7 +40,7 @@ mod pingpong {
         do pipes::entangle_buffer(buffer) |buffer, data| {
             data.ping.set_buffer(buffer);
             data.pong.set_buffer(buffer);
-            ptr::to_unsafe_ptr(&(data.ping))
+            ptr::to_mut_unsafe_ptr(&mut (data.ping))
         }
     }
     pub struct ping(server::pong);
@@ -50,11 +50,11 @@ mod pingpong {
         use core::pipes::*;
         use core::ptr;
 
-        pub fn ping(+pipe: ping) -> pong {
+        pub fn ping(mut pipe: ping) -> pong {
             {
-                let b = pipe.reuse_buffer();
-                let s = SendPacketBuffered(&b.buffer.data.pong);
-                let c = RecvPacketBuffered(&b.buffer.data.pong);
+                let mut b = pipe.reuse_buffer();
+                let s = SendPacketBuffered(&mut b.buffer.data.pong);
+                let c = RecvPacketBuffered(&mut b.buffer.data.pong);
                 let message = ::pingpong::ping(s);
                 send(pipe, message);
                 c
@@ -72,11 +72,11 @@ mod pingpong {
 
         pub type ping = pipes::RecvPacketBuffered<::pingpong::ping,
         ::pingpong::Packets>;
-        pub fn pong(+pipe: pong) -> ping {
+        pub fn pong(mut pipe: pong) -> ping {
             {
-                let b = pipe.reuse_buffer();
-                let s = SendPacketBuffered(&b.buffer.data.ping);
-                let c = RecvPacketBuffered(&b.buffer.data.ping);
+                let mut b = pipe.reuse_buffer();
+                let s = SendPacketBuffered(&mut b.buffer.data.ping);
+                let c = RecvPacketBuffered(&mut b.buffer.data.ping);
                 let message = ::pingpong::pong(s);
                 send(pipe, message);
                 c
@@ -91,7 +91,7 @@ mod test {
     use core::pipes::recv;
     use pingpong::{ping, pong};
 
-    pub fn client(+chan: ::pingpong::client::ping) {
+    pub fn client(chan: ::pingpong::client::ping) {
         use pingpong::client;
 
         let chan = client::ping(chan); return;
@@ -100,7 +100,7 @@ mod test {
         error!("Received pong");
     }
 
-    pub fn server(+chan: ::pingpong::server::ping) {
+    pub fn server(chan: ::pingpong::server::ping) {
         use pingpong::server;
 
         let ping(chan) = recv(chan); return;
diff --git a/src/test/run-pass/pipe-pingpong-proto.rs b/src/test/run-pass/pipe-pingpong-proto.rs
index d1198f3611d..5978438ef76 100644
--- a/src/test/run-pass/pipe-pingpong-proto.rs
+++ b/src/test/run-pass/pipe-pingpong-proto.rs
@@ -29,7 +29,7 @@ mod test {
     use core::pipes::recv;
     use pingpong::{ping, pong};
 
-    pub fn client(+chan: ::pingpong::client::ping) {
+    pub fn client(chan: ::pingpong::client::ping) {
         use pingpong::client;
 
         let chan = client::ping(chan);
@@ -38,7 +38,7 @@ mod test {
         error!(~"Received pong");
     }
 
-    pub fn server(+chan: ::pingpong::server::ping) {
+    pub fn server(chan: ::pingpong::server::ping) {
         use pingpong::server;
 
         let ping(chan) = recv(chan);
diff --git a/src/test/run-pass/pipe-presentation-examples.rs b/src/test/run-pass/pipe-presentation-examples.rs
index 01f68929b90..fcfd77dab0a 100644
--- a/src/test/run-pass/pipe-presentation-examples.rs
+++ b/src/test/run-pass/pipe-presentation-examples.rs
@@ -1,4 +1,8 @@
 // xfail-fast
+// xfail-test
+
+// XFAIL'd because this is going to be revamped, and it's not compatible as
+// written with the new mutability rules.
 
 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
diff --git a/src/test/run-pass/platform_thread.rs b/src/test/run-pass/platform_thread.rs
index 5e4830b0bbd..774f2470b3c 100644
--- a/src/test/run-pass/platform_thread.rs
+++ b/src/test/run-pass/platform_thread.rs
@@ -24,9 +24,15 @@ fn run(i: int) {
         return;
     }
 
-    do task::task().sched_mode(task::PlatformThread).unlinked().spawn {
+    let mut builder = task::task();
+    builder.sched_mode(task::PlatformThread);
+    builder.unlinked();
+    do builder.spawn {
         task::yield();
-        do task::task().sched_mode(task::SingleThreaded).unlinked().spawn {
+        let mut builder = task::task();
+        builder.sched_mode(task::SingleThreaded);
+        builder.unlinked();
+        do builder.spawn {
             task::yield();
             run(i - 1);
             task::yield();
diff --git a/src/test/run-pass/reflect-visit-data.rs b/src/test/run-pass/reflect-visit-data.rs
index 5b01d24aa8b..5255c13bead 100644
--- a/src/test/run-pass/reflect-visit-data.rs
+++ b/src/test/run-pass/reflect-visit-data.rs
@@ -633,7 +633,7 @@ impl TyVisitor for my_visitor {
     fn visit_closure_ptr(&self, _ck: uint) -> bool { true }
 }
 
-fn get_tydesc_for<T>(&&_t: T) -> *TyDesc {
+fn get_tydesc_for<T>(_t: T) -> *TyDesc {
     get_tydesc::<T>()
 }
 
diff --git a/src/test/run-pass/regions-copy-closure.rs b/src/test/run-pass/regions-copy-closure.rs
index 308528ef572..2e9ff88f96e 100644
--- a/src/test/run-pass/regions-copy-closure.rs
+++ b/src/test/run-pass/regions-copy-closure.rs
@@ -12,7 +12,7 @@ struct closure_box<'self> {
     cl: &'self fn(),
 }
 
-fn box_it<'r>(+x: &'r fn()) -> closure_box<'r> {
+fn box_it<'r>(x: &'r fn()) -> closure_box<'r> {
     closure_box {cl: x}
 }
 
diff --git a/src/test/run-pass/regions-static-closure.rs b/src/test/run-pass/regions-static-closure.rs
index 5221bc28fb8..eab057548ef 100644
--- a/src/test/run-pass/regions-static-closure.rs
+++ b/src/test/run-pass/regions-static-closure.rs
@@ -12,7 +12,7 @@ struct closure_box<'self> {
     cl: &'self fn(),
 }
 
-fn box_it<'r>(+x: &'r fn()) -> closure_box<'r> {
+fn box_it<'r>(x: &'r fn()) -> closure_box<'r> {
     closure_box {cl: x}
 }
 
diff --git a/src/test/run-pass/sendfn-spawn-with-fn-arg.rs b/src/test/run-pass/sendfn-spawn-with-fn-arg.rs
index afed0bd9ac3..2a69b2ca017 100644
--- a/src/test/run-pass/sendfn-spawn-with-fn-arg.rs
+++ b/src/test/run-pass/sendfn-spawn-with-fn-arg.rs
@@ -12,7 +12,7 @@ use core::cell::Cell;
 
 pub fn main() { test05(); }
 
-fn test05_start(&&f: ~fn(int)) {
+fn test05_start(f: ~fn(int)) {
     f(22);
 }
 
diff --git a/src/test/run-pass/simd-type.rs b/src/test/run-pass/simd-type.rs
new file mode 100644
index 00000000000..c3bcc9d0b7a
--- /dev/null
+++ b/src/test/run-pass/simd-type.rs
@@ -0,0 +1,9 @@
+#[simd]
+struct RGBA {
+    r: f32,
+    g: f32,
+    b: f32,
+    a: f32
+}
+
+fn main() {}
diff --git a/src/test/run-pass/spawn.rs b/src/test/run-pass/spawn.rs
index 63c2b7da38f..9a5131ef230 100644
--- a/src/test/run-pass/spawn.rs
+++ b/src/test/run-pass/spawn.rs
@@ -17,4 +17,4 @@ pub fn main() {
     task::spawn(|| child(10) );
 }
 
-fn child(&&i: int) { error!(i); assert!((i == 10)); }
+fn child(i: int) { error!(i); assert!((i == 10)); }
diff --git a/src/test/run-pass/spawn2.rs b/src/test/run-pass/spawn2.rs
index e748a1636ea..642babb5a1e 100644
--- a/src/test/run-pass/spawn2.rs
+++ b/src/test/run-pass/spawn2.rs
@@ -11,7 +11,7 @@
 
 pub fn main() { task::spawn(|| child((10, 20, 30, 40, 50, 60, 70, 80, 90)) ); }
 
-fn child(&&args: (int, int, int, int, int, int, int, int, int)) {
+fn child(args: (int, int, int, int, int, int, int, int, int)) {
     let (i1, i2, i3, i4, i5, i6, i7, i8, i9) = args;
     error!(i1);
     error!(i2);
diff --git a/src/test/run-pass/static-method-test.rs b/src/test/run-pass/static-method-test.rs
index 973897cd145..e06d09c564c 100644
--- a/src/test/run-pass/static-method-test.rs
+++ b/src/test/run-pass/static-method-test.rs
@@ -13,7 +13,7 @@
 // A trait for objects that can be used to do an if-then-else
 // (No actual need for this to be static, but it is a simple test.)
 trait bool_like {
-    fn select<A>(b: Self, +x1: A, +x2: A) -> A;
+    fn select<A>(b: Self, x1: A, x2: A) -> A;
 }
 
 fn andand<T:bool_like + Copy>(x1: T, x2: T) -> T {
@@ -21,38 +21,38 @@ fn andand<T:bool_like + Copy>(x1: T, x2: T) -> T {
 }
 
 impl bool_like for bool {
-    fn select<A>(&&b: bool, +x1: A, +x2: A) -> A {
+    fn select<A>(b: bool, x1: A, x2: A) -> A {
         if b { x1 } else { x2 }
     }
 }
 
 impl bool_like for int {
-    fn select<A>(&&b: int, +x1: A, +x2: A) -> A {
+    fn select<A>(b: int, x1: A, x2: A) -> A {
         if b != 0 { x1 } else { x2 }
     }
 }
 
 // A trait for sequences that can be constructed imperatively.
 trait buildable<A> {
-     fn build_sized(size: uint, builder: &fn(push: &fn(+v: A))) -> Self;
+     fn build_sized(size: uint, builder: &fn(push: &fn(v: A))) -> Self;
 }
 
 
 impl<A> buildable<A> for @[A] {
     #[inline(always)]
-     fn build_sized(size: uint, builder: &fn(push: &fn(+v: A))) -> @[A] {
+     fn build_sized(size: uint, builder: &fn(push: &fn(v: A))) -> @[A] {
          at_vec::build_sized(size, builder)
      }
 }
 impl<A> buildable<A> for ~[A] {
     #[inline(always)]
-     fn build_sized(size: uint, builder: &fn(push: &fn(+v: A))) -> ~[A] {
+     fn build_sized(size: uint, builder: &fn(push: &fn(v: A))) -> ~[A] {
          vec::build_sized(size, builder)
      }
 }
 
 #[inline(always)]
-fn build<A, B: buildable<A>>(builder: &fn(push: &fn(+v: A))) -> B {
+fn build<A, B: buildable<A>>(builder: &fn(push: &fn(v: A))) -> B {
     buildable::build_sized(4, builder)
 }
 
diff --git a/src/test/run-pass/struct-return.rs b/src/test/run-pass/struct-return.rs
index 5427ee38b43..7ac74fd5217 100644
--- a/src/test/run-pass/struct-return.rs
+++ b/src/test/run-pass/struct-return.rs
@@ -16,8 +16,8 @@ mod rustrt {
 
     #[nolink]
     pub extern {
-        pub fn debug_abi_1(++q: Quad) -> Quad;
-        pub fn debug_abi_2(++f: Floats) -> Floats;
+        pub fn debug_abi_1(q: Quad) -> Quad;
+        pub fn debug_abi_2(f: Floats) -> Floats;
     }
 }
 
diff --git a/src/test/run-pass/task-comm-12.rs b/src/test/run-pass/task-comm-12.rs
index b426212d872..0f0b82d7c21 100644
--- a/src/test/run-pass/task-comm-12.rs
+++ b/src/test/run-pass/task-comm-12.rs
@@ -12,12 +12,14 @@ extern mod std;
 
 pub fn main() { test00(); }
 
-fn start(&&task_number: int) { debug!("Started / Finished task."); }
+fn start(task_number: int) { debug!("Started / Finished task."); }
 
 fn test00() {
     let i: int = 0;
     let mut result = None;
-    do task::task().future_result(|+r| { result = Some(r); }).spawn {
+    let mut builder = task::task();
+    builder.future_result(|r| result = Some(r));
+    do builder.spawn {
         start(i)
     }
 
diff --git a/src/test/run-pass/task-comm-3.rs b/src/test/run-pass/task-comm-3.rs
index cf06deb1923..fd700475988 100644
--- a/src/test/run-pass/task-comm-3.rs
+++ b/src/test/run-pass/task-comm-3.rs
@@ -40,9 +40,9 @@ fn test00() {
     let mut results = ~[];
     while i < number_of_tasks {
         let ch = po.chan();
-        task::task().future_result(|+r| {
-            results.push(r);
-        }).spawn({
+        let mut builder = task::task();
+        builder.future_result(|r| results.push(r));
+        builder.spawn({
             let i = i;
             || test00_start(&ch, i, number_of_messages)
         });
diff --git a/src/test/run-pass/task-comm-9.rs b/src/test/run-pass/task-comm-9.rs
index a3c8dc554a6..798e9d37b55 100644
--- a/src/test/run-pass/task-comm-9.rs
+++ b/src/test/run-pass/task-comm-9.rs
@@ -27,8 +27,9 @@ fn test00() {
     let ch = p.chan();
 
     let mut result = None;
-    do task::task().future_result(|+r| { result = Some(r); }).spawn
-          || {
+    let mut builder = task::task();
+    builder.future_result(|r| result = Some(r));
+    do builder.spawn {
         test00_start(&ch, number_of_messages);
     }
 
diff --git a/src/test/run-pass/task-life-0.rs b/src/test/run-pass/task-life-0.rs
index 3e27ffb4152..9885c5d6f3f 100644
--- a/src/test/run-pass/task-life-0.rs
+++ b/src/test/run-pass/task-life-0.rs
@@ -13,6 +13,6 @@ pub fn main() {
     task::spawn(|| child(~"Hello") );
 }
 
-fn child(&&s: ~str) {
+fn child(s: ~str) {
 
 }
diff --git a/src/test/run-pass/threads.rs b/src/test/run-pass/threads.rs
index 288a23b855b..a72d3dd40f4 100644
--- a/src/test/run-pass/threads.rs
+++ b/src/test/run-pass/threads.rs
@@ -18,4 +18,4 @@ pub fn main() {
     debug!("main thread exiting");
 }
 
-fn child(&&x: int) { debug!(x); }
+fn child(x: int) { debug!(x); }
diff --git a/src/test/run-pass/unique-fn-arg-move.rs b/src/test/run-pass/unique-fn-arg-move.rs
index bbb33560e32..4a6386244f1 100644
--- a/src/test/run-pass/unique-fn-arg-move.rs
+++ b/src/test/run-pass/unique-fn-arg-move.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn f(+i: ~int) {
+fn f(i: ~int) {
     assert!(*i == 100);
 }
 
diff --git a/src/test/run-pass/yield.rs b/src/test/run-pass/yield.rs
index 75d9979807b..2d916abf0da 100644
--- a/src/test/run-pass/yield.rs
+++ b/src/test/run-pass/yield.rs
@@ -11,7 +11,9 @@
 
 pub fn main() {
     let mut result = None;
-    task::task().future_result(|+r| { result = Some(r); }).spawn(child);
+    let mut builder = task::task();
+    builder.future_result(|r| { result = Some(r); });
+    builder.spawn(child);
     error!("1");
     task::yield();
     error!("2");
diff --git a/src/test/run-pass/yield1.rs b/src/test/run-pass/yield1.rs
index 51483121f50..f3ca5b12118 100644
--- a/src/test/run-pass/yield1.rs
+++ b/src/test/run-pass/yield1.rs
@@ -11,7 +11,9 @@
 
 pub fn main() {
     let mut result = None;
-    task::task().future_result(|+r| { result = Some(r); }).spawn(child);
+    let mut builder = task::task();
+    builder.future_result(|r| { result = Some(r); });
+    builder.spawn(child);
     error!("1");
     task::yield();
     result.unwrap().recv();