about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/rust.md4
-rw-r--r--doc/tutorial-borrowed-ptr.md161
-rw-r--r--doc/tutorial-ffi.md14
-rw-r--r--doc/tutorial.md27
-rw-r--r--src/libcore/cell.rs (renamed from src/libstd/cell.rs)4
-rw-r--r--src/libcore/core.rc2
-rw-r--r--src/libcore/pipes.rs17
-rw-r--r--src/libcore/private.rs40
-rw-r--r--src/libcore/private/weak_task.rs25
-rw-r--r--src/libcore/repr.rs1
-rw-r--r--src/libcore/task/mod.rs7
-rw-r--r--src/libcore/task/spawn.rs9
-rw-r--r--src/librustc/middle/lint.rs29
-rw-r--r--src/librustc/middle/liveness.rs33
-rw-r--r--src/librustc/middle/trans/type_use.rs14
-rw-r--r--src/librustc/middle/typeck/astconv.rs3
-rw-r--r--src/librustc/middle/typeck/infer/region_inference.rs2
-rw-r--r--src/librustc/rustc.rc2
-rw-r--r--src/librustdoc/astsrv.rs2
-rw-r--r--src/librustdoc/config.rs2
-rw-r--r--src/librustdoc/markdown_pass.rs2
-rw-r--r--src/librustdoc/text_pass.rs2
-rw-r--r--src/libstd/std.rc2
-rw-r--r--src/libsyntax/ext/auto_encode.rs8
-rw-r--r--src/libsyntax/parse/obsolete.rs7
-rw-r--r--src/libsyntax/parse/parser.rs7
-rw-r--r--src/test/bench/msgsend-ring-mutex-arcs.rs24
-rw-r--r--src/test/bench/msgsend-ring-pipes.rs26
-rw-r--r--src/test/bench/msgsend-ring-rw-arcs.rs25
-rw-r--r--src/test/bench/shootout-chameneos-redux.rs2
-rw-r--r--src/test/bench/task-perf-jargon-metal-smoke.rs8
-rw-r--r--src/test/compile-fail/assign-super.rs15
-rw-r--r--src/test/compile-fail/borrowck-assign-comp-idx.rs6
-rw-r--r--src/test/compile-fail/borrowck-loan-vec-content.rs6
-rw-r--r--src/test/compile-fail/borrowck-mut-slice-of-imm-vec.rs2
-rw-r--r--src/test/compile-fail/borrowck-mut-vec-as-imm-slice-bad.rs24
-rw-r--r--src/test/compile-fail/borrowck-vec-pattern-move-tail.rs2
-rw-r--r--src/test/compile-fail/issue-2969.rs2
-rw-r--r--src/test/compile-fail/issue-3243.rs4
-rw-r--r--src/test/compile-fail/lub-in-args.rs3
-rw-r--r--src/test/compile-fail/mutable-huh-variance-box.rs21
-rw-r--r--src/test/compile-fail/mutable-huh-variance-deep.rs20
-rw-r--r--src/test/compile-fail/mutable-huh-variance-ptr.rs26
-rw-r--r--src/test/compile-fail/mutable-huh-variance-unique.rs21
-rw-r--r--src/test/compile-fail/mutable-huh-variance-vec1.rs22
-rw-r--r--src/test/compile-fail/mutable-huh-variance-vec2.rs22
-rw-r--r--src/test/compile-fail/mutable-huh-variance-vec3.rs22
-rw-r--r--src/test/compile-fail/mutable-huh-variance-vec4.rs56
-rw-r--r--src/test/compile-fail/no-send-res-ports.rs7
-rw-r--r--src/test/compile-fail/regions-infer-invariance-due-to-mutability-2.rs2
-rw-r--r--src/test/compile-fail/unique-mut.rs14
-rw-r--r--src/test/compile-fail/vec-add.rs26
-rw-r--r--src/test/run-pass/borrowck-preserve-box-in-uniq.rs2
-rw-r--r--src/test/run-pass/cycle-collection4.rs6
-rw-r--r--src/test/run-pass/explicit-self-closures.rs3
-rw-r--r--src/test/run-pass/intrinsic-atomics.rs2
-rw-r--r--src/test/run-pass/issue-1989.rs17
-rw-r--r--src/test/run-pass/issue-2718.rs14
-rw-r--r--src/test/run-pass/issue-980.rs6
-rw-r--r--src/test/run-pass/pipe-pingpong-bounded.rs19
-rw-r--r--src/test/run-pass/pipe-pingpong-proto.rs19
-rw-r--r--src/test/run-pass/private-method.rs16
-rw-r--r--src/test/run-pass/pure-sum.rs4
-rw-r--r--src/test/run-pass/rcvr-borrowed-to-region.rs2
-rw-r--r--src/test/run-pass/task-killjoin-rsrc.rs7
-rw-r--r--src/test/run-pass/uniq-cc-generic.rs11
-rw-r--r--src/test/run-pass/uniq-cc.rs13
-rw-r--r--src/test/run-pass/unique-assign-copy.rs2
-rw-r--r--src/test/run-pass/unique-decl-init-copy.rs4
-rw-r--r--src/test/run-pass/unique-in-vec-copy.rs2
-rw-r--r--src/test/run-pass/unique-mutable.rs2
71 files changed, 294 insertions, 691 deletions
diff --git a/doc/rust.md b/doc/rust.md
index 975e4bbb8a2..9a3d087f3d7 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -1610,11 +1610,11 @@ The following are examples of structure expressions:
 ~~~~
 # struct Point { x: float, y: float }
 # struct TuplePoint(float, float);
-# mod game { pub struct User { name: &str, age: uint, mut score: uint } }
+# mod game { pub struct User { name: &str, age: uint, score: uint } }
 # use game;
 Point {x: 10f, y: 20f};
 TuplePoint(10f, 20f);
-let u = game::User {name: "Joe", age: 35u, mut score: 100_000};
+let u = game::User {name: "Joe", age: 35u, score: 100_000};
 ~~~~
 
 A structure expression forms a new value of the named structure type.
diff --git a/doc/tutorial-borrowed-ptr.md b/doc/tutorial-borrowed-ptr.md
index c13b2528598..0c1624706bf 100644
--- a/doc/tutorial-borrowed-ptr.md
+++ b/doc/tutorial-borrowed-ptr.md
@@ -348,12 +348,12 @@ mutations:
 ~~~ {.xfail-test}
 fn example3() -> int {
     struct R { g: int }
-    struct S { mut f: ~R }
+    struct S { f: ~R }
 
-    let mut x = ~S {mut f: ~R {g: 3}};
+    let mut x = ~S {f: ~R {g: 3}};
     let y = &x.f.g;
-    x = ~S {mut f: ~R {g: 4}}; // Error reported here.
-    x.f = ~R {g: 5};           // Error reported here.
+    x = ~S {f: ~R {g: 4}};  // Error reported here.
+    x.f = ~R {g: 5};        // Error reported here.
     *y
 }
 ~~~
@@ -362,91 +362,6 @@ In this case, two errors are reported, one when the variable `x` is
 modified and another when `x.f` is modified. Either modification would
 invalidate the pointer `y`.
 
-Things get trickier when the unique box is not uniquely owned by the
-stack frame, or when there is no way for the compiler to determine the
-box's owner. Consider a program like this:
-
-~~~ {.xfail-test}
-struct R { g: int }
-struct S { mut f: ~R }
-fn example5a(x: @S, callback: @fn()) -> int {
-    let y = &x.f.g;   // Error reported here.
-    ...
-    callback();
-    ...
-#   return 0;
-}
-~~~
-
-Here the heap looks something like:
-
-~~~ {.notrust}
-     Stack            Managed Heap       Exchange Heap
-
-  x +------+        +-------------+       +------+
-    | @... | ---->  | mut f: ~... | --+-> | g: 3 |
-  y +------+        +-------------+   |   +------+
-    | &int | -------------------------+
-    +------+
-~~~
-
-In this case, the owning reference to the value being borrowed is
-`x.f`. Moreover, `x.f` is both mutable and *aliasable*. Aliasable
-means that there may be other pointers to that same managed box, so
-even if the compiler were to prove an absence of mutations to `x.f`,
-code could mutate `x.f` indirectly by changing an alias of
-`x`. Therefore, to be safe, the compiler only accepts *pure* actions
-during the lifetime of `y`. We define what "pure" means in the section
-on [purity](#purity).
-
-Besides ensuring purity, the only way to borrow the interior of a
-unique found in aliasable memory is to ensure that the borrowed field
-itself is also unique, as in the following example:
-
-~~~
-struct R { g: int }
-struct S { f: ~R }
-fn example5b(x: @S) -> int {
-    let y = &x.f.g;
-    ...
-# return 0;
-}
-~~~
-
-Here, the field `f` is not declared as mutable. But that is enough for
-the compiler to know that, even if aliases to `x` exist, the field `f`
-cannot be changed and hence the unique box `g` will remain valid.
-
-If you do have a unique box in a mutable field, and you wish to borrow
-it, one option is to use the swap operator to move that unique box
-onto your stack:
-
-~~~
-struct R { g: int }
-struct S { mut f: ~R }
-fn example5c(x: @S) -> int {
-    let mut v = ~R {g: 0};
-    v <-> x.f;         // Swap v and x.f
-    { // Block constrains the scope of `y`:
-        let y = &v.g;
-        ...
-    }
-    x.f = v;          // Replace x.f
-    ...
-# return 0;
-}
-~~~
-
-Of course, this has the side effect of modifying your managed box for
-the duration of the borrow, so it only works when you know that you
-won't be accessing that same box for the duration of the loan. Also,
-it is sometimes necessary to introduce additional blocks to constrain
-the scope of the loan.  In this example, the borrowed pointer `y`
-would still be in scope when you moved the value `v` back into `x.f`,
-and hence moving `v` would be considered illegal.  You cannot move
-values if they are the targets of valid outstanding loans. Introducing
-the block restricts the scope of `y`, making the move legal.
-
 # Borrowing and enums
 
 The previous example showed that the type system forbids any borrowing
@@ -558,11 +473,6 @@ permit `ref` bindings into data owned by the stack frame even if the
 data are mutable, but otherwise it requires that the data reside in
 immutable memory.
 
-> ***Note:*** Right now, pattern bindings not explicitly annotated
-> with `ref` or `copy` use a special mode of "implicit by reference".
-> This is changing as soon as we finish updating all the existing code
-> in the compiler that relies on the current settings.
-
 # Returning borrowed pointers
 
 So far, all of the examples we've looked at use borrowed pointers in a
@@ -745,69 +655,6 @@ fn select<T>(shape: &Shape, threshold: float,
 
 This is equivalent to the previous definition.
 
-# Purity
-
-As mentioned before, the Rust compiler offers a kind of escape hatch
-that permits borrowing of any data, as long as the actions that occur
-during the lifetime of the borrow are pure. Pure actions are those
-that only modify data owned by the current stack frame. The compiler
-can therefore permit arbitrary pointers into the heap, secure in the
-knowledge that no pure action will ever cause them to become
-invalidated (the compiler must still track data on the stack which is
-borrowed and enforce those rules normally, of course). A pure function
-in Rust is referentially transparent: it returns the same results
-given the same (observably equivalent) inputs. That is because while
-pure functions are allowed to modify data, they may only modify
-*stack-local* data, which cannot be observed outside the scope of the
-function itself. (Using an `unsafe` block invalidates this guarantee.)
-
-Let’s revisit a previous example and show how purity can affect
-typechecking. Here is `example5a()`, which borrows the interior of a
-unique box found in an aliasable, mutable location, only now we’ve
-replaced the `...` with some specific code:
-
-~~~
-struct R { g: int }
-struct S { mut f: ~R }
-fn example5a(x: @S ...) -> int {
-    let y = &x.f.g;   // Unsafe
-    *y + 1        
-}
-~~~
-
-The new code simply returns an incremented version of `y`. This code
-clearly doesn't mutate the heap, so the compiler is satisfied.
-
-But suppose we wanted to pull the increment code into a helper, like
-this:
-
-~~~
-fn add_one(x: &int) -> int { *x + 1 }
-~~~
-
-We can now update `example5a()` to use `add_one()`:
-
-~~~
-# struct R { g: int }
-# struct S { mut f: ~R }
-# pure fn add_one(x: &int) -> int { *x + 1 }
-fn example5a(x: @S ...) -> int {
-    let y = &x.f.g;
-    add_one(y)        // Error reported here
-}
-~~~
-
-But now the compiler will report an error again. The reason is that it
-only considers one function at a time (like most typecheckers), and
-so it does not know that `add_one()` consists of pure code. We can
-help the compiler by labeling `add_one()` as pure:
-
-~~~
-pure fn add_one(x: &int) -> int { *x + 1 }
-~~~
-
-With this change, the modified version of `example5a()` will again compile.
-
 # Conclusion
 
 So there you have it: a (relatively) brief tour of the borrowed pointer
diff --git a/doc/tutorial-ffi.md b/doc/tutorial-ffi.md
index c3def1f4b27..b7659376ed6 100644
--- a/doc/tutorial-ffi.md
+++ b/doc/tutorial-ffi.md
@@ -220,21 +220,21 @@ extern mod std;
 use libc::c_ulonglong;
 
 struct timeval {
-    mut tv_sec: c_ulonglong,
-    mut tv_usec: c_ulonglong
+    tv_sec: c_ulonglong,
+    tv_usec: c_ulonglong
 }
 
 #[nolink]
 extern mod lib_c {
-    fn gettimeofday(tv: *timeval, tz: *()) -> i32;
+    fn gettimeofday(tv: *mut timeval, tz: *()) -> i32;
 }
 fn unix_time_in_microseconds() -> u64 {
     unsafe {
-        let x = timeval {
-            mut tv_sec: 0 as c_ulonglong,
-            mut tv_usec: 0 as c_ulonglong
+        let mut x = timeval {
+            tv_sec: 0 as c_ulonglong,
+            tv_usec: 0 as c_ulonglong
         };
-        lib_c::gettimeofday(ptr::addr_of(&x), ptr::null());
+        lib_c::gettimeofday(&mut x, ptr::null());
         return (x.tv_sec as u64) * 1000_000_u64 + (x.tv_usec as u64);
     }
 }
diff --git a/doc/tutorial.md b/doc/tutorial.md
index 41895ebed7c..909bad9e2f4 100644
--- a/doc/tutorial.md
+++ b/doc/tutorial.md
@@ -583,19 +583,16 @@ Inherited mutability means that any field of a struct may be mutable, if the
 struct is in a mutable slot (or a field of a struct in a mutable slot, and
 so forth).
 
-A struct that is not mutable due to inherited mutability may declare some
-of its fields nevertheless mutable, using the `mut` keyword.
-
 ~~~~
 struct Stack {
     content: ~[int],
-    mut head: uint
+    head: uint
 }
 ~~~~
 
-With a value of such a type, you can do `mystack.head += 1`. If `mut` were
-omitted from the type, such an assignment to a struct without inherited
-mutability would result in a type error.
+With a value (say, `mystack`) of such a type in a mutable location, you can do
+`mystack.head += 1`. But in an immutable location, such an assignment to a
+struct without inherited mutability would result in a type error.
 
 `match` patterns destructure structs. The basic syntax is
 `Name { fieldname: pattern, ... }`:
@@ -938,19 +935,19 @@ type that contains managed boxes or other managed types.
 ~~~
 // A linked list node
 struct Node {
-    mut next: MaybeNode,
-    mut prev: MaybeNode,
+    next: MaybeNode,
+    prev: MaybeNode,
     payload: int
 }
 
 enum MaybeNode {
-    SomeNode(@Node),
+    SomeNode(@mut Node),
     NoNode
 }
 
-let node1 = @Node { next: NoNode, prev: NoNode, payload: 1 };
-let node2 = @Node { next: NoNode, prev: NoNode, payload: 2 };
-let node3 = @Node { next: NoNode, prev: NoNode, payload: 3 };
+let node1 = @mut Node { next: NoNode, prev: NoNode, payload: 1 };
+let node2 = @mut Node { next: NoNode, prev: NoNode, payload: 2 };
+let node3 = @mut Node { next: NoNode, prev: NoNode, payload: 3 };
 
 // Link the three list nodes together
 node1.next = SomeNode(node2);
@@ -2300,8 +2297,8 @@ mod farm {
 # impl Human { fn rest(&self) { } }
 # pub fn make_me_a_farm() -> farm::Farm { farm::Farm { chickens: ~[], cows: ~[], farmer: Human(0) } }
     pub struct Farm {
-        priv mut chickens: ~[Chicken],
-        priv mut cows: ~[Cow],
+        priv chickens: ~[Chicken],
+        priv cows: ~[Cow],
         farmer: Human
     }
 
diff --git a/src/libstd/cell.rs b/src/libcore/cell.rs
index c8121daddab..5887df6802f 100644
--- a/src/libstd/cell.rs
+++ b/src/libcore/cell.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::option;
-use core::prelude::*;
+use option;
+use prelude::*;
 
 /// A dynamic, mutable location.
 ///
diff --git a/src/libcore/core.rc b/src/libcore/core.rc
index 01669557389..ed18388f578 100644
--- a/src/libcore/core.rc
+++ b/src/libcore/core.rc
@@ -51,6 +51,7 @@ Implicitly, all crates behave as if they included the following prologue:
 #[warn(vecs_implicitly_copyable)];
 #[deny(non_camel_case_types)];
 #[allow(deprecated_self)];
+#[allow(deprecated_mutable_fields)];
 
 /* The Prelude. */
 
@@ -142,6 +143,7 @@ pub mod dlist;
 #[path="iter-trait.rs"] #[merge = "iter-trait/dlist.rs"]
 pub mod dlist_iter;
 pub mod hashmap;
+pub mod cell;
 
 
 /* Tasks and communication */
diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs
index 94c0a567f4c..15a6e700ffd 100644
--- a/src/libcore/pipes.rs
+++ b/src/libcore/pipes.rs
@@ -86,6 +86,7 @@ bounded and unbounded protocols allows for less code duplication.
 
 use cmp::Eq;
 use cast::{forget, reinterpret_cast, transmute};
+use cell::Cell;
 use either::{Either, Left, Right};
 use kinds::Owned;
 use libc;
@@ -917,11 +918,9 @@ pub fn spawn_service<T:Owned,Tb:Owned>(
 
     // This is some nasty gymnastics required to safely move the pipe
     // into a new task.
-    let server = ~mut Some(server);
-    do task::spawn || {
-        let mut server_ = None;
-        server_ <-> *server;
-        service(option::unwrap(server_))
+    let server = Cell(server);
+    do task::spawn {
+        service(server.take());
     }
 
     client
@@ -941,11 +940,9 @@ pub fn spawn_service_recv<T:Owned,Tb:Owned>(
 
     // This is some nasty gymnastics required to safely move the pipe
     // into a new task.
-    let server = ~mut Some(server);
-    do task::spawn || {
-        let mut server_ = None;
-        server_ <-> *server;
-        service(option::unwrap(server_))
+    let server = Cell(server);
+    do task::spawn {
+        service(server.take())
     }
 
     client
diff --git a/src/libcore/private.rs b/src/libcore/private.rs
index 280eb14b172..2580efe6d09 100644
--- a/src/libcore/private.rs
+++ b/src/libcore/private.rs
@@ -107,10 +107,14 @@ fn compare_and_swap(address: &mut int, oldval: int, newval: int) -> bool {
  * Shared state & exclusive ARC
  ****************************************************************************/
 
+struct UnwrapProtoInner {
+    contents: Option<(comm::ChanOne<()>,  comm::PortOne<bool>)>,
+}
+
 // An unwrapper uses this protocol to communicate with the "other" task that
 // drops the last refcount on an arc. Unfortunately this can't be a proper
 // pipe protocol because the unwrapper has to access both stages at once.
-type UnwrapProto = ~mut Option<(comm::ChanOne<()>,  comm::PortOne<bool>)>;
+type UnwrapProto = ~UnwrapProtoInner;
 
 struct ArcData<T> {
     mut count:     libc::intptr_t,
@@ -139,9 +143,10 @@ struct ArcDestruct<T> {
                     // reference. In effect, being here means we're the only
                     // *awake* task with the data.
                     if data.unwrapper != 0 {
-                        let p: UnwrapProto =
+                        let mut p: UnwrapProto =
                             cast::reinterpret_cast(&data.unwrapper);
-                        let (message, response) = option::swap_unwrap(p);
+                        let (message, response) =
+                            option::swap_unwrap(&mut p.contents);
                         // Send 'ready' and wait for a response.
                         comm::send_one(message, ());
                         // Unkillable wait. Message guaranteed to come.
@@ -196,7 +201,9 @@ pub unsafe fn unwrap_shared_mutable_state<T:Owned>(rc: SharedMutableState<T>)
         let ptr: ~ArcData<T> = cast::reinterpret_cast(&rc.data);
         let (p1,c1) = comm::oneshot(); // ()
         let (p2,c2) = comm::oneshot(); // bool
-        let server: UnwrapProto = ~mut Some((c1,p2));
+        let mut server: UnwrapProto = ~UnwrapProtoInner {
+            contents: Some((c1,p2))
+        };
         let serverp: int = cast::transmute(server);
         // Try to put our server end in the unwrapper slot.
         if compare_and_swap(&mut ptr.unwrapper, 0, serverp) {
@@ -409,8 +416,9 @@ pub fn unwrap_exclusive<T:Owned>(arc: Exclusive<T>) -> T {
 pub mod tests {
     use core::option::{None, Some};
 
-    use option;
+    use cell::Cell;
     use comm;
+    use option;
     use private::{exclusive, unwrap_exclusive};
     use result;
     use task;
@@ -423,7 +431,7 @@ pub mod tests {
         let num_tasks = 10;
         let count = 10;
 
-        let total = exclusive(~mut 0);
+        let total = exclusive(~0);
 
         for uint::range(0, num_tasks) |_i| {
             let total = total.clone();
@@ -472,9 +480,9 @@ pub mod tests {
     #[test]
     pub fn exclusive_unwrap_contended() {
         let x = exclusive(~~"hello");
-        let x2 = ~mut Some(x.clone());
-        do task::spawn || {
-            let x2 = option::swap_unwrap(x2);
+        let x2 = Cell(x.clone());
+        do task::spawn {
+            let x2 = x2.take();
             do x2.with |_hello| { }
             task::yield();
         }
@@ -482,11 +490,10 @@ pub mod tests {
 
         // Now try the same thing, but with the child task blocking.
         let x = exclusive(~~"hello");
-        let x2 = ~mut Some(x.clone());
+        let x2 = Cell(x.clone());
         let mut res = None;
-        do task::task().future_result(|+r| res = Some(r)).spawn
-              || {
-            let x2 = option::swap_unwrap(x2);
+        do task::task().future_result(|+r| res = Some(r)).spawn {
+            let x2 = x2.take();
             assert unwrap_exclusive(x2) == ~~"hello";
         }
         // Have to get rid of our reference before blocking.
@@ -498,11 +505,10 @@ pub mod tests {
     #[test] #[should_fail] #[ignore(cfg(windows))]
     pub fn exclusive_unwrap_conflict() {
         let x = exclusive(~~"hello");
-        let x2 = ~mut Some(x.clone());
+        let x2 = Cell(x.clone());
         let mut res = None;
-        do task::task().future_result(|+r| res = Some(r)).spawn
-           || {
-            let x2 = option::swap_unwrap(x2);
+        do task::task().future_result(|+r| res = Some(r)).spawn {
+            let x2 = x2.take();
             assert unwrap_exclusive(x2) == ~~"hello";
         }
         assert unwrap_exclusive(x) == ~~"hello";
diff --git a/src/libcore/private/weak_task.rs b/src/libcore/private/weak_task.rs
index f3df8ce72f1..8445638850c 100644
--- a/src/libcore/private/weak_task.rs
+++ b/src/libcore/private/weak_task.rs
@@ -18,16 +18,17 @@ it is running, sending a notification to the task that the runtime
 is trying to shut down.
 */
 
+use cell::Cell;
+use comm::{GenericSmartChan, stream};
+use comm::{Port, Chan, SharedChan, GenericChan, GenericPort};
+use hashmap::linear::LinearMap;
+use ops::Drop;
 use option::{Some, None, swap_unwrap};
 use private::at_exit::at_exit;
-use private::global::global_data_clone_create;
 use private::finally::Finally;
-use comm::{Port, Chan, SharedChan, GenericChan,
-           GenericPort, GenericSmartChan, stream};
-use task::{Task, task, spawn};
+use private::global::global_data_clone_create;
 use task::rt::{task_id, get_task_id};
-use hashmap::linear::LinearMap;
-use ops::Drop;
+use task::{Task, task, spawn};
 
 type ShutdownMsg = ();
 
@@ -37,14 +38,13 @@ pub unsafe fn weaken_task(f: &fn(Port<ShutdownMsg>)) {
     let service = global_data_clone_create(global_data_key,
                                            create_global_service);
     let (shutdown_port, shutdown_chan) = stream::<ShutdownMsg>();
-    let shutdown_port = ~mut Some(shutdown_port);
+    let shutdown_port = Cell(shutdown_port);
     let task = get_task_id();
     // Expect the weak task service to be alive
     assert service.try_send(RegisterWeakTask(task, shutdown_chan));
     unsafe { rust_dec_kernel_live_count(); }
     do fn&() {
-        let shutdown_port = swap_unwrap(&mut *shutdown_port);
-        f(shutdown_port)
+        f(shutdown_port.take())
     }.finally || {
         unsafe { rust_inc_kernel_live_count(); }
         // Service my have already exited
@@ -67,16 +67,15 @@ fn create_global_service() -> ~WeakTaskService {
 
     debug!("creating global weak task service");
     let (port, chan) = stream::<ServiceMsg>();
-    let port = ~mut Some(port);
+    let port = Cell(port);
     let chan = SharedChan(chan);
     let chan_clone = chan.clone();
 
     do task().unlinked().spawn {
         debug!("running global weak task service");
-        let port = swap_unwrap(&mut *port);
-        let port = ~mut Some(port);
+        let port = Cell(port.take());
         do fn&() {
-            let port = swap_unwrap(&mut *port);
+            let port = port.take();
             // The weak task service is itself a weak task
             debug!("weakening the weak service task");
             unsafe { rust_dec_kernel_live_count(); }
diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs
index 7f1687b0860..4c3abb09756 100644
--- a/src/libcore/repr.rs
+++ b/src/libcore/repr.rs
@@ -602,7 +602,6 @@ fn test_repr() {
     exact_test(&(@10), "@10");
     exact_test(&(@mut 10), "@10");
     exact_test(&(~10), "~10");
-    exact_test(&(~mut 10), "~mut 10");
     exact_test(&(&10), "&10");
     let mut x = 10;
     exact_test(&(&mut x), "&mut 10");
diff --git a/src/libcore/task/mod.rs b/src/libcore/task/mod.rs
index 336e686193b..2a640e4bf8c 100644
--- a/src/libcore/task/mod.rs
+++ b/src/libcore/task/mod.rs
@@ -34,6 +34,7 @@
  */
 
 use cast;
+use cell::Cell;
 use cmp;
 use cmp::Eq;
 use iter;
@@ -397,9 +398,9 @@ impl TaskBuilder {
     }
     /// Runs a task, while transfering ownership of one argument to the child.
     fn spawn_with<A:Owned>(arg: A, f: fn~(v: A)) {
-        let arg = ~mut Some(arg);
-        do self.spawn || {
-            f(option::swap_unwrap(arg))
+        let arg = Cell(arg);
+        do self.spawn {
+            f(arg.take());
         }
     }
 
diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs
index e77af820079..5110f70ff11 100644
--- a/src/libcore/task/spawn.rs
+++ b/src/libcore/task/spawn.rs
@@ -73,6 +73,7 @@
 #[doc(hidden)]; // FIXME #3538
 
 use cast;
+use cell::Cell;
 use container::Map;
 use option;
 use comm::{Chan, GenericChan, GenericPort, Port, stream};
@@ -530,11 +531,11 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) {
         gen_child_taskgroup(opts.linked, opts.supervised);
 
     unsafe {
-        let child_data = ~mut Some((child_tg, ancestors, f));
+        let child_data = Cell((child_tg, ancestors, f));
         // Being killed with the unsafe task/closure pointers would leak them.
         do unkillable {
             // Agh. Get move-mode items into the closure. FIXME (#2829)
-            let (child_tg, ancestors, f) = option::swap_unwrap(child_data);
+            let (child_tg, ancestors, f) = child_data.take();
             // Create child task.
             let new_task = match opts.sched.mode {
                 DefaultScheduler => rt::new_task(),
@@ -571,10 +572,10 @@ pub fn spawn_raw(opts: TaskOpts, f: fn~()) {
                           ancestors: AncestorList, is_main: bool,
                           notify_chan: Option<Chan<TaskResult>>,
                           f: fn~()) -> fn~() {
-        let child_data = ~mut Some((child_arc, ancestors));
+        let child_data = Cell((child_arc, ancestors));
         return fn~() {
             // Agh. Get move-mode items into the closure. FIXME (#2829)
-            let mut (child_arc, ancestors) = option::swap_unwrap(child_data);
+            let mut (child_arc, ancestors) = child_data.take();
             // Child task runs this code.
 
             // Even if the below code fails to kick the child off, we must
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index a25bc84f8a2..f4c3a1e8d12 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -80,6 +80,7 @@ pub enum lint {
     type_limits,
     default_methods,
     deprecated_self,
+    deprecated_mutable_fields,
 
     managed_heap_memory,
     owned_heap_memory,
@@ -254,6 +255,13 @@ pub fn get_lint_dict() -> LintDict {
             default: warn
          }),
 
+        (@~"deprecated_mutable_fields",
+         @LintSpec {
+            lint: deprecated_mutable_fields,
+            desc: "deprecated mutable fields in structures",
+            default: deny
+        }),
+
         /* FIXME(#3266)--make liveness warnings lintable
         (@~"unused_variable",
          @LintSpec {
@@ -486,6 +494,7 @@ fn check_item(i: @ast::item, cx: ty::ctxt) {
     check_item_type_limits(cx, i);
     check_item_default_methods(cx, i);
     check_item_deprecated_self(cx, i);
+    check_item_deprecated_mutable_fields(cx, i);
 }
 
 // Take a visitor, and modify it so that it will not proceed past subitems.
@@ -703,6 +712,26 @@ fn check_item_deprecated_self(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_structural_records(cx: ty::ctxt, it: @ast::item) {
     let visit = item_stopping_visitor(
         visit::mk_simple_visitor(@visit::SimpleVisitor {
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 75bf7cf2609..96aa41f7809 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -667,8 +667,8 @@ struct Liveness {
     tcx: ty::ctxt,
     ir: @mut IrMaps,
     s: Specials,
-    successors: ~[mut LiveNode],
-    users: ~[mut Users],
+    successors: @mut ~[LiveNode],
+    users: @mut ~[Users],
     // The list of node IDs for the nested loop scopes
     // we're in.
     loop_scope: DVec<node_id>,
@@ -684,14 +684,9 @@ fn Liveness(ir: @mut IrMaps, specials: Specials) -> Liveness {
         ir: ir,
         tcx: ir.tcx,
         s: specials,
-        successors:
-            vec::cast_to_mut(
-                vec::from_elem(ir.num_live_nodes,
-                               invalid_node())),
-        users:
-            vec::cast_to_mut(
-                vec::from_elem(ir.num_live_nodes * ir.num_vars,
-                               invalid_users())),
+        successors: @mut vec::from_elem(ir.num_live_nodes, invalid_node()),
+        users: @mut vec::from_elem(ir.num_live_nodes * ir.num_vars,
+                                   invalid_users()),
         loop_scope: DVec(),
         break_ln: HashMap(),
         cont_ln: HashMap()
@@ -916,12 +911,13 @@ impl Liveness {
 
         let mut changed = false;
         do self.indices2(ln, succ_ln) |idx, succ_idx| {
-            changed |= copy_if_invalid(copy self.users[succ_idx].reader,
-                                       &mut self.users[idx].reader);
-            changed |= copy_if_invalid(copy self.users[succ_idx].writer,
-                                       &mut self.users[idx].writer);
-            if self.users[succ_idx].used && !self.users[idx].used {
-                self.users[idx].used = true;
+            let users = &mut *self.users;
+            changed |= copy_if_invalid(copy users[succ_idx].reader,
+                                       &mut users[idx].reader);
+            changed |= copy_if_invalid(copy users[succ_idx].writer,
+                                       &mut users[idx].writer);
+            if users[succ_idx].used && !users[idx].used {
+                users[idx].used = true;
                 changed = true;
             }
         }
@@ -956,7 +952,8 @@ impl Liveness {
     // Either read, write, or both depending on the acc bitset
     fn acc(&self, ln: LiveNode, var: Variable, acc: uint) {
         let idx = self.idx(ln, var);
-        let user = &mut self.users[idx];
+        let users = &mut *self.users;
+        let user = &mut users[idx];
 
         if (acc & ACC_WRITE) != 0 {
             user.reader = invalid_node();
@@ -970,7 +967,7 @@ impl Liveness {
         }
 
         if (acc & ACC_USE) != 0 {
-            self.users[idx].used = true;
+            user.used = true;
         }
 
         debug!("%s accesses[%x] %s: %s",
diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs
index 3013f928b75..2fc7497f5e3 100644
--- a/src/librustc/middle/trans/type_use.rs
+++ b/src/librustc/middle/trans/type_use.rs
@@ -51,7 +51,7 @@ pub const use_tydesc: uint = 2u; /* Takes the tydesc, or compares */
 
 pub struct Context {
     ccx: @CrateContext,
-    uses: ~[mut type_uses]
+    uses: @mut ~[type_uses]
 }
 
 pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint)
@@ -72,7 +72,7 @@ pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint)
 
     let cx = Context {
         ccx: ccx,
-        uses: vec::cast_to_mut(vec::from_elem(n_tps, 0u))
+        uses: @mut vec::from_elem(n_tps, 0u)
     };
     match ty::get(ty::lookup_item_type(cx.ccx.tcx, fn_id).ty).sty {
         ty::ty_bare_fn(ty::BareFnTy {sig: ref sig, _}) |
@@ -90,7 +90,7 @@ pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint)
     }
 
     if fn_id_loc.crate != local_crate {
-        let uses = vec::cast_from_mut(copy cx.uses);
+        let uses = copy *cx.uses;
         ccx.type_use_cache.insert(fn_id, copy uses);
         return uses;
     }
@@ -175,16 +175,16 @@ pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint)
                                 ccx.tcx.sess.parse_sess.interner)));
       }
     }
-    let uses = vec::cast_from_mut(copy cx.uses);
-    // XXX: Bad copy, use @vec instead?
+    // XXX: Bad copies, use @vec instead?
+    let uses = copy *cx.uses;
     ccx.type_use_cache.insert(fn_id, copy uses);
     uses
 }
 
 pub fn type_needs(cx: Context, use_: uint, ty: ty::t) {
     // Optimization -- don't descend type if all params already have this use
-    for vec::each_mut(cx.uses) |u| {
-        if *u & use_ != use_ {
+    for uint::range(0, cx.uses.len()) |i| {
+        if cx.uses[i] & use_ != use_ {
             type_needs_inner(cx, use_, ty, @Nil);
             return;
         }
diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs
index 9269752b8ec..d0affaa1702 100644
--- a/src/librustc/middle/typeck/astconv.rs
+++ b/src/librustc/middle/typeck/astconv.rs
@@ -216,7 +216,8 @@ pub fn ast_ty_to_ty<AC:AstConv,RS:region_scope + Copy + Durable>(
         match a_seq_ty.ty.node {
             ast::ty_vec(mt) => {
                 let mut mt = ast_mt_to_mt(self, rscope, mt);
-                if a_seq_ty.mutbl == ast::m_mutbl {
+                if a_seq_ty.mutbl == ast::m_mutbl ||
+                        a_seq_ty.mutbl == ast::m_const {
                     mt = ty::mt { ty: mt.ty, mutbl: ast::m_mutbl };
                 }
                 return ty::mk_evec(tcx, mt, vst);
diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs
index cc5e860715d..ee598686652 100644
--- a/src/librustc/middle/typeck/infer/region_inference.rs
+++ b/src/librustc/middle/typeck/infer/region_inference.rs
@@ -549,6 +549,7 @@ use syntax::codemap;
 use util::common::indenter;
 use util::ppaux::note_and_explain_region;
 
+use core::cell::{Cell, empty_cell};
 use core::cmp;
 use core::dvec::DVec;
 use core::to_bytes;
@@ -557,7 +558,6 @@ use core::vec;
 use result::Result;
 use result::{Ok, Err};
 use std::oldmap::HashMap;
-use std::cell::{Cell, empty_cell};
 use std::list::{List, Nil, Cons};
 use syntax::codemap::span;
 use syntax::codemap;
diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc
index 01758a1845d..251e21578a5 100644
--- a/src/librustc/rustc.rc
+++ b/src/librustc/rustc.rc
@@ -314,8 +314,8 @@ fails without recording a fatal error then we've encountered a compiler
 bug and need to present an error.
 */
 pub fn monitor(+f: fn~(diagnostic::Emitter)) {
+    use core::cell::Cell;
     use core::comm::*;
-    use std::cell::Cell;
     let (p, ch) = stream();
     let ch = SharedChan(ch);
     let ch_capture = ch.clone();
diff --git a/src/librustdoc/astsrv.rs b/src/librustdoc/astsrv.rs
index fff2e189eb8..1c45fdafa18 100644
--- a/src/librustdoc/astsrv.rs
+++ b/src/librustdoc/astsrv.rs
@@ -21,8 +21,8 @@ use core::prelude::*;
 
 use parse;
 use util;
-use std::cell::Cell;
 
+use core::cell::Cell;
 use core::comm::{stream, Chan, SharedChan, Port};
 use core::vec;
 use core::ops::Drop;
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index e904015e419..11a1b9f3576 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -10,6 +10,7 @@
 
 use core::prelude::*;
 
+use core::cell::Cell;
 use core::cmp;
 use core::os;
 use core::result;
@@ -18,7 +19,6 @@ use core::run::ProgramOutput;
 use core::vec;
 use core::result::Result;
 use std::getopts;
-use std::cell::Cell;
 
 /// The type of document to output
 pub enum OutputFormat {
diff --git a/src/librustdoc/markdown_pass.rs b/src/librustdoc/markdown_pass.rs
index ff9faabaec2..f64f365496d 100644
--- a/src/librustdoc/markdown_pass.rs
+++ b/src/librustdoc/markdown_pass.rs
@@ -34,11 +34,11 @@ use sort_pass;
 use trim_pass;
 use unindent_pass;
 
+use core::cell::Cell;
 use core::iter;
 use core::str;
 use core::vec;
 use std::par;
-use std::cell::Cell;
 use syntax;
 
 pub fn mk_pass(writer_factory: WriterFactory) -> Pass {
diff --git a/src/librustdoc/text_pass.rs b/src/librustdoc/text_pass.rs
index b9dbe523fdd..83f35418b0b 100644
--- a/src/librustdoc/text_pass.rs
+++ b/src/librustdoc/text_pass.rs
@@ -20,8 +20,8 @@ use fold;
 use pass::Pass;
 use util::NominalOp;
 
+use core::cell::Cell;
 use std::par;
-use std::cell::Cell;
 
 pub fn mk_pass(name: ~str, op: @fn(&str) -> ~str) -> Pass {
     let op = Cell(op);
diff --git a/src/libstd/std.rc b/src/libstd/std.rc
index 1ece8c17ff7..854abfdd112 100644
--- a/src/libstd/std.rc
+++ b/src/libstd/std.rc
@@ -29,6 +29,7 @@ not required in or otherwise suitable for the core library.
 #[allow(vecs_implicitly_copyable)];
 #[deny(non_camel_case_types)];
 #[allow(deprecated_self)];
+#[allow(deprecated_mutable_fields)];
 
 #[no_core];
 
@@ -53,7 +54,6 @@ pub mod uv_global_loop;
 
 pub mod c_vec;
 pub mod timer;
-pub mod cell;
 pub mod io_util;
 
 // Concurrency
diff --git a/src/libsyntax/ext/auto_encode.rs b/src/libsyntax/ext/auto_encode.rs
index 7fbba987cc7..b345b116425 100644
--- a/src/libsyntax/ext/auto_encode.rs
+++ b/src/libsyntax/ext/auto_encode.rs
@@ -1176,9 +1176,9 @@ mod test {
         // all of the ones I was too lazy to handle:
         CallToOther
     }
-    // using a mutable field rather than changing the
+    // using `@mut` rather than changing the
     // type of self in every method of every encoder everywhere.
-    pub struct TestEncoder {mut call_log : ~[call]}
+    pub struct TestEncoder {call_log : @mut ~[call]}
 
     pub impl TestEncoder {
         // these self's should be &mut self's, as well....
@@ -1272,9 +1272,9 @@ mod test {
     struct Node {id: uint}
 
     fn to_call_log (val: Encodable<TestEncoder>) -> ~[call] {
-        let mut te = TestEncoder {call_log: ~[]};
+        let mut te = TestEncoder {call_log: @mut ~[]};
         val.encode(&te);
-        te.call_log
+        copy *te.call_log
     }
 /*
     #[test] fn encode_test () {
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 1ae8786e09b..7b3030124b7 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -48,6 +48,7 @@ pub enum ObsoleteSyntax {
     ObsoleteUnenforcedBound,
     ObsoleteImplSyntax,
     ObsoleteTraitBoundSeparator,
+    ObsoleteMutOwnedPointer,
 }
 
 pub impl to_bytes::IterBytes for ObsoleteSyntax {
@@ -126,6 +127,12 @@ pub impl Parser {
                 "space-separated trait bounds",
                 "write `+` between trait bounds"
             ),
+            ObsoleteMutOwnedPointer => (
+                "mutable owned pointer",
+                "mutability inherits through `~` pointers; place the `~` box
+                 in a mutable location, like a mutable local variable or an \
+                 `@mut` box"
+            ),
         };
 
         self.report(sp, kind, kind_str, desc);
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 853b1408050..af25a4f6e58 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -75,7 +75,7 @@ use parse::obsolete::{ObsoleteMoveInit, ObsoleteBinaryMove};
 use parse::obsolete::{ObsoleteStructCtor, ObsoleteWith};
 use parse::obsolete::{ObsoleteSyntax, ObsoleteLowerCaseKindBounds};
 use parse::obsolete::{ObsoleteUnsafeBlock, ObsoleteImplSyntax};
-use parse::obsolete::{ObsoleteTraitBoundSeparator};
+use parse::obsolete::{ObsoleteTraitBoundSeparator, ObsoleteMutOwnedPointer};
 use parse::prec::{as_prec, token_to_binop};
 use parse::token::{can_begin_expr, is_ident, is_ident_or_path};
 use parse::token::{is_plain_ident, INTERPOLATED, special_idents};
@@ -677,6 +677,11 @@ pub impl Parser {
         // rather than boxed ptrs.  But the special casing of str/vec is not
         // reflected in the AST type.
         let mt = self.parse_mt();
+
+        if mt.mutbl == m_mutbl && sigil == OwnedSigil {
+            self.obsolete(*self.last_span, ObsoleteMutOwnedPointer);
+        }
+
         ctor(mt)
     }
 
diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs
index 9b6fee5e23b..12060a87850 100644
--- a/src/test/bench/msgsend-ring-mutex-arcs.rs
+++ b/src/test/bench/msgsend-ring-mutex-arcs.rs
@@ -19,6 +19,7 @@ extern mod std;
 use std::time;
 use std::arc;
 use std::future;
+use core::cell::Cell;
 
 // A poor man's pipe.
 type pipe = arc::MutexARC<~[uint]>;
@@ -77,7 +78,7 @@ fn main() {
     let msg_per_task = uint::from_str(args[2]).get();
 
     let (num_chan, num_port) = init();
-    let mut num_chan = Some(num_chan);
+    let mut num_chan = Cell(num_chan);
 
     let start = time::precise_time_s();
 
@@ -87,24 +88,19 @@ fn main() {
     for uint::range(1u, num_tasks) |i| {
         //error!("spawning %?", i);
         let (new_chan, num_port) = init();
-        let num_chan2 = ~mut None;
-        *num_chan2 <-> num_chan;
-        let num_port = ~mut Some(num_port);
-        let new_future = do future::spawn() || {
-            let mut num_chan = None;
-            num_chan <-> *num_chan2;
-            let mut num_port1 = None;
-            num_port1 <-> *num_port;
-            thread_ring(i, msg_per_task,
-                        option::unwrap(num_chan),
-                        option::unwrap(num_port1))
+        let num_chan2 = Cell(num_chan.take());
+        let num_port = Cell(num_port);
+        let new_future = do future::spawn() {
+            let num_chan = num_chan2.take();
+            let num_port1 = num_port.take();
+            thread_ring(i, msg_per_task, num_chan, num_port1)
         };
         futures.push(new_future);
-        num_chan = Some(new_chan);
+        num_chan.put_back(new_chan);
     };
 
     // do our iteration
-    thread_ring(0, msg_per_task, option::unwrap(num_chan), num_port);
+    thread_ring(0, msg_per_task, num_chan.take(), num_port);
 
     // synchronize
     for futures.each |f| { f.get() };
diff --git a/src/test/bench/msgsend-ring-pipes.rs b/src/test/bench/msgsend-ring-pipes.rs
index 0f7c41f5997..56a46d3e006 100644
--- a/src/test/bench/msgsend-ring-pipes.rs
+++ b/src/test/bench/msgsend-ring-pipes.rs
@@ -17,10 +17,11 @@
 // This version uses automatically compiled channel contracts.
 
 extern mod std;
-use std::time;
-use std::future;
 
+use core::cell::Cell;
 use core::pipes::recv;
+use std::time;
+use std::future;
 
 proto! ring (
     num:send {
@@ -70,7 +71,7 @@ fn main() {
     let msg_per_task = uint::from_str(args[2]).get();
 
     let (num_chan, num_port) = ring::init();
-    let mut num_chan = Some(num_chan);
+    let mut num_chan = Cell(num_chan);
 
     let start = time::precise_time_s();
 
@@ -80,24 +81,19 @@ fn main() {
     for uint::range(1u, num_tasks) |i| {
         //error!("spawning %?", i);
         let (new_chan, num_port) = ring::init();
-        let num_chan2 = ~mut None;
-        *num_chan2 <-> num_chan;
-        let num_port = ~mut Some(num_port);
+        let num_chan2 = Cell(num_chan.take());
+        let num_port = Cell(num_port);
         let new_future = do future::spawn || {
-            let mut num_chan = None;
-            num_chan <-> *num_chan2;
-            let mut num_port1 = None;
-            num_port1 <-> *num_port;
-            thread_ring(i, msg_per_task,
-                        option::unwrap(num_chan),
-                        option::unwrap(num_port1))
+            let num_chan = num_chan2.take();
+            let num_port1 = num_port.take();
+            thread_ring(i, msg_per_task, num_chan, num_port1)
         };
         futures.push(new_future);
-        num_chan = Some(new_chan);
+        num_chan.put_back(new_chan);
     };
 
     // do our iteration
-    thread_ring(0, msg_per_task, option::unwrap(num_chan), num_port);
+    thread_ring(0, msg_per_task, num_chan.take(), num_port);
 
     // synchronize
     for futures.each |f| { f.get() };
diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs
index eaae8370d6b..57d04abb414 100644
--- a/src/test/bench/msgsend-ring-rw-arcs.rs
+++ b/src/test/bench/msgsend-ring-rw-arcs.rs
@@ -16,6 +16,8 @@
 // This also serves as a pipes test, because ARCs are implemented with pipes.
 
 extern mod std;
+
+use core::cell::Cell;
 use std::time;
 use std::arc;
 use std::future;
@@ -77,7 +79,7 @@ fn main() {
     let msg_per_task = uint::from_str(args[2]).get();
 
     let (num_chan, num_port) = init();
-    let mut num_chan = Some(num_chan);
+    let mut num_chan = Cell(num_chan);
 
     let start = time::precise_time_s();
 
@@ -87,24 +89,19 @@ fn main() {
     for uint::range(1u, num_tasks) |i| {
         //error!("spawning %?", i);
         let (new_chan, num_port) = init();
-        let num_chan2 = ~mut None;
-        *num_chan2 <-> num_chan;
-        let num_port = ~mut Some(num_port);
-        let new_future = do future::spawn || {
-            let mut num_chan = None;
-            num_chan <-> *num_chan2;
-            let mut num_port1 = None;
-            num_port1 <-> *num_port;
-            thread_ring(i, msg_per_task,
-                        option::unwrap(num_chan),
-                        option::unwrap(num_port1))
+        let num_chan2 = Cell(num_chan.take());
+        let num_port = Cell(num_port);
+        let new_future = do future::spawn {
+            let num_chan = num_chan2.take();
+            let num_port1 = num_port.take();
+            thread_ring(i, msg_per_task, num_chan, num_port1)
         };
         futures.push(new_future);
-        num_chan = Some(new_chan);
+        num_chan.put_back(new_chan);
     };
 
     // do our iteration
-    thread_ring(0, msg_per_task, option::unwrap(num_chan), num_port);
+    thread_ring(0, msg_per_task, num_chan.take(), num_port);
 
     // synchronize
     for futures.each |f| { f.get() };
diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs
index 42a1e4b5046..111219974d0 100644
--- a/src/test/bench/shootout-chameneos-redux.rs
+++ b/src/test/bench/shootout-chameneos-redux.rs
@@ -14,7 +14,7 @@ extern mod std;
 use std::oldmap;
 use std::oldmap::HashMap;
 use std::sort;
-use std::cell::Cell;
+use core::cell::Cell;
 use core::comm::*;
 
 fn print_complements() {
diff --git a/src/test/bench/task-perf-jargon-metal-smoke.rs b/src/test/bench/task-perf-jargon-metal-smoke.rs
index 49a06fd491c..9bdc5aae3f2 100644
--- a/src/test/bench/task-perf-jargon-metal-smoke.rs
+++ b/src/test/bench/task-perf-jargon-metal-smoke.rs
@@ -17,13 +17,15 @@
 //
 // The filename is a song reference; google it in quotes.
 
+use core::cell::Cell;
+
 fn child_generation(gens_left: uint, -c: comm::Chan<()>) {
     // This used to be O(n^2) in the number of generations that ever existed.
     // With this code, only as many generations are alive at a time as tasks
     // alive at a time,
-    let c = ~mut Some(c);
-    do task::spawn_supervised || {
-        let c = option::swap_unwrap(c);
+    let c = Cell(c);
+    do task::spawn_supervised {
+        let c = c.take();
         if gens_left & 1 == 1 {
             task::yield(); // shake things up a bit
         }
diff --git a/src/test/compile-fail/assign-super.rs b/src/test/compile-fail/assign-super.rs
deleted file mode 100644
index 17c7ff1bb60..00000000000
--- a/src/test/compile-fail/assign-super.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    let mut x: ~[mut int] = ~[mut 3];
-    let y: ~[int] = ~[3];
-    x = y; //~ ERROR values differ in mutability
-}
diff --git a/src/test/compile-fail/borrowck-assign-comp-idx.rs b/src/test/compile-fail/borrowck-assign-comp-idx.rs
index 21236dc4a83..ded47fc9f7f 100644
--- a/src/test/compile-fail/borrowck-assign-comp-idx.rs
+++ b/src/test/compile-fail/borrowck-assign-comp-idx.rs
@@ -11,7 +11,7 @@
 type point = { x: int, y: int };
 
 fn a() {
-    let mut p = ~[mut 1];
+    let mut p = ~[1];
 
     // Create an immutable pointer into p's contents:
     let _q: &int = &p[0]; //~ NOTE loan of mutable vec content granted here
@@ -25,7 +25,7 @@ fn b() {
     // here we alias the mutable vector into an imm slice and try to
     // modify the original:
 
-    let mut p = ~[mut 1];
+    let mut p = ~[1];
 
     do borrow(p) { //~ NOTE loan of mutable vec content granted here
         p[0] = 5; //~ ERROR assigning to mutable vec content prohibited due to outstanding loan
@@ -35,7 +35,7 @@ fn b() {
 fn c() {
     // Legal because the scope of the borrow does not include the
     // modification:
-    let mut p = ~[mut 1];
+    let mut p = ~[1];
     borrow(p, ||{});
     p[0] = 5;
 }
diff --git a/src/test/compile-fail/borrowck-loan-vec-content.rs b/src/test/compile-fail/borrowck-loan-vec-content.rs
index b0b22dcfe61..8457fce255e 100644
--- a/src/test/compile-fail/borrowck-loan-vec-content.rs
+++ b/src/test/compile-fail/borrowck-loan-vec-content.rs
@@ -17,13 +17,13 @@ fn takes_imm_elt(_v: &int, f: fn()) {
 }
 
 fn has_mut_vec_and_does_not_try_to_change_it() {
-    let v = ~[mut 1, 2, 3];
+    let mut v = ~[1, 2, 3];
     do takes_imm_elt(&v[0]) {
     }
 }
 
 fn has_mut_vec_but_tries_to_change_it() {
-    let v = ~[mut 1, 2, 3];
+    let mut v = ~[1, 2, 3];
     do takes_imm_elt(&v[0]) { //~ NOTE loan of mutable vec content granted here
         v[1] = 4; //~ ERROR assigning to mutable vec content prohibited due to outstanding loan
     }
@@ -34,7 +34,7 @@ fn takes_const_elt(_v: &const int, f: fn()) {
 }
 
 fn has_mut_vec_and_tries_to_change_it() {
-    let v = ~[mut 1, 2, 3];
+    let mut v = ~[1, 2, 3];
     do takes_const_elt(&const v[0]) {
         v[1] = 4;
     }
diff --git a/src/test/compile-fail/borrowck-mut-slice-of-imm-vec.rs b/src/test/compile-fail/borrowck-mut-slice-of-imm-vec.rs
index 51448d6061e..bc0340983ae 100644
--- a/src/test/compile-fail/borrowck-mut-slice-of-imm-vec.rs
+++ b/src/test/compile-fail/borrowck-mut-slice-of-imm-vec.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn write(v: &[mut int]) {
+fn write(v: &mut [int]) {
     v[0] += 1;
 }
 
diff --git a/src/test/compile-fail/borrowck-mut-vec-as-imm-slice-bad.rs b/src/test/compile-fail/borrowck-mut-vec-as-imm-slice-bad.rs
deleted file mode 100644
index 43feb65c8b9..00000000000
--- a/src/test/compile-fail/borrowck-mut-vec-as-imm-slice-bad.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn want_slice(v: &[int]) -> int {
-    let mut sum = 0;
-    for vec::each(v) |i| { sum += *i; }
-    return sum;
-}
-
-fn has_mut_vec(+v: @~[mut int]) -> int {
-    want_slice(*v) //~ ERROR illegal borrow unless pure
-        //~^ NOTE impure due to access to impure function
-}
-
-fn main() {
-    assert has_mut_vec(@~[mut 1, 2, 3]) == 6;
-}
diff --git a/src/test/compile-fail/borrowck-vec-pattern-move-tail.rs b/src/test/compile-fail/borrowck-vec-pattern-move-tail.rs
index 941883f80f9..16b48aedb0c 100644
--- a/src/test/compile-fail/borrowck-vec-pattern-move-tail.rs
+++ b/src/test/compile-fail/borrowck-vec-pattern-move-tail.rs
@@ -1,5 +1,5 @@
 fn main() {
-    let a = [mut 1, 2, 3, 4];
+    let mut a = [1, 2, 3, 4];
     let _ = match a {
         [1, 2, ..tail] => tail,
         _ => core::util::unreachable()
diff --git a/src/test/compile-fail/issue-2969.rs b/src/test/compile-fail/issue-2969.rs
index 5e1b9397247..88c76fb31a1 100644
--- a/src/test/compile-fail/issue-2969.rs
+++ b/src/test/compile-fail/issue-2969.rs
@@ -12,7 +12,7 @@
 fn main()
 {
 // See #2969 -- error message should be improved
-   let mut x = [mut 1, 2, 4];
+   let mut x = [1, 2, 4];
    let v : &int = &x[2];
    x[2] = 6;
    assert *v == 6;
diff --git a/src/test/compile-fail/issue-3243.rs b/src/test/compile-fail/issue-3243.rs
index ac5c099e114..443fae619ba 100644
--- a/src/test/compile-fail/issue-3243.rs
+++ b/src/test/compile-fail/issue-3243.rs
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 // xfail-test
-fn function() -> &[mut int] {
-    let mut x: &static/[mut int] = &[mut 1,2,3];
+fn function() -> &mut [int] {
+    let mut x: &static/mut [int] = &[1,2,3];
     x[0] = 12345;
     x //~ ERROR bad
 }
diff --git a/src/test/compile-fail/lub-in-args.rs b/src/test/compile-fail/lub-in-args.rs
index c2879d7f272..5c71ae38a64 100644
--- a/src/test/compile-fail/lub-in-args.rs
+++ b/src/test/compile-fail/lub-in-args.rs
@@ -11,8 +11,6 @@
 fn two_args<T>(x: T, y: T) { }
 
 fn main() {
-    let x: ~[mut int] = ~[mut 3];
-    let y: ~[int] = ~[3];
     let a: @mut int = @mut 3;
     let b: @int = @3;
 
@@ -22,6 +20,5 @@ fn main() {
     // shortcoming of the current inference algorithm.  These errors
     // are *not* desirable.
 
-    two_args(x, y); //~ ERROR (values differ in mutability)
     two_args(a, b); //~ ERROR (values differ in mutability)
 }
diff --git a/src/test/compile-fail/mutable-huh-variance-box.rs b/src/test/compile-fail/mutable-huh-variance-box.rs
deleted file mode 100644
index 316c832f011..00000000000
--- a/src/test/compile-fail/mutable-huh-variance-box.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern: mismatched types
-
-fn main() {
-    let v = @mut ~[0];
-
-    fn f(&&v: @mut ~[const int]) {
-        *v = ~[mut 3]
-    }
-
-    f(v);
-}
diff --git a/src/test/compile-fail/mutable-huh-variance-deep.rs b/src/test/compile-fail/mutable-huh-variance-deep.rs
deleted file mode 100644
index 4f0c6d7a4c8..00000000000
--- a/src/test/compile-fail/mutable-huh-variance-deep.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern: mismatched types
-
-fn main() {
-    let v = ~[mut @mut ~mut ~[0]];
-
-    fn f(&&v: ~[mut @mut ~mut ~[const int]]) {
-    }
-
-    f(v);
-}
diff --git a/src/test/compile-fail/mutable-huh-variance-ptr.rs b/src/test/compile-fail/mutable-huh-variance-ptr.rs
deleted file mode 100644
index dba6f9ae3fa..00000000000
--- a/src/test/compile-fail/mutable-huh-variance-ptr.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern: mismatched types
-
-extern mod std;
-
-fn main() {
-    let mut a = ~[0];
-    let v: *mut ~[int] = &mut a;
-
-    fn f(&&v: *mut ~[const int]) {
-        unsafe {
-            *v = ~[mut 3]
-        }
-    }
-
-    f(v);
-}
diff --git a/src/test/compile-fail/mutable-huh-variance-unique.rs b/src/test/compile-fail/mutable-huh-variance-unique.rs
deleted file mode 100644
index f2188911346..00000000000
--- a/src/test/compile-fail/mutable-huh-variance-unique.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// error-pattern: mismatched types
-
-fn main() {
-    let v = ~mut ~[0];
-
-    fn f(&&v: ~mut ~[const int]) {
-        *v = ~[mut 3]
-    }
-
-    f(v);
-}
diff --git a/src/test/compile-fail/mutable-huh-variance-vec1.rs b/src/test/compile-fail/mutable-huh-variance-vec1.rs
deleted file mode 100644
index c3f4636f898..00000000000
--- a/src/test/compile-fail/mutable-huh-variance-vec1.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    // Note: explicit type annot is required here
-    // because otherwise the inference gets smart
-    // and assigns a type of ~[mut ~[const int]].
-    let v: ~[mut ~[int]] = ~[mut ~[0]];
-
-    fn f(&&v: ~[mut ~[const int]]) {
-        v[0] = ~[mut 3]
-    }
-
-    f(v); //~ ERROR (values differ in mutability)
-}
diff --git a/src/test/compile-fail/mutable-huh-variance-vec2.rs b/src/test/compile-fail/mutable-huh-variance-vec2.rs
deleted file mode 100644
index aeb06324341..00000000000
--- a/src/test/compile-fail/mutable-huh-variance-vec2.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    // Note: explicit type annot is required here
-    // because otherwise the inference gets smart
-    // and assigns a type of ~[mut ~[const int]].
-    let v: ~[mut ~[mut int]] = ~[mut ~[mut 0]];
-
-    fn f(&&v: ~[mut ~[const int]]) {
-        v[0] = ~[3]
-    }
-
-    f(v); //~ ERROR (values differ in mutability)
-}
diff --git a/src/test/compile-fail/mutable-huh-variance-vec3.rs b/src/test/compile-fail/mutable-huh-variance-vec3.rs
deleted file mode 100644
index edc66536e9b..00000000000
--- a/src/test/compile-fail/mutable-huh-variance-vec3.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-    // Note: explicit type annot is required here
-    // because otherwise the inference gets smart
-    // and assigns a type of ~[mut ~[const int]].
-    let v: ~[mut ~[mut ~[int]]] = ~[mut ~[mut ~[0]]];
-
-    fn f(&&v: ~[mut ~[mut ~[const int]]]) {
-        v[0][1] = ~[mut 3]
-    }
-
-    f(v); //~ ERROR (values differ in mutability)
-}
diff --git a/src/test/compile-fail/mutable-huh-variance-vec4.rs b/src/test/compile-fail/mutable-huh-variance-vec4.rs
deleted file mode 100644
index e0980826a2a..00000000000
--- a/src/test/compile-fail/mutable-huh-variance-vec4.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-fn main() {
-
-    // Note: here we do not have any type annotations
-    // but we do express conflicting requirements:
-
-    let v = ~[mut ~[0]];
-    let w = ~[mut ~[mut 0]];
-    let x = ~[mut ~[mut 0]];
-
-    fn f(&&v: ~[mut ~[int]]) {
-        v[0] = ~[3]
-    }
-
-    fn g(&&v: ~[const ~[const int]]) {
-    }
-
-    fn h(&&v: ~[mut ~[mut int]]) {
-        v[0] = ~[mut 3]
-    }
-
-    fn i(&&v: ~[mut ~[const int]]) {
-        v[0] = ~[mut 3]
-    }
-
-    fn j(&&v: ~[~[const int]]) {
-    }
-
-    f(v);
-    g(v);
-    h(v); //~ ERROR (values differ in mutability)
-    i(v); //~ ERROR (values differ in mutability)
-    j(v); //~ ERROR (values differ in mutability)
-
-    f(w); //~ ERROR (values differ in mutability)
-    g(w);
-    h(w);
-    i(w); //~ ERROR (values differ in mutability)
-    j(w); //~ ERROR (values differ in mutability)
-
-    // Note that without adding f() or h() to the mix, it is valid for
-    // x to have the type ~[mut ~[const int]], and thus we can safely
-    // call g() and i() but not j():
-    g(x);
-    i(x);
-    j(x); //~ ERROR (values differ in mutability)
-}
diff --git a/src/test/compile-fail/no-send-res-ports.rs b/src/test/compile-fail/no-send-res-ports.rs
index 4954bbfa09d..0d7e2d2377c 100644
--- a/src/test/compile-fail/no-send-res-ports.rs
+++ b/src/test/compile-fail/no-send-res-ports.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::cell::Cell;
+
 struct Port<T>(@T);
 
 fn main() {
@@ -25,11 +27,10 @@ fn main() {
         }
     }
 
-    let x = ~mut Some(foo(Port(@())));
+    let x = Cell(foo(Port(@())));
 
     do task::spawn {
-        let mut y = None;
-        *x <-> y; //~ ERROR value has non-owned type
+        let y = x.take();   //~ ERROR value has non-owned type
         log(error, y);
     }
 }
diff --git a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-2.rs b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-2.rs
index 1a20ca23fae..4b637b0195c 100644
--- a/src/test/compile-fail/regions-infer-invariance-due-to-mutability-2.rs
+++ b/src/test/compile-fail/regions-infer-invariance-due-to-mutability-2.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 struct invariant {
-    f: @[mut &int]
+    f: @mut [&int]
 }
 
 fn to_same_lifetime(bi: invariant/&r) {
diff --git a/src/test/compile-fail/unique-mut.rs b/src/test/compile-fail/unique-mut.rs
deleted file mode 100644
index a3a197505a3..00000000000
--- a/src/test/compile-fail/unique-mut.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//error-pattern:mismatched types
-fn main() {
-    let i: ~int = ~mut 0;
-}
diff --git a/src/test/compile-fail/vec-add.rs b/src/test/compile-fail/vec-add.rs
index 0eaf40e110f..0f51d34fc2f 100644
--- a/src/test/compile-fail/vec-add.rs
+++ b/src/test/compile-fail/vec-add.rs
@@ -14,7 +14,7 @@
 // the right hand side in all cases. We are getting compiler errors
 // about this now, so I'm xfailing the test for now. -eholk
 
-fn add(i: ~[int], m: ~[mut int], c: ~[const int]) {
+fn add(i: ~[int], mut m: ~[int], c: ~[const int]) {
 
     // Check that:
     //  (1) vectors of any two mutabilities can be added
@@ -24,9 +24,9 @@ fn add(i: ~[int], m: ~[mut int], c: ~[const int]) {
        m + ~[3],
        ~[3]);
 
-   add(i + ~[mut 3],
-       m + ~[mut 3],
-       ~[mut 3]);
+   add(i + ~[3],
+       m + ~[3],
+       ~[3]);
 
    add(i + i,
        m + i,
@@ -54,19 +54,19 @@ fn add(i: ~[int], m: ~[mut int], c: ~[const int]) {
                 //~^ mismatched types
        ~[3]);
 
-   add(m + ~[mut 3], //~ ERROR mismatched types
-       m + ~[mut 3],
-       m + ~[mut 3]);
+   add(m + ~[3], //~ ERROR mismatched types
+       m + ~[3],
+       m + ~[3]);
 
-   add(i + ~[mut 3],
-       i + ~[mut 3], //~ ERROR mismatched types
-       i + ~[mut 3]);
+   add(i + ~[3],
+       i + ~[3], //~ ERROR mismatched types
+       i + ~[3]);
 
-   add(c + ~[mut 3], //~ ERROR binary operation + cannot be applied
+   add(c + ~[3], //~ ERROR binary operation + cannot be applied
                     //~^ mismatched types
-       c + ~[mut 3], //~ ERROR binary operation + cannot be applied
+       c + ~[3], //~ ERROR binary operation + cannot be applied
                     //~^ mismatched types
-       ~[mut 3]);
+       ~[3]);
 
    add(m + i, //~ ERROR mismatched types
        m + i,
diff --git a/src/test/run-pass/borrowck-preserve-box-in-uniq.rs b/src/test/run-pass/borrowck-preserve-box-in-uniq.rs
index 9724717f2d5..b11a5356f69 100644
--- a/src/test/run-pass/borrowck-preserve-box-in-uniq.rs
+++ b/src/test/run-pass/borrowck-preserve-box-in-uniq.rs
@@ -20,7 +20,7 @@ fn borrow(x: &int, f: fn(x: &int)) {
 struct F { f: ~int }
 
 pub fn main() {
-    let mut x = ~mut @F{f: ~3};
+    let mut x = ~@F{f: ~3};
     do borrow(x.f) |b_x| {
         assert *b_x == 3;
         assert ptr::addr_of(&(*x.f)) == ptr::addr_of(&(*b_x));
diff --git a/src/test/run-pass/cycle-collection4.rs b/src/test/run-pass/cycle-collection4.rs
index 4be43fc1296..8a3139157fd 100644
--- a/src/test/run-pass/cycle-collection4.rs
+++ b/src/test/run-pass/cycle-collection4.rs
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct foo { mut z : fn@() }
+struct foo { z : fn@() }
 
 fn nop() { }
-fn nop_foo(_y: ~[int], _x : @foo) { }
+fn nop_foo(_y: ~[int], _x : @mut foo) { }
 
 pub fn main() {
-    let w = @foo{ z: || nop() };
+    let w = @mut foo{ z: || nop() };
     let x : fn@() = || nop_foo(~[], w);
     w.z = x;
 }
diff --git a/src/test/run-pass/explicit-self-closures.rs b/src/test/run-pass/explicit-self-closures.rs
index 4c12b6ad47c..d40b2f72ae8 100644
--- a/src/test/run-pass/explicit-self-closures.rs
+++ b/src/test/run-pass/explicit-self-closures.rs
@@ -21,9 +21,6 @@ impl Box {
     fn set_many2(@mut self, xs: &[uint]) {
         for xs.each |x| { self.x = *x; }
     }
-    fn set_many3(~mut self, xs: &[uint]) {
-        for xs.each |x| { self.x = *x; }
-    }
 }
 
 pub fn main() {}
diff --git a/src/test/run-pass/intrinsic-atomics.rs b/src/test/run-pass/intrinsic-atomics.rs
index eb10a51c0bd..7d5bf65dad7 100644
--- a/src/test/run-pass/intrinsic-atomics.rs
+++ b/src/test/run-pass/intrinsic-atomics.rs
@@ -29,7 +29,7 @@ extern mod rusti {
 
 pub fn main() {
     unsafe {
-        let x = ~mut 1;
+        let mut x = ~1;
 
         assert rusti::atomic_cxchg(x, 1, 2) == 1;
         assert *x == 2;
diff --git a/src/test/run-pass/issue-1989.rs b/src/test/run-pass/issue-1989.rs
index f941a9002ef..95129851d5b 100644
--- a/src/test/run-pass/issue-1989.rs
+++ b/src/test/run-pass/issue-1989.rs
@@ -12,23 +12,22 @@
 
 enum maybe_pointy {
     none,
-    p(@Pointy)
+    p(@mut Pointy)
 }
 
 struct Pointy {
-    mut a : maybe_pointy,
-    mut f : fn@()->(),
+    a : maybe_pointy,
+    f : fn@()->(),
 }
 
-fn empty_pointy() -> @Pointy {
-    return @Pointy{
-        mut a : none,
-        mut f : fn@()->(){},
+fn empty_pointy() -> @mut Pointy {
+    return @mut Pointy{
+        a : none,
+        f : fn@()->(){},
     }
 }
 
-pub fn main()
-{
+pub fn main() {
     let v = ~[empty_pointy(), empty_pointy()];
     v[0].a = p(v[0]);
 }
diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs
index 249d1c21376..b97ebb04f71 100644
--- a/src/test/run-pass/issue-2718.rs
+++ b/src/test/run-pass/issue-2718.rs
@@ -318,18 +318,16 @@ pub fn main() {
 //    Commented out because of option::get error
 
     let (client_, server_) = pingpong::init();
-    let client_ = ~mut Some(client_);
-    let server_ = ~mut Some(server_);
+    let client_ = Cell(client_);
+    let server_ = Cell(server_);
 
     task::spawn {|client_|
-        let mut client__ = none;
-        *client_ <-> client__;
-        client(option::unwrap(client__));
+        let client__ = client_.take();
+        client(client__);
     };
     task::spawn {|server_|
-        let mut server_ˊ = none;
-        *server_ <-> server_ˊ;
-        server(option::unwrap(server_ˊ));
+        let server__ = server_.take();
+        server(server_ˊ);
     };
   */
 }
diff --git a/src/test/run-pass/issue-980.rs b/src/test/run-pass/issue-980.rs
index 842eabf8fc5..e2e5dfcc7d5 100644
--- a/src/test/run-pass/issue-980.rs
+++ b/src/test/run-pass/issue-980.rs
@@ -10,14 +10,14 @@
 
 enum maybe_pointy {
     no_pointy,
-    yes_pointy(@Pointy),
+    yes_pointy(@mut Pointy),
 }
 
 struct Pointy {
-    mut x : maybe_pointy
+    x : maybe_pointy
 }
 
 pub fn main() {
-    let m = @Pointy { mut x : no_pointy };
+    let m = @mut Pointy { x : no_pointy };
     m.x = yes_pointy(m);
 }
diff --git a/src/test/run-pass/pipe-pingpong-bounded.rs b/src/test/run-pass/pipe-pingpong-bounded.rs
index 2ada6df76a6..2b270a54d80 100644
--- a/src/test/run-pass/pipe-pingpong-bounded.rs
+++ b/src/test/run-pass/pipe-pingpong-bounded.rs
@@ -14,6 +14,7 @@
 // experiment with what code the compiler should generate for bounded
 // protocols.
 
+use core::cell::Cell;
 
 // This was generated initially by the pipe compiler, but it's been
 // modified in hopefully straightforward ways.
@@ -111,16 +112,14 @@ mod test {
 
 pub fn main() {
     let (client_, server_) = ::pingpong::init();
-    let client_ = ~mut Some(client_);
-    let server_ = ~mut Some(server_);
-    do task::spawn || {
-        let mut client__ = None;
-        *client_ <-> client__;
-        test::client(option::unwrap(client__));
+    let client_ = Cell(client_);
+    let server_ = Cell(server_);
+    do task::spawn {
+        let client__ = client_.take();
+        test::client(client__);
     };
-    do task::spawn || {
-        let mut server_ˊ = None;
-        *server_ <-> server_ˊ;
-        test::server(option::unwrap(server_ˊ));
+    do task::spawn {
+        let server__ = server_.take();
+        test::server(server__);
     };
 }
diff --git a/src/test/run-pass/pipe-pingpong-proto.rs b/src/test/run-pass/pipe-pingpong-proto.rs
index 050ff76ef9b..c51c0733622 100644
--- a/src/test/run-pass/pipe-pingpong-proto.rs
+++ b/src/test/run-pass/pipe-pingpong-proto.rs
@@ -12,6 +12,7 @@
 
 // An example to make sure the protocol parsing syntax extension works.
 
+use core::cell::Cell;
 use core::option;
 
 proto! pingpong (
@@ -49,17 +50,15 @@ mod test {
 
 pub fn main() {
     let (client_, server_) = pingpong::init();
-    let client_ = ~mut Some(client_);
-    let server_ = ~mut Some(server_);
+    let client_ = Cell(client_);
+    let server_ = Cell(server_);
 
-    do task::spawn || {
-        let mut client__ = None;
-        *client_ <-> client__;
-        test::client(option::unwrap(client__));
+    do task::spawn {
+        let client__ = client_.take();
+        test::client(client__);
     };
-    do task::spawn || {
-        let mut server_ˊ = None;
-        *server_ <-> server_ˊ;
-        test::server(option::unwrap(server_ˊ));
+    do task::spawn {
+        let server__ = server_.take();
+        test::server(server__);
     };
 }
diff --git a/src/test/run-pass/private-method.rs b/src/test/run-pass/private-method.rs
index ae149421f0a..432c189ae42 100644
--- a/src/test/run-pass/private-method.rs
+++ b/src/test/run-pass/private-method.rs
@@ -9,20 +9,20 @@
 // except according to those terms.
 
 struct cat {
-  priv mut meows : uint,
+    priv meows : uint,
 
-  how_hungry : int,
+    how_hungry : int,
 }
 
 impl cat {
-  fn play() {
-    self.meows += 1u;
-    self.nap();
-  }
+    fn play(&mut self) {
+        self.meows += 1u;
+        self.nap();
+    }
 }
 
 priv impl cat {
-    fn nap() { for uint::range(1u, 10u) |_i| { }}
+    fn nap(&mut self) { for uint::range(1u, 10u) |_i| { }}
 }
 
 fn cat(in_x : uint, in_y : int) -> cat {
@@ -33,6 +33,6 @@ fn cat(in_x : uint, in_y : int) -> cat {
 }
 
 pub fn main() {
-  let nyan : cat = cat(52u, 99);
+  let mut nyan : cat = cat(52u, 99);
   nyan.play();
 }
diff --git a/src/test/run-pass/pure-sum.rs b/src/test/run-pass/pure-sum.rs
index f4c92c869e4..cac6b4ef349 100644
--- a/src/test/run-pass/pure-sum.rs
+++ b/src/test/run-pass/pure-sum.rs
@@ -20,7 +20,7 @@ pure fn sums_to(v: ~[int], sum: int) -> bool {
 }
 
 pure fn sums_to_using_uniq(v: ~[int], sum: int) -> bool {
-    let mut i = 0u, sum0 = ~mut 0;
+    let mut i = 0u, sum0 = ~0;
     while i < v.len() {
         *sum0 += v[i];
         i += 1u;
@@ -40,7 +40,7 @@ pure fn sums_to_using_rec(v: ~[int], sum: int) -> bool {
 struct F<T> { f: T }
 
 pure fn sums_to_using_uniq_rec(v: ~[int], sum: int) -> bool {
-    let mut i = 0u, sum0 = F {f: ~mut 0};
+    let mut i = 0u, sum0 = F {f: ~0};
     while i < v.len() {
         *sum0.f += v[i];
         i += 1u;
diff --git a/src/test/run-pass/rcvr-borrowed-to-region.rs b/src/test/run-pass/rcvr-borrowed-to-region.rs
index 61cb473bf8f..7011f5ba1ad 100644
--- a/src/test/run-pass/rcvr-borrowed-to-region.rs
+++ b/src/test/run-pass/rcvr-borrowed-to-region.rs
@@ -31,7 +31,7 @@ pub fn main() {
     debug!("y=%d", y);
     assert y == 6;
 
-    let x = ~mut 6;
+    let mut x = ~6;
     let y = x.get();
     debug!("y=%d", y);
     assert y == 6;
diff --git a/src/test/run-pass/task-killjoin-rsrc.rs b/src/test/run-pass/task-killjoin-rsrc.rs
index b90c39ab34e..991025a1ad2 100644
--- a/src/test/run-pass/task-killjoin-rsrc.rs
+++ b/src/test/run-pass/task-killjoin-rsrc.rs
@@ -13,6 +13,7 @@
 // A port of task-killjoin to use a class with a dtor to manage
 // the join.
 
+use core::cell::Cell;
 use core::comm::*;
 
 struct notify {
@@ -49,11 +50,9 @@ fn joinable(f: fn~()) -> Port<bool> {
         *b = true;
     }
     let (p, c) = stream();
-    let c = ~mut Some(c);
+    let c = Cell(c);
     do task::spawn_unlinked {
-        let mut cc = None;
-        *c <-> cc;
-        let ccc = option::unwrap(cc);
+        let ccc = c.take();
         wrapper(ccc, f)
     }
     p
diff --git a/src/test/run-pass/uniq-cc-generic.rs b/src/test/run-pass/uniq-cc-generic.rs
index dd86150b93b..1b602ab7d30 100644
--- a/src/test/run-pass/uniq-cc-generic.rs
+++ b/src/test/run-pass/uniq-cc-generic.rs
@@ -10,11 +10,11 @@
 
 enum maybe_pointy {
     none,
-    p(@Pointy),
+    p(@mut Pointy),
 }
 
 struct Pointy {
-    mut a : maybe_pointy,
+    a : maybe_pointy,
     d : fn~() -> uint,
 }
 
@@ -22,15 +22,14 @@ fn make_uniq_closure<A:Owned + Copy>(a: A) -> fn~() -> uint {
     fn~() -> uint { ptr::addr_of(&a) as uint }
 }
 
-fn empty_pointy() -> @Pointy {
-    return @Pointy {
+fn empty_pointy() -> @mut Pointy {
+    return @mut Pointy {
         mut a : none,
         d : make_uniq_closure(~"hi")
     }
 }
 
-pub fn main()
-{
+pub fn main() {
     let v = empty_pointy();
     v.a = p(v);
 }
diff --git a/src/test/run-pass/uniq-cc.rs b/src/test/run-pass/uniq-cc.rs
index 384450ec57f..3d72a411828 100644
--- a/src/test/run-pass/uniq-cc.rs
+++ b/src/test/run-pass/uniq-cc.rs
@@ -10,25 +10,24 @@
 
 enum maybe_pointy {
     none,
-    p(@Pointy),
+    p(@mut Pointy),
 }
 
 struct Pointy {
-    mut a : maybe_pointy,
+    a : maybe_pointy,
     c : ~int,
     d : fn~()->(),
 }
 
-fn empty_pointy() -> @Pointy {
-    return @Pointy {
-        mut a : none,
+fn empty_pointy() -> @mut Pointy {
+    return @mut Pointy {
+        a : none,
         c : ~22,
         d : fn~()->(){},
     }
 }
 
-pub fn main()
-{
+pub fn main() {
     let v = empty_pointy();
     v.a = p(v);
 }
diff --git a/src/test/run-pass/unique-assign-copy.rs b/src/test/run-pass/unique-assign-copy.rs
index 4723356dcd0..1bb04aef286 100644
--- a/src/test/run-pass/unique-assign-copy.rs
+++ b/src/test/run-pass/unique-assign-copy.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub fn main() {
-    let i = ~mut 1;
+    let mut i = ~1;
     // Should be a copy
     let mut j;
     j = copy i;
diff --git a/src/test/run-pass/unique-decl-init-copy.rs b/src/test/run-pass/unique-decl-init-copy.rs
index 628eb7265a5..67e59cb08e0 100644
--- a/src/test/run-pass/unique-decl-init-copy.rs
+++ b/src/test/run-pass/unique-decl-init-copy.rs
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 pub fn main() {
-    let i = ~mut 1;
+    let mut i = ~1;
     // Should be a copy
-    let j = copy i;
+    let mut j = copy i;
     *i = 2;
     *j = 3;
     assert *i == 2;
diff --git a/src/test/run-pass/unique-in-vec-copy.rs b/src/test/run-pass/unique-in-vec-copy.rs
index 54ea0258c7c..ac8796674ab 100644
--- a/src/test/run-pass/unique-in-vec-copy.rs
+++ b/src/test/run-pass/unique-in-vec-copy.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub fn main() {
-    let a = ~[~mut 10];
+    let mut a = ~[~10];
     let b = copy a;
 
     assert *a[0] == 10;
diff --git a/src/test/run-pass/unique-mutable.rs b/src/test/run-pass/unique-mutable.rs
index c52d3b563ac..8784dbeb0af 100644
--- a/src/test/run-pass/unique-mutable.rs
+++ b/src/test/run-pass/unique-mutable.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 pub fn main() {
-    let i = ~mut 0;
+    let mut i = ~0;
     *i = 1;
     assert *i == 1;
 }