diff --git a/AUTHORS.txt b/AUTHORS.txt index e7fa662c603f..4a0bd86b5441 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -9,9 +9,11 @@ Aleksander Balicki Alex Rønne Petersen Alexander Stavonin Andreas Gal +Andrew Paseltiner Arkaitz Jimenez Armin Ronacher Austin Seipp +auREAX Ben Blum Ben Striegel Benjamin Herr @@ -41,6 +43,7 @@ Evan McClanahan Francisco Souza Gareth Daniel Smith Glenn Willen +Gonçalo Cabrita <_@gmcabrita.com> Graham Fawcett Grahame Bowland Haitao Li @@ -103,4 +106,5 @@ Tomoki Aonuma Tycho Sci Vincent Belliard Wade Mealing +Yasuhiro Fujii Zack Corr diff --git a/configure b/configure index 9f3ecddefe13..e67ea3af5f38 100755 --- a/configure +++ b/configure @@ -295,6 +295,7 @@ opt manage-submodules 1 "let the build manage the git submodules" opt mingw-cross 0 "cross-compile for win32 using mingw" opt clang 0 "prefer clang to gcc for building the runtime" opt local-rust 0 "use an installed rustc rather than downloading a snapshot" +opt pax-flags 0 "apply PaX flags to rustc binaries (required for GRSecurity/PaX-patched kernels)" valopt prefix "/usr/local" "set installation prefix" valopt local-rust-root "/usr/local" "set prefix for local rust binary" valopt llvm-root "" "set LLVM root" @@ -343,6 +344,11 @@ probe CFG_PDFLATEX pdflatex probe CFG_XETEX xetex probe CFG_LUATEX luatex probe CFG_NODE nodejs node +if [ "$CFG_OSTYPE" = "unknown-linux-gnu" ] +then + probe CFG_PAXCTL paxctl /sbin/paxctl + probe CFG_ZCAT zcat +fi if [ ! -z "$CFG_PANDOC" ] then @@ -354,6 +360,51 @@ then fi fi +if [ "$CFG_OSTYPE" = "unknown-linux-gnu" ] +then + if [ ! -z "$CFG_ENABLE_PAX_FLAGS" -a -z "$CFG_PAXCTL" ] + then + err "enabled PaX markings but no paxctl binary found" + fi + + if [ -z "$CFG_DISABLE_PAX_FLAGS" ] + then + # GRSecurity/PaX detection. This can be very flaky. + GRSEC_DETECTED= + + # /dev/grsec only exists if CONFIG_GRKERNSEC_NO_RBAC is not set. + # /proc/sys/kernel/grsecurity is not available if ÇONFIG_GRKERNSEC_SYSCTL is not set. + if [ -e /dev/grsec -o -d /proc/sys/kernel/grsecurity ] + then + GRSEC_DETECTED=1 + # /proc/config.gz is normally only available to root, and only if CONFIG_IKCONFIG_PROC has been set. + elif [ -r /proc/config.gz -a ! -z "$CFG_ZCAT" ] + then + if "$CFG_ZCAT" /proc/config.gz | grep --quiet "CONFIG_GRKERNSEC=y" + then + GRSEC_DETECTED=1 + fi + # Flaky. + elif grep --quiet grsec /proc/version + then + GRSEC_DETECTED=1 + fi + + if [ ! -z "$GRSEC_DETECTED" ] + then + step_msg "GRSecurity: yes" + if [ ! -z "$CFG_PAXCTL" ] + then + CFG_ENABLE_PAX_FLAGS=1 + else + warn "GRSecurity kernel detected but no paxctl binary found: not setting CFG_ENABLE_PAX_FLAGS" + fi + else + step_msg "GRSecurity: no" + fi + fi +fi + if [ ! -z "$CFG_ENABLE_LOCAL_RUST" ] then if [ ! -f ${CFG_LOCAL_RUST_ROOT}/bin/rustc ] @@ -523,15 +574,23 @@ then msg "git: submodule sync" "${CFG_GIT}" submodule --quiet sync + msg "git: submodule update" + "${CFG_GIT}" submodule --quiet update --init + need_ok "git failed" + + msg "git: submodule foreach sync" + "${CFG_GIT}" submodule --quiet foreach --recursive git submodule sync + need_ok "git failed" + + msg "git: submodule foreach update" + "${CFG_GIT}" submodule --quiet update --init --recursive + need_ok "git failed" + # NB: this is just for the sake of getting the submodule SHA1 values # and status written into the build log. msg "git: submodule status" "${CFG_GIT}" submodule status --recursive - msg "git: submodule update" - "${CFG_GIT}" submodule --quiet update --init --recursive - need_ok "git failed" - msg "git: submodule clobber" "${CFG_GIT}" submodule --quiet foreach --recursive git clean -dxf need_ok "git failed" @@ -699,6 +758,12 @@ putvar CFG_C_COMPILER putvar CFG_LIBDIR putvar CFG_DISABLE_MANAGE_SUBMODULES +if [ ! -z "$CFG_ENABLE_PAX_FLAGS" ] +then + putvar CFG_ENABLE_PAX_FLAGS + putvar CFG_PAXCTL +fi + if [ ! -z $BAD_PANDOC ] then CFG_PANDOC= diff --git a/doc/prep.js b/doc/prep.js index 1cd5bec81b2b..3a1e60ec4231 100755 --- a/doc/prep.js +++ b/doc/prep.js @@ -60,9 +60,10 @@ while ((line = lines[cur++]) != null) { var html = '
', curstr = "", curstyle = null;
       function add(str, style) {
         if (style != curstyle) {
-          if (curstyle) html += '' + curstr
-            + "";
-          else if (curstr) html += curstr;
+          if (curstyle) html +=
+            '' +
+            CodeMirror.htmlEscape(curstr) + "";
+          else if (curstr) html += CodeMirror.htmlEscape(curstr);
           curstr = str; curstyle = style;
         } else curstr += str;
       }
diff --git a/doc/rust.md b/doc/rust.md
index 5fd9622046ad..66552c29017f 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -773,8 +773,8 @@ A view item manages the namespace of a module; it does not define new items
 but simply changes the visibility of other items. There are several kinds of
 view item:
 
- * [extern mod declarations](#extern-mod-declarations)
- * [use declarations](#use-declarations)
+ * [`extern mod` declarations](#extern-mod-declarations)
+ * [`use` declarations](#use-declarations)
 
 ##### Extern mod declarations
 
@@ -784,7 +784,7 @@ link_attrs : link_attr [ ',' link_attrs ] + ;
 link_attr : ident '=' literal ;
 ~~~~~~~~
 
-An _extern mod declaration_ specifies a dependency on an external crate.
+An _`extern mod` declaration_ specifies a dependency on an external crate.
 The external crate is then bound into the declaring scope as the `ident` provided in the `extern_mod_decl`.
 
 The external crate is resolved to a specific `soname` at compile time, and a
@@ -960,24 +960,12 @@ pure fn pure_length(ls: List) -> uint { ... }
 pure fn nonempty_list(ls: List) -> bool { pure_length(ls) > 0u }
 ~~~~
 
-*TODO:* should actually define referential transparency.
-
-The effect checking rules previously enumerated are a restricted set
-of typechecking rules meant to approximate the universe of observably
-referentially transparent Rust procedures conservatively. Sometimes,
-these rules are *too* restrictive. Rust allows programmers to violate
-these rules by writing pure functions that the compiler cannot prove
-to be referentially transparent, using "unsafe blocks". When writing
-code that uses unsafe blocks, programmers should always be aware that
-they have an obligation to show that the code *behaves* referentially
-transparently at all times, even if the compiler cannot *prove*
-automatically that the code is referentially transparent. In the
-presence of unsafe blocks, the compiler provides no static guarantee
-that the code will behave as expected at runtime. Rather, the
-programmer has an independent obligation to verify the semantics of
-the pure functions they write.
-
-*TODO:* last two sentences are vague.
+These purity-checking rules approximate the concept of referential transparency:
+that a call-expression could be rewritten with the literal-expression of its return value, without changing the meaning of the program.
+Since they are an approximation, sometimes these rules are *too* restrictive.
+Rust allows programmers to violate these rules using [`unsafe` blocks](#unsafe-blocks).
+As with any `unsafe` block, those that violate static purity carry transfer the burden of safety-proof from the compiler to the programmer.
+Programmers should exercise caution when breaking such rules.
 
 An example of a pure function that uses an unsafe block:
 
@@ -1045,6 +1033,28 @@ Similarly, [trait](#traits) bounds can be specified for type
 parameters to allow methods with that trait to be called on values
 of that type.
 
+#### Unsafe functions
+
+Unsafe functions are those containing unsafe operations that are not contained in an [`unsafe` block](#unsafe-blocks).
+
+Unsafe operations are those that potentially violate the memory-safety guarantees of Rust's static semantics.
+Specifically, the following operations are considered unsafe:
+
+  - Dereferencing a [raw pointer](#pointer-types)
+  - Casting a [raw pointer](#pointer-types) to a safe pointer type
+  - Breaking the [purity-checking rules](#pure-functions)
+  - Calling an unsafe function
+
+##### Unsafe blocks
+
+A block of code can also be prefixed with the `unsafe` keyword,
+to permit a sequence of unsafe operations in an otherwise-safe function.
+This facility exists because the static semantics of a Rust are a necessary approximation of the dynamic semantics.
+When a programmer has sufficient conviction that a sequence of unsafe operations is actually safe,
+they can encapsulate that sequence (taken as a whole) within an `unsafe` block.
+The compiler will consider uses of such code "safe", to the surrounding context.
+
+
 #### Extern functions
 
 Extern functions are part of Rust's foreign function interface, providing
@@ -1059,7 +1069,7 @@ extern fn new_vec() -> ~[int] { ~[] }
 ~~~
 
 Extern functions may not be called from Rust code, but their value
-may be taken as an unsafe `u8` pointer.
+may be taken as a raw `u8` pointer.
 
 ~~~
 # extern fn new_vec() -> ~[int] { ~[] }
@@ -1468,6 +1478,25 @@ structure of expressions. Blocks themselves are expressions, so the nesting
 sequence of block, statement, expression, and block can repeatedly nest to an
 arbitrary depth.
 
+#### Lvalues, rvalues and temporaries
+
+Expressions are divided into two main categories: _lvalues_ and _rvalues_.
+Likewise within each expression, sub-expressions may occur in _lvalue context_ or _rvalue context_.
+The evaluation of an expression depends both on its own category and the context it occurs within.
+
+Path, field and index expressions are lvalues.
+All other expressions are rvalues.
+
+The left operand of an assignment expression and the operand of the borrow operator are lvalue contexts.
+All other expression contexts are rvalue contexts.
+
+When an lvalue is evaluated in an _lvalue context_, it denotes a memory location;
+when evaluated in an _rvalue context_, it denotes the value held _in_ that memory location.
+
+When an rvalue is used in lvalue context, a temporary un-named lvalue is created and used instead.
+A temporary's lifetime equals the largest lifetime of any borrowed pointer that points to it.
+
+
 ### Literal expressions
 
 A _literal expression_ consists of one of the [literal](#literals)
@@ -1708,9 +1737,9 @@ A type cast expression is denoted with the binary operator `as`.
 Executing an `as` expression casts the value on the left-hand side to the type
 on the right-hand side.
 
-A numeric value can be cast to any numeric type.  An unsafe pointer value can
-be cast to or from any integral type or unsafe pointer type.  Any other cast
-is unsupported and will fail to compile.
+A numeric value can be cast to any numeric type.
+A raw pointer value can be cast to or from any integral type or raw pointer type.
+Any other cast is unsupported and will fail to compile.
 
 An example of an `as` expression:
 
@@ -2277,30 +2306,25 @@ logging level:
 // Full version, logging a value.
 log(core::error, ~"file not found: " + filename);
 
-// Log-level abbreviated, since core::* is imported by default.
+// Log-level abbreviated, since core::* is used by default.
 log(error, ~"file not found: " + filename);
 
-// Formatting the message using a format-string and #fmt
+// Formatting the message using a format-string and fmt!
 log(error, fmt!("file not found: %s", filename));
 
-// Using the #error macro, that expands to the previous call.
+// Using the error! macro, that expands to the previous call.
 error!("file not found: %s", filename);
 ~~~~
 
-A `log` expression is *not evaluated* when logging at the specified
-logging-level, module or task is disabled at runtime. This makes inactive
-`log` expressions very cheap; they should be used extensively in Rust
-code, as diagnostic aids, as they add little overhead beyond a single
-integer-compare and branch at runtime.
+A `log` expression is *not evaluated* when logging at the specified logging-level, module or task is disabled at runtime.
+This makes inactive `log` expressions very cheap;
+they should be used extensively in Rust code, as diagnostic aids,
+as they add little overhead beyond a single integer-compare and branch at runtime.
 
-Logging is presently implemented as a language built-in feature, as it makes
-use of compiler-provided logic for allocating the associated per-module
-logging-control structures visible to the runtime, and lazily evaluating
-arguments. In the future, as more of the supporting compiler-provided logic is
-moved into libraries, logging is likely to move to a component of the core
-library. It is best to use the macro forms of logging (*#error*,
-*#debug*, etc.) to minimize disruption to code using the logging facility
-when it is changed.
+Logging is presently implemented as a language built-in feature,
+as it makes use of compiler-provided, per-module data tables and flags.
+In the future, logging will move into a library, and will no longer be a core expression type.
+It is therefore recommended to use the macro forms of logging (`error!`, `debug!`, etc.) to minimize disruption in code that uses logging.
 
 
 ### Assert expressions
@@ -2481,27 +2505,53 @@ tuple of arguments.
 Enumerated types cannot be denoted *structurally* as types, but must be
 denoted by named reference to an [*enumeration* item](#enumerations).
 
-### Box types
+### Pointer types
 
-Box types are represented as pointers. There are three flavours of
-pointers:
+All pointers in Rust are explicit first-class values.
+They can be copied, stored into data structures, and returned from functions.
+There are four varieties of pointer in Rust:
 
-Shared boxes (`@`)
-  : These are reference-counted boxes. Their type is written
-    `@content`, for example `@int` means a shared box containing an
-    integer. Copying a value of such a type means copying the pointer
-    and increasing the reference count.
+Managed pointers (`@`)
+  : These point to managed heap allocations (or "boxes") in the task-local, managed heap.
+    Managed pointers are written `@content`,
+    for example `@int` means a managed pointer to a managed box containing an integer.
+    Copying a managed pointer is a "shallow" operation:
+    it involves only copying the pointer itself
+    (as well as any reference-count or GC-barriers required by the managed heap).
+    Dropping a managed pointer does not necessarily release the box it points to;
+    the lifecycles of managed boxes are subject to an unspecified garbage collection algorithm.
 
-Unique boxes (`~`)
-  : Unique boxes have only a single owner, and are freed when their
-    owner releases them. They are written `~content`. Copying a
-    unique box involves copying the contents into a new box.
+Owning pointers (`~`)
+  : These point to owned heap allocations (or "boxes") in the shared, inter-task heap.
+    Each owned box has a single owning pointer; pointer and pointee retain a 1:1 relationship at all times.
+    Owning pointers are written `~content`,
+    for example `~int` means an owning pointer to an owned box containing an integer.
+    Copying an owned box is a "deep" operation:
+    it involves allocating a new owned box and copying the contents of the old box into the new box.
+    Releasing an owning pointer immediately releases its corresponding owned box.
 
-Unsafe pointers (`*`)
-  : Unsafe pointers are pointers without safety guarantees or
-    language-enforced semantics. Their type is written `*content`.
-    They can be copied and dropped freely. Dereferencing an unsafe
-    pointer is part of the unsafe sub-dialect of Rust.
+Borrowed pointers (`&`)
+  : These point to memory _owned by some other value_.
+    Borrowed pointers arise by (automatic) conversion from owning pointers, managed pointers,
+    or by applying the borrowing operator `&` to some other value,
+    including [lvalues, rvalues or temporaries](#lvalues-rvalues-and-temporaries).
+    Borrowed pointers are written `&content`, or in some cases `&f/content` for some lifetime-variable `f`,
+    for example `&int` means a borrowed pointer to an integer.
+    Copying a borrowed pointer is a "shallow" operation:
+    it involves only copying the pointer itself.
+    Releasing a borrowed pointer typically has no effect on the value it points to,
+    with the exception of temporary values,
+    which are released when the last borrowed pointer to them is released.
+
+Raw pointers (`*`)
+  : Raw pointers are pointers without safety or liveness guarantees.
+    Raw pointers are written `*content`,
+    for example `*int` means a raw pointer to an integer.
+    Copying or dropping a raw pointer is has no effect on the lifecycle of any other value.
+    Dereferencing a raw pointer or converting it to any other pointer type is an [`unsafe` operation](#unsafe-functions).
+    Raw pointers are generally discouraged in Rust code;
+    they exist to support interoperability with foreign code,
+    and writing performance-critical or low-level functions.
 
 ### Function types
 
@@ -2678,20 +2728,17 @@ the box values pointing to it. Since box values may themselves be passed in
 and out of frames, or stored in the heap, heap allocations may outlive the
 frame they are allocated within.
 
-
 ### Memory ownership
 
 A task owns all memory it can *safely* reach through local variables,
-shared or unique boxes, and/or references. Sharing memory between tasks can
-only be accomplished using *unsafe* constructs, such as raw pointer
-operations or calling C code.
+as well as managed, owning and borrowed pointers.
 
-When a task sends a value that has the `send` trait over a channel, it
-loses ownership of the value sent and can no longer refer to it. This is
-statically guaranteed by the combined use of "move semantics" and the
-compiler-checked _meaning_ of the `send` trait: it is only instantiated
-for (transitively) unique kinds of data constructor and pointers, never shared
-pointers.
+When a task sends a value that has the `Send` trait to another task,
+it loses ownership of the value sent and can no longer refer to it.
+This is statically guaranteed by the combined use of "move semantics",
+and the compiler-checked _meaning_ of the `Send` trait:
+it is only instantiated for (transitively) sendable kinds of data constructor and pointers,
+never including managed or borrowed pointers.
 
 When a stack frame is exited, its local allocations are all released, and its
 references to boxes (both shared and owned) are dropped.
@@ -2737,14 +2784,12 @@ aside a copy of that value to refer to. If this is not semantically safe (for
 example, if the referred-to value contains mutable fields), it will reject the
 program. If the compiler deems copying the value expensive, it will warn.
 
-A function can be declared to take an argument by mutable reference. This
-allows the function to write to the slot that the reference refers to.
-
-An example function that accepts an value by mutable reference:
+A function with an argument of type `&mut T`, for some type `T`, can write to
+the slot that its argument refers to. An example of such a function is:
 
 ~~~~~~~~
-fn incr(&i: int) {
-    i = i + 1;
+fn incr(i: &mut int) {
+    *i = *i + 1;
 }
 ~~~~~~~~
 
@@ -2832,54 +2877,21 @@ exploiting.]
 
 ### Communication between tasks
 
-With the exception of *unsafe* blocks, Rust tasks are isolated from
-interfering with one another's memory directly. Instead of manipulating shared
-storage, Rust tasks communicate with one another using a typed, asynchronous,
-simplex message-passing system.
+Rust tasks are isolated and generally unable to interfere with one another's memory directly,
+except through [`unsafe` code](#unsafe-functions).
+All contact between tasks is mediated by safe forms of ownership transfer,
+and data races on memory are prohibited by the type system.
 
-A _port_ is a communication endpoint that can *receive* messages. Ports
-receive messages from channels.
+Inter-task communication and co-ordination facilities are provided in the standard library.
+These include:
+  - synchronous and asynchronous communication channels with various communication topologies
+  - read-only and read-write shared variables with various safe mutual exclusion patterns
+  - simple locks and semaphores
 
-A _channel_ is a communication endpoint that can *send* messages. Channels
-send messages to ports.
-
-Each port is implicitly boxed and mutable; as such a port has a unique
-per-task identity and cannot be replicated or transmitted. If a port value is
-copied, both copies refer to the *same* port. New ports can be
-constructed dynamically and stored in data structures.
-
-Each channel is bound to a port when the channel is constructed, so the
-destination port for a channel must exist before the channel itself. A channel
-cannot be rebound to a different port from the one it was constructed with.
-
-Channels are weak: a channel does not keep the port it is bound to
-alive. Ports are owned by their allocating task and cannot be sent over
-channels; if a task dies its ports die with it, and all channels bound to
-those ports no longer function. Messages sent to a channel connected to a dead
-port will be dropped.
-
-Channels are immutable types with meaning known to the runtime; channels can
-be sent over channels.
-
-Many channels can be bound to the same port, but each channel is bound to a
-single port. In other words, channels and ports exist in an N:1 relationship,
-N channels to 1 port. ^[It may help to remember nautical terminology
-when differentiating channels from ports.  Many different waterways --
-channels -- may lead to the same port.]
-
-Each port and channel can carry only one type of message. The message type is
-encoded as a parameter of the channel or port type. The message type of a
-channel is equal to the message type of the port it is bound to. The types of
-messages must satisfy the `send` built-in trait.
-
-Messages are generally sent asynchronously, with optional
-rate-limiting on the transmit side.  Each port contains a message
-queue and sending a message over a channel merely means inserting it
-into the associated port's queue; message receipt is the
-responsibility of the receiving task.
-
-Messages are sent on channels and received on ports using standard library
-functions.
+When such facilities carry values, the values are restricted to the [`Send` type-kind](#type-kinds).
+Restricting communication interfaces to this kind ensures that no borrowed or managed pointers move between tasks.
+Thus access to an entire data structure can be mediated through its owning "root" value;
+no further locking or copying is required to avoid data races within the substructure of such a value.
 
 
 ### Task lifecycle
@@ -2896,12 +2908,11 @@ A task begins its lifecycle -- once it has been spawned -- in the *running*
 state. In this state it executes the statements of its entry function, and any
 functions called by the entry function.
 
-A task may transition from the *running* state to the *blocked* state any time
-it makes a blocking receive call on a port, or attempts a rate-limited
-blocking send on a channel. When the communication expression can be completed
--- when a message arrives at a sender, or a queue drains sufficiently to
-complete a rate-limited send -- then the blocked task will unblock and
-transition back to *running*.
+A task may transition from the *running* state to the *blocked*
+state any time it makes a blocking communication call. When the
+call can be completed -- when a message arrives at a sender, or a
+buffer opens to receive a message -- then the blocked task will
+unblock and transition back to *running*.
 
 A task may transition to the *failing* state at any time, due being
 killed by some external event or internally, from the evaluation of a
@@ -2952,7 +2963,7 @@ An example of a `spawn` call:
 
 ~~~~
 let po = comm::Port();
-let ch = comm::Chan(po);
+let ch = comm::Chan(&po);
 
 do task::spawn {
     // let task run, do other things
@@ -2974,7 +2985,7 @@ An example of a send:
 
 ~~~~
 let po = comm::Port();
-let ch = comm::Chan(po);
+let ch = comm::Chan(&po);
 comm::send(ch, ~"hello, world");
 ~~~~
 
@@ -2990,7 +3001,7 @@ An example of a *receive*:
 
 ~~~~~~~~
 # let po = comm::Port();
-# let ch = comm::Chan(po);
+# let ch = comm::Chan(&po);
 # comm::send(ch, ~"");
 let s = comm::recv(po);
 ~~~~~~~~
diff --git a/doc/tutorial-macros.md b/doc/tutorial-macros.md
index 5cd5d79bd297..8202fbe8dc53 100644
--- a/doc/tutorial-macros.md
+++ b/doc/tutorial-macros.md
@@ -65,7 +65,7 @@ forbidden.
 To take as an argument a fragment of Rust code, write `$` followed by a name
  (for use on the right-hand side), followed by a `:`, followed by the sort of
 fragment to match (the most common ones are `ident`, `expr`, `ty`, `pat`, and
-`block`). Anything not preceeded by a `$` is taken literally. The standard
+`block`). Anything not preceded by a `$` is taken literally. The standard
 rules of tokenization apply,
 
 So `($x:ident => (($e:expr)))`, though excessively fancy, would create a macro
@@ -88,7 +88,7 @@ position).
 
 Going back to the motivating example, suppose that we wanted each invocation
 of `early_return` to potentially accept multiple "special" identifiers. The
-syntax `$(...)*` accepts zero or more occurences of its contents, much like
+syntax `$(...)*` accepts zero or more occurrences of its contents, much like
 the Kleene star operator in regular expressions. It also supports a separator
 token (a comma-separated list could be written `$(...),*`), and `+` instead of
 `*` to mean "at least one".
diff --git a/doc/tutorial-tasks.md b/doc/tutorial-tasks.md
index 405f4ac73478..8b9d0c0c2a7d 100644
--- a/doc/tutorial-tasks.md
+++ b/doc/tutorial-tasks.md
@@ -47,7 +47,7 @@ In particular, there are currently two independent modules that provide
 a message passing interface to Rust code: `core::comm` and `core::pipes`.
 `core::comm` is an older, less efficient system that is being phased out
 in favor of `pipes`. At some point the existing `core::comm` API will
-be romoved and the user-facing portions of `core::pipes` will be moved
+be removed and the user-facing portions of `core::pipes` will be moved
 to `core::comm`. In this tutorial we will discuss `pipes` and ignore
 the `comm` API.
 
@@ -58,7 +58,7 @@ concurrency at the moment.
 * [`core::comm`] - The deprecated message passing API
 * [`core::pipes`] - The new message passing infrastructure and API
 * [`std::comm`] - Higher level messaging types based on `core::pipes`
-* [`std::sync`] - More exotic synchronization tools, including locks 
+* [`std::sync`] - More exotic synchronization tools, including locks
 * [`std::arc`] - The ARC type, for safely sharing immutable data
 * [`std::par`] - Some basic tools for implementing parallel algorithms
 
@@ -151,7 +151,7 @@ commonly used, which we will cover presently.
 
 The simplest way to create a pipe is to use the `pipes::stream`
 function to create a `(Chan, Port)` pair. In Rust parlance a 'channel'
-is a sending endpoint of a pipe, and a 'port' is the recieving
+is a sending endpoint of a pipe, and a 'port' is the receiving
 endpoint. Consider the following example of performing two calculations
 concurrently.
 
@@ -183,7 +183,7 @@ let (chan, port): (Chan, Port) = stream();
 ~~~~
 
 The channel will be used by the child task to send data to the parent task,
-which will wait to recieve the data on the port. The next statement
+which will wait to receive the data on the port. The next statement
 spawns the child task.
 
 ~~~~
@@ -307,7 +307,7 @@ unrecoverable within a single task - once a task fails there is no way
 to "catch" the exception.
 
 All tasks are, by default, _linked_ to each other, meaning their fate
-is interwined, and if one fails so do all of them.
+is intertwined, and if one fails so do all of them.
 
 ~~~
 # use task::spawn;
diff --git a/doc/tutorial.md b/doc/tutorial.md
index 7f60492e06ff..bf262105f6e4 100644
--- a/doc/tutorial.md
+++ b/doc/tutorial.md
@@ -152,9 +152,9 @@ example, by changing `io::println` to some nonexistent function), and
 then compile it, you'll see an error message like this:
 
 ~~~~ {.notrust}
-hello.rs:2:4: 2:16 error: unresolved name: io::print_it
-hello.rs:2     io::print_it("hello? yes, this is rust");
-               ^~~~~~~~~~~~
+hello.rs:2:4: 2:16 error: unresolved name: io::print_with_unicorns
+hello.rs:2     io::print_with_unicorns("hello? yes, this is rust");
+               ^~~~~~~~~~~~~~~~~~~~~~~
 ~~~~
 
 In its simplest form, a Rust program is a `.rs` file with some types
@@ -162,12 +162,7 @@ and functions defined in it. If it has a `main` function, it can be
 compiled to an executable. Rust does not allow code that's not a
 declaration to appear at the top level of the file—all statements must
 live inside a function.  Rust programs can also be compiled as
-libraries, and included in other programs. The `extern mod std`
-directive that appears at the top of many examples imports the
-[standard library][std], described in more detail [later
-on](#modules-and-crates).
-
-[std]: http://doc.rust-lang.org/doc/std
+libraries, and included in other programs.
 
 ## Editing Rust code
 
@@ -178,9 +173,11 @@ included in that directory. In particular, if you are running emacs
 24, then using emacs's internal package manager to install `rust-mode`
 is the easiest way to keep it up to date. There is also a package for
 Sublime Text 2, available both [standalone][sublime] and through
-[Sublime Package Control][sublime-pkg].
+[Sublime Package Control][sublime-pkg], and support for Kate
+under `src/etc/kate`.
 
-Other editors are not provided for yet. If you end up writing a Rust
+There is ctags support via `src/etc/ctags.rust`, but many other
+tools and editors are not provided for yet. If you end up writing a Rust
 mode for your favorite editor, let us know so that we can link to it.
 
 [sublime]: http://github.com/dbp/sublime-rust
@@ -191,7 +188,7 @@ mode for your favorite editor, let us know so that we can link to it.
 Assuming you've programmed in any C-family language (C++, Java,
 JavaScript, C#, or PHP), Rust will feel familiar. Code is arranged
 in blocks delineated by curly braces; there are control structures
-for branching and looping, like the familiar `if` and `when`; function
+for branching and looping, like the familiar `if` and `while`; function
 calls are written `myfunc(arg1, arg2)`; operators are written the same
 and mostly have the same precedence as in C; comments are again like C.
 
@@ -227,18 +224,24 @@ while count < 10 {
 }
 ~~~~
 
-Although Rust can almost always infer the types of local variables, it
-can help readability to specify a variable's type by following it with
-a colon, then the type name. 
+Although Rust can almost always infer the types of local variables, you
+can specify a variable's type by following it with a colon, then the type
+name. 
 
 ~~~~
-let my_favorite_value: float = 57.8;
-let my_favorite_value: int = my_favorite_value as int;
+let monster_size: float = 57.8;
+let imaginary_size = monster_size * 10.0;
+let monster_size: int = 50;
 ~~~~
 
 Local variables may shadow earlier declarations, as in the previous
-example in which `my_favorite_value` is first declared as a `float`
-then a second `my_favorite_value` is declared as an int.
+example in which `monster_size` is first declared as a `float`
+then a second `monster_size` is declared as an int. If you were to actually
+compile this example though, the compiler will see that the second
+`monster_size` is unused, assume that you have made a mistake, and issue
+a warning. For occasions where unused variables are intentional, their
+name may be prefixed with an underscore to silence the warning, like
+`let _monster_size = 50;`.
 
 Rust identifiers follow the same rules as C; they start with an alphabetic
 character or an underscore, and after that may contain any sequence of
@@ -248,14 +251,14 @@ underscores where they help readability, while writing types in camel case.
 
 ~~~
 let my_variable = 100;
-type MyType = int; // built-in types though are _not_ camel case
+type MyType = int;     // some built-in types are _not_ camel case
 ~~~
 
 ## Expression syntax
 
 Though it isn't apparent in all code, there is a fundamental
-difference between Rust's syntax and its predecessors in this family
-of languages. Many constructs that are statements in C are expressions
+difference between Rust's syntax and predecessors like C.
+Many constructs that are statements in C are expressions
 in Rust, allowing code to be more concise. For example, you might
 write a piece of code like this:
 
@@ -275,24 +278,25 @@ But, in Rust, you don't have to repeat the name `price`:
 
 ~~~~
 # let item = "salad";
-let price = if item == "salad" {
-    3.50
-} else if item == "muffin" {
-    2.25
-} else {
-    2.00
-};
+let price =
+    if item == "salad" {
+        3.50
+    } else if item == "muffin" {
+        2.25
+    } else {
+        2.00
+    };
 ~~~~
 
 Both pieces of code are exactly equivalent—they assign a value to
-`price` depending on the condition that holds. Note that the
-semicolons are omitted from the blocks in the second snippet. This is
+`price` depending on the condition that holds. Note that there
+are not semicolons in the blocks of the second snippet. This is
 important; the lack of a semicolon after the last statement in a
 braced block gives the whole block the value of that last expression.
 
 Put another way, the semicolon in Rust *ignores the value of an expression*.
 Thus, if the branches of the `if` had looked like `{ 4; }`, the above example
-would simply assign nil (void) to `price`. But without the semicolon, each
+would simply assign `()` (nil or void) to `price`. But without the semicolon, each
 branch has a different value, and `price` gets the value of the branch that
 was taken.
 
@@ -320,7 +324,6 @@ something—in which case you'll have embedded it in a bigger statement.
 # fn foo() -> bool { true }
 # fn bar() -> bool { true }
 # fn baz() -> bool { true }
-
 // `let` is not an expression, so it is semi-colon terminated;
 let x = foo();
 
@@ -346,12 +349,11 @@ if x {
 let y = if x { foo() } else { bar() };
 ~~~
 
-This may sound a bit intricate, but it is super-useful, and it will
-grow on you (hopefully).
+This may sound intricate, but it is super-useful and will grow on you.
 
 ## Types
 
-The basic types include the usual boolean, integral, and floating point types.
+The basic types include the usual boolean, integral, and floating-point types.
 
 ------------------------- -----------------------------------------------
 `()`                      Nil, the type that has only a single value
@@ -360,17 +362,18 @@ The basic types include the usual boolean, integral, and floating point types.
 `i8`, `i16`, `i32`, `i64` Signed integers with a specific size (in bits)
 `u8`, `u16`, `u32`, `u64` Unsigned integers with a specific size
 `float`                   The largest floating-point type efficiently supported on the target machine
-`f32`, `f64`              Floating-point types with a specific size.
-`char`                    A Unicode character (32 bits).
+`f32`, `f64`              Floating-point types with a specific size
+`char`                    A Unicode character (32 bits)
 ------------------------- -----------------------------------------------
 
 These can be combined in composite types, which will be described in
-more detail later on (the `T`s here stand for any other type):
+more detail later on (the `T`s here stand for any other type,
+while N should be a literal number):
 
 ------------------------- -----------------------------------------------
 `[T * N]`                 Vector (like an array in other languages) with N elements
 `[mut T * N]`             Mutable vector with N elements
-`(T1, T2)`                Tuple type. Any arity above 1 is supported
+`(T1, T2)`                Tuple type; any arity above 1 is supported
 `&T`, `~T`, `@T`          [Pointer types](#boxes-and-pointers)
 ------------------------- -----------------------------------------------
 
@@ -392,7 +395,7 @@ the type `fn() -> bool` or the function declaration `fn foo() -> bool
 optionally write `-> ()`, but usually the return annotation is simply
 left off, as in `fn main() { ... }`.
 
-Types can be given names with `type` declarations:
+Types can be given names or aliases with `type` declarations:
 
 ~~~~
 type MonsterSize = uint;
@@ -401,9 +404,25 @@ type MonsterSize = uint;
 This will provide a synonym, `MonsterSize`, for unsigned integers. It will not
 actually create a new, incompatible type—`MonsterSize` and `uint` can be used
 interchangeably, and using one where the other is expected is not a type
-error. Read about [single-variant enums](#single_variant_enum)
-further on if you need to create a type name that's not just a
-synonym.
+error.
+
+To create data types which are not synonyms, `struct` and `enum`
+can be used. They're described in more detail below, but they look like this:
+
+~~~~
+enum HidingPlaces {
+   Closet(uint),
+   UnderTheBed(uint)
+}
+
+struct HeroicBabysitter {
+   bedtime_stories: uint,
+   sharpened_stakes: uint
+}
+
+struct BabysitterSize(uint);  // a single-variant struct
+enum MonsterSize = uint;      // a single-variant enum
+~~~~
 
 ## Literals
 
@@ -435,10 +454,38 @@ The nil literal is written just like the type: `()`. The keywords
 
 Character literals are written between single quotes, as in `'x'`. Just as in
 C, Rust understands a number of character escapes, using the backslash
-character, `\n`, `\r`, and `\t` being the most common. String literals,
+character, such as `\n`, `\r`, and `\t`. String literals,
 written between double quotes, allow the same escape sequences. Rust strings
 may contain newlines.
 
+## Constants
+
+Compile-time constants are declared with `const`. All scalar types,
+like integers and floats, may be declared `const`, as well as fixed
+length vectors, static strings (more on this later), and structs.
+Constants may be declared in any scope and may refer to other
+constants. Constant declarations are not type inferred, so must always
+have a type annotation.  By convention they are written in all capital
+letters.
+
+~~~
+// Scalars can be constants
+const MY_PASSWORD: int = 12345;
+
+// Scalar constants can be combined with other constants
+const MY_DOGGIES_PASSWORD: int = MY_PASSWORD + 1;
+
+// Fixed-length vectors
+const MY_VECTORY_PASSWORD: [int * 5] = [1, 2, 3, 4, 5];
+
+// Static strings
+const MY_STRINGY_PASSWORD: &static/str = "12345";
+
+// Structs
+struct Password { value: int }
+const MY_STRUCTY_PASSWORD: Password = Password { value: MY_PASSWORD };
+~~~
+
 ## Operators
 
 Rust's set of operators contains very few surprises. Arithmetic is done with
@@ -466,8 +513,8 @@ assert y == 4u;
 
 The main difference with C is that `++` and `--` are missing, and that
 the logical bitwise operators have higher precedence — in C, `x & 2 > 0`
-comes out as `x & (2 > 0)`, in Rust, it means `(x & 2) > 0`, which is
-more likely to be what you expect (unless you are a C veteran).
+means `x & (2 > 0)`, but in Rust, it means `(x & 2) > 0`, which is
+more likely what a novice expects.
 
 ## Syntax extensions
 
@@ -556,18 +603,14 @@ underscore (`_`) is a wildcard pattern that matches everything.
 
 The patterns in an match arm are followed by a fat arrow, `=>`, then an
 expression to evaluate. Each case is separated by commas. It's often
-convenient to use a block expression for a case, in which case the
+convenient to use a block expression for each case, in which case the
 commas are optional.
 
 ~~~
 # let my_number = 1;
 match my_number {
-  0 => {
-    io::println("zero")
-  }
-  _ => {
-    io::println("something else")
-  }
+  0 => { io::println("zero") }
+  _ => { io::println("something else") }
 }
 ~~~
 
@@ -686,12 +729,13 @@ omitted from the type, such an assignment would result in a type error.
 
 Structs can be destructured in `match` patterns. The basic syntax is
 `Name {fieldname: pattern, ...}`:
+
 ~~~~
 # struct Point { x: float, y: float }
 # let mypoint = Point { x: 0.0, y: 0.0 };
 match mypoint {
-    Point { x: 0.0, y: y } => { io::println(y.to_str());                    }
-    Point { x: x, y: y }   => { io::println(x.to_str() + " " + y.to_str()); }
+    Point { x: 0.0, y: yy } => { io::println(yy.to_str());                     }
+    Point { x: xx,  y: yy } => { io::println(xx.to_str() + " " + yy.to_str()); }
 }
 ~~~~
 
@@ -699,6 +743,35 @@ In general, the field names of a struct do not have to appear in the same
 order they appear in the type. When you are not interested in all
 the fields of a struct, a struct pattern may end with `, _` (as in
 `Name {field1, _}`) to indicate that you're ignoring all other fields.
+Additionally, struct fields have a shorthand matching form that simply
+reuses the field name as the binding name.
+
+~~~
+# struct Point { x: float, y: float }
+# let mypoint = Point { x: 0.0, y: 0.0 };
+match mypoint {
+    Point { x, _ } => { io::println(x.to_str()) }
+}
+~~~
+
+Structs are the only type in Rust that may have user-defined destructors,
+using `drop` blocks, inside of which the struct's value may be referred
+to with the name `self`.
+
+~~~
+struct TimeBomb {
+    explosivity: uint,
+
+    drop {
+        for iter::repeat(self.explosivity) {
+            io::println(fmt!("blam!"));
+        }
+    }
+}
+~~~
+
+> ***Note***: This destructor syntax is temporary. Eventually destructors
+> will be defined for any type using [traits](#traits).
 
 ## Enums
 
@@ -781,7 +854,7 @@ dereference (`*`) unary operator:
 
 ~~~~
 # enum GizmoId = int;
-let my_gizmo_id = GizmoId(10);
+let my_gizmo_id: GizmoId = GizmoId(10);
 let id_int: int = *my_gizmo_id;
 ~~~~
 
@@ -842,12 +915,8 @@ back to [later](#modules-and-crates)). They are introduced with the
 the return type follows the arrow.
 
 ~~~~
-fn repeat(string: &str, count: int) -> ~str {
-    let mut result = ~"";
-    for count.times {
-        result += string;
-    }
-    return result;
+fn line(a: int, b: int, x: int) -> int {
+    return a * x + b;
 }
 ~~~~
 
@@ -857,21 +926,8 @@ also return a value by having its top level block produce an
 expression.
 
 ~~~~
-# const copernicus: int = 0;
-fn int_to_str(i: int) -> ~str {
-    if i == copernicus {
-        return ~"tube sock";
-    } else {
-        return ~"violin";
-    }
-}
-~~~~
-
-~~~~
-# const copernicus: int = 0;
-fn int_to_str(i: int) -> ~str {
-    if i == copernicus { ~"tube sock" }
-    else { ~"violin" }
+fn line(a: int, b: int, x: int) -> int {
+    a * x + b
 }
 ~~~~
 
@@ -885,6 +941,16 @@ fn do_nothing_the_hard_way() -> () { return (); }
 fn do_nothing_the_easy_way() { }
 ~~~~
 
+Ending the function with a semicolon like so is equivalent to returning `()`.
+
+~~~~
+fn line(a: int, b: int, x: int) -> int { a * x + b  }
+fn oops(a: int, b: int, x: int) -> ()  { a * x + b; }
+
+assert 8  == line(5, 3, 1);
+assert () == oops(5, 3, 1);
+~~~~
+
 Methods are like functions, except that they are defined for a specific
 'self' type (like 'this' in C++). Calling a method is done with
 dot notation, as in `my_vec.len()`. Methods may be defined on most
@@ -984,7 +1050,7 @@ easy for programmers to reason about. Heap isolation has the
 additional benefit that garbage collection must only be done
 per-heap. Rust never "stops the world" to reclaim memory.
 
-Complete isolation of heaps between tasks implies that any data
+Complete isolation of heaps between tasks would, however, mean that any data
 transferred between tasks must be copied. While this is a fine and
 useful way to implement communication between tasks, it is also very
 inefficient for large data structures.  Because of this, Rust also
@@ -1096,6 +1162,9 @@ If you really want to copy a unique box you must say so explicitly.
 ~~~~
 let x = ~10;
 let y = copy x;
+
+let z = *x + *y;
+assert z == 20;
 ~~~~
 
 This is where the 'move' operator comes in. It is similar to
@@ -1104,9 +1173,11 @@ from `x` to `y`, without violating the constraint that it only has a
 single owner (if you used assignment instead of the move operator, the
 box would, in principle, be copied).
 
-~~~~
+~~~~ {.xfail-test}
 let x = ~10;
 let y = move x;
+
+let z = *x + *y; // would cause an error: use of moved variable: `x`
 ~~~~
 
 Owned boxes, when they do not contain any managed boxes, can be sent
@@ -1208,6 +1279,73 @@ For a more in-depth explanation of borrowed pointers, read the
 
 [borrowtut]: tutorial-borrowed-ptr.html
 
+## Dereferencing pointers
+
+Rust uses the unary star operator (`*`) to access the contents of a
+box or pointer, similarly to C.
+
+~~~
+let managed = @10;
+let owned = ~20;
+let borrowed = &30;
+
+let sum = *managed + *owned + *borrowed;
+~~~
+
+Dereferenced mutable pointers may appear on the left hand side of
+assignments, in which case the value they point to is modified.
+
+~~~
+let managed = @mut 10;
+let owned = ~mut 20;
+
+let mut value = 30;
+let borrowed = &mut value;
+
+*managed = *owned + 10;
+*owned = *borrowed + 100;
+*borrowed = *managed + 1000;
+~~~
+
+Pointers have high operator precedence, but lower precedence than the
+dot operator used for field and method access. This can lead to some
+awkward code filled with parenthesis.
+
+~~~
+# struct Point { x: float, y: float }
+# enum Shape { Rectangle(Point, Point) }
+# impl Shape { fn area() -> int { 0 } }
+let start = @Point { x: 10f, y: 20f };
+let end = ~Point { x: (*start).x + 100f, y: (*start).y + 100f };
+let rect = &Rectangle(*start, *end);
+let area = (*rect).area();
+~~~
+
+To combat this ugliness the dot operator performs _automatic pointer
+dereferencing_ on the receiver (the value on the left hand side of the
+dot), so in most cases dereferencing the receiver is not necessary.
+
+~~~
+# struct Point { x: float, y: float }
+# enum Shape { Rectangle(Point, Point) }
+# impl Shape { fn area() -> int { 0 } }
+let start = @Point { x: 10f, y: 20f };
+let end = ~Point { x: start.x + 100f, y: start.y + 100f };
+let rect = &Rectangle(*start, *end);
+let area = rect.area();
+~~~
+
+Auto-dereferencing is performed through any number of pointers. If you
+felt inclined you could write something silly like
+
+~~~
+# struct Point { x: float, y: float }
+let point = &@~Point { x: 10f, y: 20f };
+io::println(fmt!("%f", point.x));
+~~~
+
+The indexing operator (`[]`) is also auto-dereferencing.
+
 # Vectors and strings
 
 Vectors are a contiguous section of memory containing zero or more
@@ -1219,52 +1357,23 @@ pointers to vectors are also called 'slices'.
 enum Crayon {
     Almond, AntiqueBrass, Apricot,
     Aquamarine, Asparagus, AtomicTangerine,
-    BananaMania, Beaver, Bittersweet
+    BananaMania, Beaver, Bittersweet,
+    Black, BlizzardBlue, Blue
 }
 
 // A fixed-size stack vector
 let stack_crayons: [Crayon * 3] = [Almond, AntiqueBrass, Apricot];
 
 // A borrowed pointer to stack allocated vector
-let stack_crayons: &[Crayon] = &[Almond, AntiqueBrass, Apricot];
+let stack_crayons: &[Crayon] = &[Aquamarine, Asparagus, AtomicTangerine];
 
 // A local heap (managed) vector of crayons
-let local_crayons: @[Crayon] = @[Aquamarine, Asparagus, AtomicTangerine];
+let local_crayons: @[Crayon] = @[BananaMania, Beaver, Bittersweet];
 
 // An exchange heap (owned) vector of crayons
-let exchange_crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet];
+let exchange_crayons: ~[Crayon] = ~[Black, BlizzardBlue, Blue];
 ~~~
 
-Vector literals are enclosed in square brackets and dereferencing is
-also done with square brackets (zero-based):
-
-~~~~
-# enum Crayon { Almond, AntiqueBrass, Apricot,
-#               Aquamarine, Asparagus, AtomicTangerine,
-#               BananaMania, Beaver, Bittersweet };
-# fn draw_scene(c: Crayon) { }
-
-let crayons = [BananaMania, Beaver, Bittersweet];
-match crayons[0] {
-    Bittersweet => draw_scene(crayons[0]),
-    _ => ()
-}
-~~~~
-
-By default, vectors are immutable—you can not replace their elements.
-The type written as `[mut T]` is a vector with mutable
-elements. Mutable vector literals are written `[mut]` (empty) or `[mut
-1, 2, 3]` (with elements).
-
-~~~~
-# enum Crayon { Almond, AntiqueBrass, Apricot,
-#               Aquamarine, Asparagus, AtomicTangerine,
-#               BananaMania, Beaver, Bittersweet };
-
-let crayons = [mut BananaMania, Beaver, Bittersweet];
-crayons[0] = AtomicTangerine;
-~~~~
-
 The `+` operator means concatenation when applied to vector types.
 
 ~~~~
@@ -1275,20 +1384,12 @@ The `+` operator means concatenation when applied to vector types.
 let my_crayons = ~[Almond, AntiqueBrass, Apricot];
 let your_crayons = ~[BananaMania, Beaver, Bittersweet];
 
+// Add two vectors to create a new one
 let our_crayons = my_crayons + your_crayons;
-~~~~
-
-The `+=` operator also works as expected, provided the assignee
-lives in a mutable slot.
-
-~~~~
-# enum Crayon { Almond, AntiqueBrass, Apricot,
-#               Aquamarine, Asparagus, AtomicTangerine,
-#               BananaMania, Beaver, Bittersweet };
-
-let mut my_crayons = ~[Almond, AntiqueBrass, Apricot];
-let your_crayons = ~[BananaMania, Beaver, Bittersweet];
 
+// += will append to a vector, provided it leves
+// in a mutable slot
+let mut my_crayons = move my_crayons;
 my_crayons += your_crayons;
 ~~~~
 
@@ -1297,30 +1398,79 @@ my_crayons += your_crayons;
 > not well supported yet, owned vectors are often the most
 > usable.
 
-Strings are simply vectors of `[u8]`, though they have a distinct
-type. They support most of the same allocation aptions as
+Indexing into vectors is done with square brackets:
+
+~~~~
+# enum Crayon { Almond, AntiqueBrass, Apricot,
+#               Aquamarine, Asparagus, AtomicTangerine,
+#               BananaMania, Beaver, Bittersweet };
+# fn draw_scene(c: Crayon) { }
+let crayons: [Crayon * 3] = [BananaMania, Beaver, Bittersweet];
+match crayons[0] {
+    Bittersweet => draw_scene(crayons[0]),
+    _ => ()
+}
+~~~~
+
+The elements of a vector _inherit the mutability of the vector_,
+and as such individual elements may not be reassigned when the
+vector lives in an immutable slot.
+
+~~~ {.xfail-test}
+# enum Crayon { Almond, AntiqueBrass, Apricot,
+#               Aquamarine, Asparagus, AtomicTangerine,
+#               BananaMania, Beaver, Bittersweet };
+let crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet];
+
+crayons[0] = Apricot; // ERROR: Can't assign to immutable vector
+~~~
+
+Moving it into a mutable slot makes the elements assignable.
+
+~~~
+# enum Crayon { Almond, AntiqueBrass, Apricot,
+#               Aquamarine, Asparagus, AtomicTangerine,
+#               BananaMania, Beaver, Bittersweet };
+let crayons: ~[Crayon] = ~[BananaMania, Beaver, Bittersweet];
+
+// Put the vector into a mutable slot
+let mut mutable_crayons = move crayons;
+
+// Now it's mutable to the bone
+mutable_crayons[0] = Apricot;
+~~~
+
+This is a simple example of Rust's _dual-mode data structures_, also
+referred to as _freezing and thawing_.
+
+Strings are implemented with vectors of `u8`, though they have a distinct
+type. They support most of the same allocation options as
 vectors, though the string literal without a storage sigil, e.g.
 `"foo"` is treated differently than a comparable vector (`[foo]`).
-Where
+Whereas plain vectors are stack-allocated fixed-length vectors,
+plain strings are region pointers to read-only memory. Strings
+are always immutable.
 
 ~~~
 // A plain string is a slice to read-only (static) memory
 let stack_crayons: &str = "Almond, AntiqueBrass, Apricot";
 
-// The same thing, but without
-let stack_crayons: &str = &"Almond, AntiqueBrass, Apricot";
+// The same thing, but with the `&`
+let stack_crayons: &str = &"Aquamarine, Asparagus, AtomicTangerine";
 
 // A local heap (managed) string
-let local_crayons: @str = @"Aquamarine, Asparagus, AtomicTangerine";
+let local_crayons: @str = @"BananMania, Beaver, Bittersweet";
 
 // An exchange heap (owned) string
-let exchange_crayons: ~str = ~"BananaMania, Beaver, Bittersweet";
+let exchange_crayons: ~str = ~"Black, BlizzardBlue, Blue";
 ~~~
 
 Both vectors and strings support a number of useful
-[methods](#implementation).  While we haven't covered methods yet,
-most vector functionality is provided by methods, so let's have a
-brief look at a few common ones.
+[methods](#functions-and-methods), defined in [`core::vec`]
+and [`core::str`]. Here are some examples.
+
+[`core::vec`]: core/vec.html
+[`core::str`]: core/str.html
 
 ~~~
 # use io::println;
@@ -1403,7 +1553,7 @@ access local variables in the enclosing scope.
 
 ~~~~
 let mut max = 0;
-(~[1, 2, 3]).map(|x| if *x > max { max = *x });
+[1, 2, 3].map(|x| if *x > max { max = *x });
 ~~~~
 
 Stack closures are very efficient because their environment is
@@ -1431,8 +1581,7 @@ This code creates a closure that adds a given string to its argument,
 returns it from a function, and then calls it:
 
 ~~~~
-extern mod std;
-
+# extern mod std;
 fn mk_appender(suffix: ~str) -> fn@(~str) -> ~str {
     return fn@(s: ~str) -> ~str { s + suffix };
 }
@@ -1479,7 +1628,7 @@ fn call_twice(f: fn()) { f(); f(); }
 call_twice(|| { ~"I am an inferred stack closure"; } );
 call_twice(fn&() { ~"I am also a stack closure"; } );
 call_twice(fn@() { ~"I am a managed closure"; });
-call_twice(fn~() { ~"I am a owned closure"; });
+call_twice(fn~() { ~"I am an owned closure"; });
 fn bare_function() { ~"I am a plain function"; }
 call_twice(bare_function);
 ~~~~
@@ -1490,9 +1639,12 @@ call_twice(bare_function);
 
 ## Do syntax
 
-Closures in Rust are frequently used in combination with higher-order
-functions to simulate control structures like `if` and
-`loop`. Consider this function that iterates over a vector of
+The `do` expression is syntactic sugar for use with functions which
+take a closure as a final argument, because closures in Rust
+are so frequently used in combination with higher-order
+functions.
+
+Consider this function which iterates over a vector of
 integers, passing in a pointer to each integer in the vector:
 
 ~~~~
@@ -1537,8 +1689,7 @@ do each(&[1, 2, 3]) |n| {
 The call is prefixed with the keyword `do` and, instead of writing the
 final closure inside the argument list it is moved outside of the
 parenthesis where it looks visually more like a typical block of
-code. The `do` expression is purely syntactic sugar for a call that
-takes a final closure argument.
+code.
 
 `do` is often used for task spawning.
 
@@ -1632,6 +1783,10 @@ fn contains(v: &[int], elt: int) -> bool {
 
 `for` syntax only works with stack closures.
 
+> ***Note:*** This is, essentially, a special loop protocol:
+> the keywords `break`, `loop`, and `return` work, in varying degree,
+> with `while`, `loop`, `do`, and `for` constructs.
+
 # Generics
 
 Throughout this tutorial, we've been defining functions that act only on
@@ -2036,6 +2191,9 @@ The compiler will now look for `poultry/chicken.rs` and
 and `poultry::turkey`. You can also provide a `poultry.rs` to add
 content to the `poultry` module itself.
 
+The compiler then builds the crate as a platform-specific shared library or
+executable which can be distributed.
+
 ## Using other crates
 
 Having compiled a crate that contains the `#[crate_type = "lib"]`
@@ -2082,7 +2240,7 @@ Rust program.
 
 This library is documented [here][core].
 
-[core]: http://doc.rust-lang.org/doc/core
+[core]: core/index.html
 
 ## A minimal example
 
@@ -2090,22 +2248,22 @@ Now for something that you can actually compile yourself. We have
 these two files:
 
 ~~~~
-// mylib.rs
-#[link(name = "mylib", vers = "1.0")];
-fn world() -> ~str { ~"world" }
+// world.rs
+#[link(name = "world", vers = "1.0")];
+fn explore() -> ~str { ~"world" }
 ~~~~
 
 ~~~~ {.ignore}
 // main.rs
-extern mod mylib;
-fn main() { io::println(~"hello " + mylib::world()); }
+extern mod world;
+fn main() { io::println(~"hello " + world::explore()); }
 ~~~~
 
 Now compile and run like this (adjust to your platform if necessary):
 
 ~~~~ {.notrust}
-> rustc --lib mylib.rs
-> rustc main.rs -L .
+> rustc --lib world.rs  # compiles libworld-94839cbfe144198-1.0.so
+> rustc main.rs -L .    # compiles main
 > ./main
 "hello world"
 ~~~~
@@ -2125,12 +2283,14 @@ fn main() {
 }
 ~~~~
 
+
 It is also possible to import just the name of a module (`use
 std::list;`, then use `list::find`), to import all identifiers exported
 by a given module (`use io::*`), or to import a specific set
 of identifiers (`use math::{min, max, pi}`).
 
-You can rename an identifier when importing using the `=` operator:
+Rust uses different namespaces for modules, types, and values.  You
+can also rename an identifier when importing using the `=` operator:
 
 ~~~~
 use prnt = io::println;
@@ -2154,27 +2314,6 @@ This defines a rock-solid encryption algorithm. Code outside of the
 module can refer to the `enc::encrypt` and `enc::decrypt` identifiers
 just fine, but it does not have access to `enc::super_secret_number`.
 
-## Namespaces
-
-Rust uses three different namespaces: one for modules, one for types,
-and one for values. This means that this code is valid:
-
-~~~~
-#[legacy_exports]
-mod buffalo {
-    type buffalo = int;
-    fn buffalo(+buffalo: buffalo) -> buffalo { buffalo }
-}
-fn main() {
-    let buffalo: buffalo::buffalo = 1;
-    buffalo::buffalo::(buffalo::buffalo(buffalo));
-}
-~~~~
-
-You don't want to write things like that, but it *is* very practical
-to not have to worry about name clashes between types, values, and
-modules.
-
 ## Resolution
 
 The resolution process in Rust simply goes up the chain of contexts,
@@ -2190,7 +2329,7 @@ Identifiers can shadow each other. In this program, `x` is of type
 type MyType = ~str;
 fn main() {
     type MyType = int;
-    let x: MyType;
+    let x: MyType = 17;
 }
 ~~~~
 
@@ -2198,13 +2337,17 @@ An `use` directive will only import into the namespaces for which
 identifiers are actually found. Consider this example:
 
 ~~~~
-mod foo { fn bar() {} }
-fn baz() {
-    let bar = 10u;
+mod foo {
+   fn bar() {}
+}
+
+fn main() {
+    let bar = 10;
 
     {
         use foo::bar;
         let quux = bar;
+        assert quux == 10;
     }
 }
 ~~~~
diff --git a/mk/stage0.mk b/mk/stage0.mk
index e55b9f70c8ff..b64f5df9ca03 100644
--- a/mk/stage0.mk
+++ b/mk/stage0.mk
@@ -12,6 +12,10 @@ ifdef CFG_ENABLE_LOCAL_RUST
 	$(Q)$(S)src/etc/local_stage0.sh $(CFG_HOST_TRIPLE) $(CFG_LOCAL_RUST_ROOT)
 else 
 	$(Q)$(S)src/etc/get-snapshot.py $(CFG_HOST_TRIPLE) $(SNAPSHOT_FILE)
+ifdef CFG_ENABLE_PAX_FLAGS
+	@$(call E, apply PaX flags: $@)
+	@"$(CFG_PAXCTL)" -cm "$@"
+endif
 endif 
 	$(Q)touch $@
 
diff --git a/mk/target.mk b/mk/target.mk
index 5ddc825d335b..967191ab7450 100644
--- a/mk/target.mk
+++ b/mk/target.mk
@@ -29,6 +29,10 @@ $$(TBIN$(1)_T_$(2)_H_$(3))/rustc$$(X):				\
 		$$(TLIBRUSTC_DEFAULT$(1)_T_$(2)_H_$(3))
 	@$$(call E, compile_and_link: $$@)
 	$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$<
+ifdef CFG_ENABLE_PAX_FLAGS
+	@$$(call E, apply PaX flags: $$@)
+	@"$(CFG_PAXCTL)" -cm "$$@"
+endif
 
 $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_LIBRUSTC):		\
 		$$(COMPILER_CRATE) $$(COMPILER_INPUTS)		\
diff --git a/src/README.txt b/src/README.txt
index 2086765b6f9e..5e0d9bd0e841 100644
--- a/src/README.txt
+++ b/src/README.txt
@@ -1,4 +1,4 @@
-This is preliminary version of the Rust compiler, libraries and tools
+This is a preliminary version of the Rust compiler, libraries and tools
 
 Source layout:
 
diff --git a/src/cargo/cargo.rs b/src/cargo/cargo.rs
index 211b048de7a3..179a8941587f 100644
--- a/src/cargo/cargo.rs
+++ b/src/cargo/cargo.rs
@@ -1889,7 +1889,8 @@ Commands:
     set-method      Change the method for a source.");
 }
 
-fn main(argv: ~[~str]) {
+fn main() {
+    let argv = os::args();
     let o = build_cargo_options(argv);
 
     if vec::len(o.free) < 2u {
diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs
index 264ee61018bf..55fa67402687 100644
--- a/src/compiletest/compiletest.rs
+++ b/src/compiletest/compiletest.rs
@@ -12,7 +12,8 @@ use common::mode_pretty;
 use common::mode;
 use util::logv;
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let config = parse_config(args);
     log_config(config);
     run_tests(config);
diff --git a/src/etc/combine-tests.py b/src/etc/combine-tests.py
index 7016713f2fee..1e3c0bcfbfc3 100755
--- a/src/etc/combine-tests.py
+++ b/src/etc/combine-tests.py
@@ -19,7 +19,6 @@ if not src_dir:
 run_pass = os.path.join(src_dir, "src", "test", "run-pass")
 run_pass = os.path.abspath(run_pass)
 stage2_tests = []
-take_args = {}
 
 for t in os.listdir(run_pass):
     if t.endswith(".rs") and not (
@@ -30,8 +29,6 @@ for t in os.listdir(run_pass):
                 "xfail-fast" in s or
                 "xfail-win32" in s):
             stage2_tests.append(t)
-            if "fn main(args:" in s or "fn main(++args:" in s:
-                take_args[t] = True
         f.close()
 
 stage2_tests.sort()
@@ -64,9 +61,6 @@ for t in stage2_tests:
     p = os.path.join("test", "run-pass", t)
     p = p.replace("\\", "\\\\")
     d.write("    out.write_str(~\"run-pass [stage2]: %s\\n\");\n" % p)
-    if t in take_args:
-        d.write("    t_%d::main(~[~\"arg0\"]);\n" % i)
-    else:
-        d.write("    t_%d::main();\n" % i)
+    d.write("    t_%d::main();\n" % i)
     i += 1
 d.write("}\n")
diff --git a/src/fuzzer/fuzzer.rs b/src/fuzzer/fuzzer.rs
index cd312362d6a4..3e31287e3cd1 100644
--- a/src/fuzzer/fuzzer.rs
+++ b/src/fuzzer/fuzzer.rs
@@ -599,7 +599,8 @@ fn check_variants(files: &[Path], cx: context) {
     }
 }
 
-fn main(args: ~[~str]) {
+fn main() {
+    let args = os::args();
     if vec::len(args) != 2u {
         error!("usage: %s ", args[0]);
         return;
diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs
index 7d410c0337ad..ce3dec89e418 100644
--- a/src/libcore/at_vec.rs
+++ b/src/libcore/at_vec.rs
@@ -1,7 +1,7 @@
 //! Managed vectors
 
 // NB: transitionary, de-mode-ing.
-// tjc: re-forbid deprecated modes after snapshot
+#[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
 use cast::transmute;
@@ -21,7 +21,7 @@ extern mod rustrt {
 #[abi = "rust-intrinsic"]
 extern mod rusti {
     #[legacy_exports];
-    fn move_val_init(&dst: T, -src: T);
+    fn move_val_init(dst: &mut T, -src: T);
 }
 
 /// Returns the number of elements the vector can hold without reallocating
@@ -176,7 +176,7 @@ pub mod raw {
             push_slow(v, move initval);
         }
     }
-    // This doesn't bother to make sure we have space.
+
     #[inline(always)] // really pretty please
     pub unsafe fn push_fast(v: &mut @[const T], initval: T) {
         let repr: **VecRepr = ::cast::reinterpret_cast(&v);
@@ -184,7 +184,7 @@ pub mod raw {
         (**repr).unboxed.fill += sys::size_of::();
         let p = addr_of(&((**repr).unboxed.data));
         let p = ptr::offset(p, fill) as *mut T;
-        rusti::move_val_init(*p, move initval);
+        rusti::move_val_init(&mut(*p), move initval);
     }
 
     pub unsafe fn push_slow(v: &mut @[const T], initval: T) {
diff --git a/src/libcore/cast.rs b/src/libcore/cast.rs
index f4f0d7b61044..030f05c6eeae 100644
--- a/src/libcore/cast.rs
+++ b/src/libcore/cast.rs
@@ -1,4 +1,5 @@
 //! Unsafe operations
+#[forbid(deprecated_mode)]
 
 #[abi = "rust-intrinsic"]
 extern mod rusti {
@@ -18,7 +19,7 @@ pub unsafe fn reinterpret_cast(src: &T) -> U {
  * The forget function will take ownership of the provided value but neglect
  * to run any required cleanup or memory-management operations on it. This
  * can be used for various acts of magick, particularly when using
- * reinterpret_cast on managed pointer types.
+ * reinterpret_cast on pointer types.
  */
 #[inline(always)]
 pub unsafe fn forget(thing: T) { rusti::forget(move thing); }
diff --git a/src/libcore/cmath.rs b/src/libcore/cmath.rs
index 9a9a7cb31121..b0aeb78afaa8 100644
--- a/src/libcore/cmath.rs
+++ b/src/libcore/cmath.rs
@@ -40,15 +40,15 @@ pub extern mod c_double {
     #[link_name="fmax"] pure fn fmax(a: c_double, b: c_double) -> c_double;
     #[link_name="fmin"] pure fn fmin(a: c_double, b: c_double) -> c_double;
     pure fn nextafter(x: c_double, y: c_double) -> c_double;
-    pure fn frexp(n: c_double, &value: c_int) -> c_double;
+    pure fn frexp(n: c_double, value: &mut c_int) -> c_double;
     pure fn hypot(x: c_double, y: c_double) -> c_double;
     pure fn ldexp(x: c_double, n: c_int) -> c_double;
     #[cfg(unix)]
     #[link_name="lgamma_r"] pure fn lgamma(n: c_double,
-                                           &sign: c_int) -> c_double;
+                                           sign: &mut c_int) -> c_double;
     #[cfg(windows)]
     #[link_name="__lgamma_r"] pure fn lgamma(n: c_double,
-                                             &sign: c_int) -> c_double;
+                                             sign: &mut c_int) -> c_double;
     // renamed: log is a reserved keyword; ln seems more natural, too
     #[link_name="log"] pure fn ln(n: c_double) -> c_double;
     // renamed: "logb" /often/ is confused for log2 by beginners
@@ -58,7 +58,7 @@ pub extern mod c_double {
     pure fn log10(n: c_double) -> c_double;
     pure fn log2(n: c_double) -> c_double;
     #[link_name="ilogb"] pure fn ilog_radix(n: c_double) -> c_int;
-    pure fn modf(n: c_double, &iptr: c_double) -> c_double;
+    pure fn modf(n: c_double, iptr: &mut c_double) -> c_double;
     pure fn pow(n: c_double, e: c_double) -> c_double;
 // FIXME (#1379): enable when rounding modes become available
 //    pure fn rint(n: c_double) -> c_double;
@@ -110,7 +110,7 @@ pub extern mod c_float {
     #[link_name="fdimf"] pure fn abs_sub(a: c_float, b: c_float) -> c_float;
     #[link_name="floorf"] pure fn floor(n: c_float) -> c_float;
     #[link_name="frexpf"] pure fn frexp(n: c_float,
-                                        &value: c_int) -> c_float;
+                                        value: &mut c_int) -> c_float;
     #[link_name="fmaf"] pure fn mul_add(a: c_float,
                                         b: c_float, c: c_float) -> c_float;
     #[link_name="fmaxf"] pure fn fmax(a: c_float, b: c_float) -> c_float;
@@ -122,11 +122,11 @@ pub extern mod c_float {
 
     #[cfg(unix)]
     #[link_name="lgammaf_r"] pure fn lgamma(n: c_float,
-                                            &sign: c_int) -> c_float;
+                                            sign: &mut c_int) -> c_float;
 
     #[cfg(windows)]
     #[link_name="__lgammaf_r"] pure fn lgamma(n: c_float,
-                                              &sign: c_int) -> c_float;
+                                              sign: &mut c_int) -> c_float;
 
     #[link_name="logf"] pure fn ln(n: c_float) -> c_float;
     #[link_name="logbf"] pure fn log_radix(n: c_float) -> c_float;
@@ -135,7 +135,7 @@ pub extern mod c_float {
     #[link_name="log10f"] pure fn log10(n: c_float) -> c_float;
     #[link_name="ilogbf"] pure fn ilog_radix(n: c_float) -> c_int;
     #[link_name="modff"] pure fn modf(n: c_float,
-                                      &iptr: c_float) -> c_float;
+                                      iptr: &mut c_float) -> c_float;
     #[link_name="powf"] pure fn pow(n: c_float, e: c_float) -> c_float;
 // FIXME (#1379): enable when rounding modes become available
 //    #[link_name="rintf"] pure fn rint(n: c_float) -> c_float;
diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs
index 64c38d13e493..c9cd1a21b454 100644
--- a/src/libcore/comm.rs
+++ b/src/libcore/comm.rs
@@ -32,8 +32,8 @@ will once again be the preferred module for intertask communication.
 
 */
 
-// NB: transitionary, de-mode-ing
-// tjc: re-forbid deprecated modes after snapshot
+// NB: transitionary, de-mode-ing.
+#[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
 use either::Either;
@@ -74,7 +74,7 @@ pub fn Port() -> Port {
 
 impl Port {
 
-    fn chan() -> Chan { Chan(self) }
+    fn chan() -> Chan { Chan(&self) }
     fn send(v: T) { self.chan().send(move v) }
     fn recv() -> T { recv(self) }
     fn peek() -> bool { peek(self) }
@@ -166,7 +166,7 @@ fn as_raw_port(ch: comm::Chan, f: fn(*rust_port) -> U) -> U {
  * Constructs a channel. The channel is bound to the port used to
  * construct it.
  */
-pub fn Chan(&&p: Port) -> Chan {
+pub fn Chan(p: &Port) -> Chan {
     Chan_(rustrt::get_port_id((**p).po))
 }
 
@@ -304,19 +304,19 @@ extern mod rusti {
 
 
 #[test]
-fn create_port_and_chan() { let p = Port::(); Chan(p); }
+fn create_port_and_chan() { let p = Port::(); Chan(&p); }
 
 #[test]
 fn send_int() {
     let p = Port::();
-    let c = Chan(p);
+    let c = Chan(&p);
     send(c, 22);
 }
 
 #[test]
 fn send_recv_fn() {
     let p = Port::();
-    let c = Chan::(p);
+    let c = Chan::(&p);
     send(c, 42);
     assert (recv(p) == 42);
 }
@@ -324,7 +324,7 @@ fn send_recv_fn() {
 #[test]
 fn send_recv_fn_infer() {
     let p = Port();
-    let c = Chan(p);
+    let c = Chan(&p);
     send(c, 42);
     assert (recv(p) == 42);
 }
@@ -332,23 +332,23 @@ fn send_recv_fn_infer() {
 #[test]
 fn chan_chan_infer() {
     let p = Port(), p2 = Port::();
-    let c = Chan(p);
-    send(c, Chan(p2));
+    let c = Chan(&p);
+    send(c, Chan(&p2));
     recv(p);
 }
 
 #[test]
 fn chan_chan() {
     let p = Port::>(), p2 = Port::();
-    let c = Chan(p);
-    send(c, Chan(p2));
+    let c = Chan(&p);
+    send(c, Chan(&p2));
     recv(p);
 }
 
 #[test]
 fn test_peek() {
     let po = Port();
-    let ch = Chan(po);
+    let ch = Chan(&po);
     assert !peek(po);
     send(ch, ());
     assert peek(po);
@@ -360,8 +360,8 @@ fn test_peek() {
 fn test_select2_available() {
     let po_a = Port();
     let po_b = Port();
-    let ch_a = Chan(po_a);
-    let ch_b = Chan(po_b);
+    let ch_a = Chan(&po_a);
+    let ch_b = Chan(&po_b);
 
     send(ch_a, ~"a");
 
@@ -376,8 +376,8 @@ fn test_select2_available() {
 fn test_select2_rendezvous() {
     let po_a = Port();
     let po_b = Port();
-    let ch_a = Chan(po_a);
-    let ch_b = Chan(po_b);
+    let ch_a = Chan(&po_a);
+    let ch_b = Chan(&po_b);
 
     for iter::repeat(10) {
         do task::spawn {
@@ -400,8 +400,8 @@ fn test_select2_rendezvous() {
 fn test_select2_stress() {
     let po_a = Port();
     let po_b = Port();
-    let ch_a = Chan(po_a);
-    let ch_b = Chan(po_b);
+    let ch_a = Chan(&po_a);
+    let ch_b = Chan(&po_b);
 
     let msgs = 100;
     let times = 4u;
@@ -436,7 +436,7 @@ fn test_select2_stress() {
 #[test]
 fn test_recv_chan() {
     let po = Port();
-    let ch = Chan(po);
+    let ch = Chan(&po);
     send(ch, ~"flower");
     assert recv_chan(ch) == ~"flower";
 }
@@ -445,7 +445,7 @@ fn test_recv_chan() {
 #[should_fail]
 #[ignore(cfg(windows))]
 fn test_recv_chan_dead() {
-    let ch = Chan(Port());
+    let ch = Chan(&Port());
     send(ch, ~"flower");
     recv_chan(ch);
 }
@@ -454,7 +454,7 @@ fn test_recv_chan_dead() {
 #[ignore(cfg(windows))]
 fn test_recv_chan_wrong_task() {
     let po = Port();
-    let ch = Chan(po);
+    let ch = Chan(&po);
     send(ch, ~"flower");
     assert result::is_err(&task::try(||
         recv_chan(ch)
diff --git a/src/libcore/core.rc b/src/libcore/core.rc
index 818e1e890ec9..94e6decc4ca8 100644
--- a/src/libcore/core.rc
+++ b/src/libcore/core.rc
@@ -36,227 +36,185 @@ Implicitly, all crates behave as if they included the following prologue:
 // Don't link to core. We are core.
 #[no_core];
 
-#[legacy_exports];
-
 #[warn(deprecated_mode)];
 #[warn(deprecated_pattern)];
 
 #[warn(vecs_implicitly_copyable)];
 #[deny(non_camel_case_types)];
 
-export int, i8, i16, i32, i64;
-export uint, u8, u16, u32, u64;
-export float, f32, f64;
-export box, char, str, ptr, vec, at_vec, bool;
-export either, option, result, iter;
-export gc, io, libc, os, run, rand, sys, cast, logging;
-export comm, task, future, pipes;
-export extfmt;
-// The test harness links against core, so don't include runtime in tests.
-// FIXME (#2861): Uncomment this after snapshot gets updated.
-//#[cfg(notest)]
-export rt;
-export tuple;
-export to_str, to_bytes;
-export from_str;
-export util;
-export dvec, dvec_iter;
-export dlist, dlist_iter;
-export send_map;
-export hash;
-export cmp;
-export num;
-export path;
-export mutable;
-export flate;
-export unit;
-export uniq;
-export repr;
-export cleanup;
-export reflect;
-
-// NDM seems to be necessary for resolve to work
-export option_iter;
-
-// This creates some APIs that I do not want to commit to, but it must be
-// exported from core in order for uv to remain in std (see #2648).
-export private;
-
-
 // Built-in-type support modules
 
 /// Operations and constants for `int`
 #[path = "int-template"]
-mod int {
+pub mod int {
     pub use inst::{ pow };
     #[path = "int.rs"]
-    mod inst;
+    pub mod inst;
 }
 
 /// Operations and constants for `i8`
 #[path = "int-template"]
-mod i8 {
+pub mod i8 {
     #[path = "i8.rs"]
-    mod inst;
+    pub mod inst;
 }
 
 /// Operations and constants for `i16`
 #[path = "int-template"]
-mod i16 {
+pub mod i16 {
     #[path = "i16.rs"]
-    mod inst;
+    pub mod inst;
 }
 
 /// Operations and constants for `i32`
 #[path = "int-template"]
-mod i32 {
+pub mod i32 {
     #[path = "i32.rs"]
-    mod inst;
+    pub mod inst;
 }
 
 /// Operations and constants for `i64`
 #[path = "int-template"]
-mod i64 {
+pub mod i64 {
     #[path = "i64.rs"]
-    mod inst;
+    pub mod inst;
 }
 
 /// Operations and constants for `uint`
 #[path = "uint-template"]
-mod uint {
+pub mod uint {
     pub use inst::{
         div_ceil, div_round, div_floor, iterate,
         next_power_of_two
     };
     #[path = "uint.rs"]
-    mod inst;
+    pub mod inst;
 }
 
 /// Operations and constants for `u8`
 #[path = "uint-template"]
-mod u8 {
+pub mod u8 {
     pub use inst::is_ascii;
     #[path = "u8.rs"]
-    mod inst;
+    pub mod inst;
 }
 
 /// Operations and constants for `u16`
 #[path = "uint-template"]
-mod u16 {
+pub mod u16 {
     #[path = "u16.rs"]
-    mod inst;
+    pub mod inst;
 }
 
 /// Operations and constants for `u32`
 #[path = "uint-template"]
-mod u32 {
+pub mod u32 {
     #[path = "u32.rs"]
-    mod inst;
+    pub mod inst;
 }
 
 /// Operations and constants for `u64`
 #[path = "uint-template"]
-mod u64 {
+pub mod u64 {
     #[path = "u64.rs"]
-    mod inst;
+    pub mod inst;
 }
 
 
-mod box;
-mod char;
-mod float;
-mod f32;
-mod f64;
-mod str;
-mod ptr;
-mod vec;
-mod at_vec;
-mod bool;
-mod tuple;
-mod unit;
-mod uniq;
+pub mod box;
+pub mod char;
+pub mod float;
+pub mod f32;
+pub mod f64;
+pub mod str;
+pub mod ptr;
+pub mod vec;
+pub mod at_vec;
+pub mod bool;
+pub mod tuple;
+pub mod unit;
+pub mod uniq;
 
 // Ubiquitous-utility-type modules
 
 #[cfg(notest)]
-mod ops;
-mod cmp;
-mod num;
-mod hash;
-mod either;
-mod iter;
-mod logging;
-mod option;
+pub mod ops;
+pub mod cmp;
+pub mod num;
+pub mod hash;
+pub mod either;
+pub mod iter;
+pub mod logging;
+pub mod option;
 #[path="iter-trait"]
-mod option_iter {
+pub mod option_iter {
     #[path = "option.rs"]
-    mod inst;
+    pub mod inst;
 }
-mod result;
-mod to_str;
-mod to_bytes;
-mod from_str;
-mod util;
+pub mod result;
+pub mod to_str;
+pub mod to_bytes;
+pub mod from_str;
+pub mod util;
 
 // Data structure modules
 
-mod dvec;
+pub mod dvec;
 #[path="iter-trait"]
-mod dvec_iter {
+pub mod dvec_iter {
     #[path = "dvec.rs"]
-    mod inst;
+    pub mod inst;
 }
-mod dlist;
+pub mod dlist;
 #[path="iter-trait"]
-mod dlist_iter {
+pub mod dlist_iter {
     #[path ="dlist.rs"]
-    mod inst;
+    pub mod inst;
 }
-mod send_map;
+pub mod send_map;
 
 // Concurrency
-mod comm;
-mod task {
+pub mod comm;
+pub mod task {
     pub mod local_data;
     mod local_data_priv;
     pub mod spawn;
     pub mod rt;
 }
-mod future;
-mod pipes;
+pub mod future;
+pub mod pipes;
 
 // Runtime and language-primitive support
 
-mod gc;
-mod io;
-mod libc;
-mod os;
-mod path;
-mod rand;
-mod run;
-mod sys;
-mod cast;
-mod mutable;
-mod flate;
-mod repr;
-mod cleanup;
-mod reflect;
+pub mod gc;
+pub mod io;
+pub mod libc;
+pub mod os;
+pub mod path;
+pub mod rand;
+pub mod run;
+pub mod sys;
+pub mod cast;
+pub mod mutable;
+pub mod flate;
+pub mod repr;
+pub mod cleanup;
+pub mod reflect;
 
 // Modules supporting compiler-generated code
 // Exported but not part of the public interface
 
-#[legacy_exports]
-mod extfmt;
+pub mod extfmt;
 // The test harness links against core, so don't include runtime in tests.
 #[cfg(notest)]
 #[legacy_exports]
-mod rt;
+pub mod rt;
 
+// Ideally not exported, but currently is.
+pub mod private;
 
-// For internal use, not exported
-
+// For internal use, not exported.
 mod unicode;
-mod private;
 mod cmath;
 mod stackwalk;
 
diff --git a/src/libcore/core.rs b/src/libcore/core.rs
index c7261aa8c29c..a14b67b40f13 100644
--- a/src/libcore/core.rs
+++ b/src/libcore/core.rs
@@ -2,101 +2,76 @@
 
 // Export various ubiquitous types, constructors, methods.
 
-use option::{Some, None};
-use Option = option::Option;
-use result::{Result, Ok, Err};
+pub use option::{Some, None};
+pub use Option = option::Option;
+pub use result::{Result, Ok, Err};
 
-use Path = path::Path;
-use GenericPath = path::GenericPath;
-use WindowsPath = path::WindowsPath;
-use PosixPath = path::PosixPath;
+pub use Path = path::Path;
+pub use GenericPath = path::GenericPath;
+pub use WindowsPath = path::WindowsPath;
+pub use PosixPath = path::PosixPath;
 
-use tuple::{TupleOps, ExtendedTupleOps};
-use str::{StrSlice, UniqueStr};
-use vec::{ConstVector, CopyableVector, ImmutableVector};
-use vec::{ImmutableEqVector, ImmutableCopyableVector};
-use vec::{MutableVector, MutableCopyableVector};
-use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
-use iter::{CopyableOrderedIter, Times, TimesIx};
-use num::Num;
-use ptr::Ptr;
-use to_str::ToStr;
-
-export Path, WindowsPath, PosixPath, GenericPath;
-export Option, Some, None;
-export Result, Ok, Err;
-export extensions;
-// The following exports are the extension impls for numeric types
-export Num, Times, TimesIx;
-// The following exports are the common traits
-export StrSlice, UniqueStr;
-export ConstVector, CopyableVector, ImmutableVector;
-export ImmutableEqVector, ImmutableCopyableVector, IterTraitExtensions;
-export MutableVector, MutableCopyableVector;
-export BaseIter, CopyableIter, CopyableOrderedIter, ExtendedIter, EqIter;
-export TupleOps, ExtendedTupleOps;
-export Ptr;
-export ToStr;
+pub use tuple::{TupleOps, ExtendedTupleOps};
+pub use str::{StrSlice, UniqueStr};
+pub use vec::{ConstVector, CopyableVector, ImmutableVector};
+pub use vec::{ImmutableEqVector, ImmutableCopyableVector};
+pub use vec::{MutableVector, MutableCopyableVector};
+pub use iter::{BaseIter, ExtendedIter, EqIter, CopyableIter};
+pub use iter::{CopyableOrderedIter, Times, TimesIx};
+pub use num::Num;
+pub use ptr::Ptr;
+pub use to_str::ToStr;
 
 // The following exports are the core operators and kinds
 // The compiler has special knowlege of these so we must not duplicate them
 // when compiling for testing
 #[cfg(notest)]
-use ops::{Const, Copy, Send, Owned};
+pub use ops::{Const, Copy, Send, Owned};
 #[cfg(notest)]
-use ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr, BitXor};
+pub use ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr, BitXor};
 #[cfg(notest)]
-use ops::{Shl, Shr, Index};
-
-#[cfg(notest)]
-export Const, Copy, Send, Owned;
-#[cfg(notest)]
-export Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr, BitXor;
-#[cfg(notest)]
-export Shl, Shr, Index;
+pub use ops::{Shl, Shr, Index};
 
 #[cfg(test)]
 extern mod coreops(name = "core", vers = "0.4");
 
 #[cfg(test)]
-use coreops::ops::{Const, Copy, Send, Owned};
+pub use coreops::ops::{Const, Copy, Send, Owned};
 #[cfg(test)]
-use coreops::ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr, BitXor};
+pub use coreops::ops::{Add, Sub, Mul, Div, Modulo, Neg, BitAnd, BitOr};
 #[cfg(test)]
-use coreops::ops::{Shl, Shr, Index};
+pub use coreops::ops::{BitXor};
+#[cfg(test)]
+pub use coreops::ops::{Shl, Shr, Index};
 
 
 // Export the log levels as global constants. Higher levels mean
 // more-verbosity. Error is the bottom level, default logging level is
 // warn-and-below.
 
-export error, warn, info, debug;
-
 /// The error log level
-const error : u32 = 0_u32;
+pub const error : u32 = 0_u32;
 /// The warning log level
-const warn : u32 = 1_u32;
+pub const warn : u32 = 1_u32;
 /// The info log level
-const info : u32 = 2_u32;
+pub const info : u32 = 2_u32;
 /// The debug log level
-const debug : u32 = 3_u32;
+pub const debug : u32 = 3_u32;
 
 // A curious inner-module that's not exported that contains the binding
 // 'core' so that macro-expanded references to core::error and such
 // can be resolved within libcore.
 #[doc(hidden)] // FIXME #3538
 mod core {
-    #[legacy_exports];
-    const error : u32 = 0_u32;
-    const warn : u32 = 1_u32;
-    const info : u32 = 2_u32;
-    const debug : u32 = 3_u32;
+    pub const error : u32 = 0_u32;
+    pub const warn : u32 = 1_u32;
+    pub const info : u32 = 2_u32;
+    pub const debug : u32 = 3_u32;
 }
 
 // Similar to above. Some magic to make core testable.
 #[cfg(test)]
 mod std {
-    #[legacy_exports];
     extern mod std(vers = "0.4");
-    use std::test;
+    pub use std::test;
 }
diff --git a/src/libcore/dlist.rs b/src/libcore/dlist.rs
index 17ddd6ea73b7..3bcf486ef7e0 100644
--- a/src/libcore/dlist.rs
+++ b/src/libcore/dlist.rs
@@ -9,7 +9,7 @@ Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate.
 */
 
 // NB: transitionary, de-mode-ing.
-// tjc: re-forbid deprecated modes after snapshot
+#[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
 type DListLink = Option>;
diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs
index a2a709087971..1540eb30fe5a 100644
--- a/src/libcore/dvec.rs
+++ b/src/libcore/dvec.rs
@@ -10,7 +10,7 @@ Note that recursive use is not permitted.
 */
 
 // NB: transitionary, de-mode-ing.
-// tjc: re-forbid deprecated modes after snapshot
+#[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
 use cast::reinterpret_cast;
diff --git a/src/libcore/either.rs b/src/libcore/either.rs
index c64cd25e4813..7500ff409a41 100644
--- a/src/libcore/either.rs
+++ b/src/libcore/either.rs
@@ -1,5 +1,5 @@
 // NB: transitionary, de-mode-ing.
-// tjc: re-forbid deprecated modes after snapshot
+#[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
 //! A type that represents one of two alternatives
diff --git a/src/libcore/extfmt.rs b/src/libcore/extfmt.rs
index e10ff4bac714..de2e91b2e326 100644
--- a/src/libcore/extfmt.rs
+++ b/src/libcore/extfmt.rs
@@ -1,4 +1,7 @@
 #[doc(hidden)];
+// NB: transitionary, de-mode-ing.
+#[forbid(deprecated_mode)];
+#[forbid(deprecated_pattern)];
 
 /*
 Syntax Extension: fmt
@@ -41,11 +44,10 @@ use option::{Some, None};
  */
 
 // Functions used by the fmt extension at compile time
-mod ct {
-    #[legacy_exports];
-    enum Signedness { Signed, Unsigned, }
-    enum Caseness { CaseUpper, CaseLower, }
-    enum Ty {
+pub mod ct {
+    pub enum Signedness { Signed, Unsigned, }
+    pub enum Caseness { CaseUpper, CaseLower, }
+    pub enum Ty {
         TyBool,
         TyStr,
         TyChar,
@@ -56,14 +58,14 @@ mod ct {
         TyFloat,
         TyPoly,
     }
-    enum Flag {
+    pub enum Flag {
         FlagLeftJustify,
         FlagLeftZeroPad,
         FlagSpaceForSign,
         FlagSignAlways,
         FlagAlternate,
     }
-    enum Count {
+    pub enum Count {
         CountIs(int),
         CountIsParam(int),
         CountIsNextParam,
@@ -71,7 +73,7 @@ mod ct {
     }
 
     // A formatted conversion from an expression to a string
-    type Conv =
+    pub type Conv =
         {param: Option,
          flags: ~[Flag],
          width: Count,
@@ -80,10 +82,10 @@ mod ct {
 
 
     // A fragment of the output sequence
-    enum Piece { PieceString(~str), PieceConv(Conv), }
-    type ErrorFn = fn@(&str) -> ! ;
+    pub enum Piece { PieceString(~str), PieceConv(Conv), }
+    pub type ErrorFn = fn@(&str) -> ! ;
 
-    fn parse_fmt_string(s: &str, error: ErrorFn) -> ~[Piece] {
+    pub fn parse_fmt_string(s: &str, error: ErrorFn) -> ~[Piece] {
         let mut pieces: ~[Piece] = ~[];
         let lim = str::len(s);
         let mut buf = ~"";
@@ -118,7 +120,7 @@ mod ct {
         flush_buf(move buf, &mut pieces);
         move pieces
     }
-    fn peek_num(s: &str, i: uint, lim: uint) ->
+    pub fn peek_num(s: &str, i: uint, lim: uint) ->
        Option<{num: uint, next: uint}> {
         let mut j = i;
         let mut accum = 0u;
@@ -140,7 +142,8 @@ mod ct {
             None
         }
     }
-    fn parse_conversion(s: &str, i: uint, lim: uint, error: ErrorFn) ->
+    pub fn parse_conversion(s: &str, i: uint, lim: uint,
+                            error: ErrorFn) ->
        {piece: Piece, next: uint} {
         let parm = parse_parameter(s, i, lim);
         let flags = parse_flags(s, parm.next, lim);
@@ -155,7 +158,7 @@ mod ct {
                              ty: ty.ty}),
              next: ty.next};
     }
-    fn parse_parameter(s: &str, i: uint, lim: uint) ->
+    pub fn parse_parameter(s: &str, i: uint, lim: uint) ->
        {param: Option, next: uint} {
         if i >= lim { return {param: None, next: i}; }
         let num = peek_num(s, i, lim);
@@ -170,7 +173,7 @@ mod ct {
               }
             };
     }
-    fn parse_flags(s: &str, i: uint, lim: uint) ->
+    pub fn parse_flags(s: &str, i: uint, lim: uint) ->
        {flags: ~[Flag], next: uint} {
         let noflags: ~[Flag] = ~[];
         if i >= lim { return {flags: move noflags, next: i}; }
@@ -198,7 +201,7 @@ mod ct {
                 more(FlagAlternate, s, i, lim)
             } else { {flags: move noflags, next: i} };
     }
-    fn parse_count(s: &str, i: uint, lim: uint)
+    pub fn parse_count(s: &str, i: uint, lim: uint)
         -> {count: Count, next: uint} {
         return if i >= lim {
                 {count: CountImplied, next: i}
@@ -220,7 +223,7 @@ mod ct {
                 }
             };
     }
-    fn parse_precision(s: &str, i: uint, lim: uint) ->
+    pub fn parse_precision(s: &str, i: uint, lim: uint) ->
        {count: Count, next: uint} {
         return if i >= lim {
                 {count: CountImplied, next: i}
@@ -236,7 +239,7 @@ mod ct {
                 }
             } else { {count: CountImplied, next: i} };
     }
-    fn parse_type(s: &str, i: uint, lim: uint, error: ErrorFn) ->
+    pub fn parse_type(s: &str, i: uint, lim: uint, error: ErrorFn) ->
        {ty: Ty, next: uint} {
         if i >= lim { error(~"missing type in conversion"); }
         let tstr = str::slice(s, i, i+1u);
@@ -274,21 +277,20 @@ mod ct {
 // decisions made a runtime. If it proves worthwhile then some of these
 // conditions can be evaluated at compile-time. For now though it's cleaner to
 // implement it 0this way, I think.
-mod rt {
-    #[legacy_exports];
-    const flag_none : u32 = 0u32;
-    const flag_left_justify   : u32 = 0b00000000000000000000000000000001u32;
-    const flag_left_zero_pad  : u32 = 0b00000000000000000000000000000010u32;
-    const flag_space_for_sign : u32 = 0b00000000000000000000000000000100u32;
-    const flag_sign_always    : u32 = 0b00000000000000000000000000001000u32;
-    const flag_alternate      : u32 = 0b00000000000000000000000000010000u32;
+pub mod rt {
+    pub const flag_none : u32 = 0u32;
+    pub const flag_left_justify   : u32 = 0b00000000000001u32;
+    pub const flag_left_zero_pad  : u32 = 0b00000000000010u32;
+    pub const flag_space_for_sign : u32 = 0b00000000000100u32;
+    pub const flag_sign_always    : u32 = 0b00000000001000u32;
+    pub const flag_alternate      : u32 = 0b00000000010000u32;
 
-    enum Count { CountIs(int), CountImplied, }
-    enum Ty { TyDefault, TyBits, TyHexUpper, TyHexLower, TyOctal, }
+    pub enum Count { CountIs(int), CountImplied, }
+    pub enum Ty { TyDefault, TyBits, TyHexUpper, TyHexLower, TyOctal, }
 
-    type Conv = {flags: u32, width: Count, precision: Count, ty: Ty};
+    pub type Conv = {flags: u32, width: Count, precision: Count, ty: Ty};
 
-    pure fn conv_int(cv: Conv, i: int) -> ~str {
+    pub pure fn conv_int(cv: Conv, i: int) -> ~str {
         let radix = 10;
         let prec = get_int_precision(cv);
         let mut s : ~str = int_to_str_prec(i, radix, prec);
@@ -301,7 +303,7 @@ mod rt {
         }
         return unsafe { pad(cv, s, PadSigned) };
     }
-    pure fn conv_uint(cv: Conv, u: uint) -> ~str {
+    pub pure fn conv_uint(cv: Conv, u: uint) -> ~str {
         let prec = get_int_precision(cv);
         let mut rs =
             match cv.ty {
@@ -313,17 +315,17 @@ mod rt {
             };
         return unsafe { pad(cv, rs, PadUnsigned) };
     }
-    pure fn conv_bool(cv: Conv, b: bool) -> ~str {
+    pub pure fn conv_bool(cv: Conv, b: bool) -> ~str {
         let s = if b { ~"true" } else { ~"false" };
         // run the boolean conversion through the string conversion logic,
         // giving it the same rules for precision, etc.
         return conv_str(cv, s);
     }
-    pure fn conv_char(cv: Conv, c: char) -> ~str {
+    pub pure fn conv_char(cv: Conv, c: char) -> ~str {
         let mut s = str::from_char(c);
         return unsafe { pad(cv, s, PadNozero) };
     }
-    pure fn conv_str(cv: Conv, s: &str) -> ~str {
+    pub pure fn conv_str(cv: Conv, s: &str) -> ~str {
         // For strings, precision is the maximum characters
         // displayed
         let mut unpadded = match cv.precision {
@@ -336,7 +338,7 @@ mod rt {
         };
         return unsafe { pad(cv, unpadded, PadNozero) };
     }
-    pure fn conv_float(cv: Conv, f: float) -> ~str {
+    pub pure fn conv_float(cv: Conv, f: float) -> ~str {
         let (to_str, digits) = match cv.precision {
               CountIs(c) => (float::to_str_exact, c as uint),
               CountImplied => (float::to_str, 6u)
@@ -351,14 +353,14 @@ mod rt {
         }
         return unsafe { pad(cv, s, PadFloat) };
     }
-    pure fn conv_poly(cv: Conv, v: &T) -> ~str {
+    pub pure fn conv_poly(cv: Conv, v: &T) -> ~str {
         let s = sys::log_str(v);
         return conv_str(cv, s);
     }
 
     // Convert an int to string with minimum number of digits. If precision is
     // 0 and num is 0 then the result is the empty string.
-    pure fn int_to_str_prec(num: int, radix: uint, prec: uint) -> ~str {
+    pub pure fn int_to_str_prec(num: int, radix: uint, prec: uint) -> ~str {
         return if num < 0 {
                 ~"-" + uint_to_str_prec(-num as uint, radix, prec)
             } else { uint_to_str_prec(num as uint, radix, prec) };
@@ -367,7 +369,8 @@ mod rt {
     // Convert a uint to string with a minimum number of digits.  If precision
     // is 0 and num is 0 then the result is the empty string. Could move this
     // to uint: but it doesn't seem all that useful.
-    pure fn uint_to_str_prec(num: uint, radix: uint, prec: uint) -> ~str {
+    pub pure fn uint_to_str_prec(num: uint, radix: uint,
+                                 prec: uint) -> ~str {
         return if prec == 0u && num == 0u {
                 ~""
             } else {
@@ -380,16 +383,16 @@ mod rt {
                 } else { move s }
             };
     }
-    pure fn get_int_precision(cv: Conv) -> uint {
+    pub pure fn get_int_precision(cv: Conv) -> uint {
         return match cv.precision {
               CountIs(c) => c as uint,
               CountImplied => 1u
             };
     }
 
-    enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat }
+    pub enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat }
 
-    impl PadMode : Eq {
+    pub impl PadMode : Eq {
         pure fn eq(other: &PadMode) -> bool {
             match (self, (*other)) {
                 (PadSigned, PadSigned) => true,
@@ -405,7 +408,7 @@ mod rt {
         pure fn ne(other: &PadMode) -> bool { !self.eq(other) }
     }
 
-    fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str {
+    pub fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str {
         let mut s = move s; // sadtimes
         let uwidth : uint = match cv.width {
           CountImplied => return s,
@@ -458,209 +461,13 @@ mod rt {
         }
         return padstr + s;
     }
-    pure fn have_flag(flags: u32, f: u32) -> bool {
-        flags & f != 0
-    }
-}
-
-// Remove after snapshot
-
-// Functions used by the fmt extension at runtime. For now there are a lot of
-// decisions made a runtime. If it proves worthwhile then some of these
-// conditions can be evaluated at compile-time. For now though it's cleaner to
-// implement it 0this way, I think.
-mod rt2 {
-    #[legacy_exports];
-    const flag_none : u32 = 0u32;
-    const flag_left_justify   : u32 = 0b00000000000000000000000000000001u32;
-    const flag_left_zero_pad  : u32 = 0b00000000000000000000000000000010u32;
-    const flag_space_for_sign : u32 = 0b00000000000000000000000000000100u32;
-    const flag_sign_always    : u32 = 0b00000000000000000000000000001000u32;
-    const flag_alternate      : u32 = 0b00000000000000000000000000010000u32;
-
-    enum Count { CountIs(int), CountImplied, }
-    enum Ty { TyDefault, TyBits, TyHexUpper, TyHexLower, TyOctal, }
-
-    type Conv = {flags: u32, width: Count, precision: Count, ty: Ty};
-
-    pure fn conv_int(cv: Conv, i: int) -> ~str {
-        let radix = 10;
-        let prec = get_int_precision(cv);
-        let mut s : ~str = int_to_str_prec(i, radix, prec);
-        if 0 <= i {
-            if have_flag(cv.flags, flag_sign_always) {
-                unsafe { str::unshift_char(&mut s, '+') };
-            } else if have_flag(cv.flags, flag_space_for_sign) {
-                unsafe { str::unshift_char(&mut s, ' ') };
-            }
-        }
-        return unsafe { pad(cv, s, PadSigned) };
-    }
-    pure fn conv_uint(cv: Conv, u: uint) -> ~str {
-        let prec = get_int_precision(cv);
-        let mut rs =
-            match cv.ty {
-              TyDefault => uint_to_str_prec(u, 10u, prec),
-              TyHexLower => uint_to_str_prec(u, 16u, prec),
-              TyHexUpper => str::to_upper(uint_to_str_prec(u, 16u, prec)),
-              TyBits => uint_to_str_prec(u, 2u, prec),
-              TyOctal => uint_to_str_prec(u, 8u, prec)
-            };
-        return unsafe { pad(cv, rs, PadUnsigned) };
-    }
-    pure fn conv_bool(cv: Conv, b: bool) -> ~str {
-        let s = if b { ~"true" } else { ~"false" };
-        // run the boolean conversion through the string conversion logic,
-        // giving it the same rules for precision, etc.
-        return conv_str(cv, s);
-    }
-    pure fn conv_char(cv: Conv, c: char) -> ~str {
-        let mut s = str::from_char(c);
-        return unsafe { pad(cv, s, PadNozero) };
-    }
-    pure fn conv_str(cv: Conv, s: &str) -> ~str {
-        // For strings, precision is the maximum characters
-        // displayed
-        let mut unpadded = match cv.precision {
-          CountImplied => s.to_unique(),
-          CountIs(max) => if max as uint < str::char_len(s) {
-            str::substr(s, 0u, max as uint)
-          } else {
-            s.to_unique()
-          }
-        };
-        return unsafe { pad(cv, unpadded, PadNozero) };
-    }
-    pure fn conv_float(cv: Conv, f: float) -> ~str {
-        let (to_str, digits) = match cv.precision {
-              CountIs(c) => (float::to_str_exact, c as uint),
-              CountImplied => (float::to_str, 6u)
-        };
-        let mut s = unsafe { to_str(f, digits) };
-        if 0.0 <= f {
-            if have_flag(cv.flags, flag_sign_always) {
-                s = ~"+" + s;
-            } else if have_flag(cv.flags, flag_space_for_sign) {
-                s = ~" " + s;
-            }
-        }
-        return unsafe { pad(cv, s, PadFloat) };
-    }
-    pure fn conv_poly(cv: Conv, v: &T) -> ~str {
-        let s = sys::log_str(v);
-        return conv_str(cv, s);
-    }
-
-    // Convert an int to string with minimum number of digits. If precision is
-    // 0 and num is 0 then the result is the empty string.
-    pure fn int_to_str_prec(num: int, radix: uint, prec: uint) -> ~str {
-        return if num < 0 {
-                ~"-" + uint_to_str_prec(-num as uint, radix, prec)
-            } else { uint_to_str_prec(num as uint, radix, prec) };
-    }
-
-    // Convert a uint to string with a minimum number of digits.  If precision
-    // is 0 and num is 0 then the result is the empty string. Could move this
-    // to uint: but it doesn't seem all that useful.
-    pure fn uint_to_str_prec(num: uint, radix: uint, prec: uint) -> ~str {
-        return if prec == 0u && num == 0u {
-                ~""
-            } else {
-                let s = uint::to_str(num, radix);
-                let len = str::char_len(s);
-                if len < prec {
-                    let diff = prec - len;
-                    let pad = str::from_chars(vec::from_elem(diff, '0'));
-                    pad + s
-                } else { move s }
-            };
-    }
-    pure fn get_int_precision(cv: Conv) -> uint {
-        return match cv.precision {
-              CountIs(c) => c as uint,
-              CountImplied => 1u
-            };
-    }
-
-    enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat }
-
-    impl PadMode : Eq {
-        pure fn eq(other: &PadMode) -> bool {
-            match (self, (*other)) {
-                (PadSigned, PadSigned) => true,
-                (PadUnsigned, PadUnsigned) => true,
-                (PadNozero, PadNozero) => true,
-                (PadFloat, PadFloat) => true,
-                (PadSigned, _) => false,
-                (PadUnsigned, _) => false,
-                (PadNozero, _) => false,
-                (PadFloat, _) => false
-            }
-        }
-        pure fn ne(other: &PadMode) -> bool { !self.eq(other) }
-    }
-
-    fn pad(cv: Conv, s: ~str, mode: PadMode) -> ~str {
-        let mut s = move s; // sadtimes
-        let uwidth : uint = match cv.width {
-          CountImplied => return s,
-          CountIs(width) => {
-              // FIXME: width should probably be uint (see Issue #1996)
-              width as uint
-          }
-        };
-        let strlen = str::char_len(s);
-        if uwidth <= strlen { return s; }
-        let mut padchar = ' ';
-        let diff = uwidth - strlen;
-        if have_flag(cv.flags, flag_left_justify) {
-            let padstr = str::from_chars(vec::from_elem(diff, padchar));
-            return s + padstr;
-        }
-        let {might_zero_pad, signed} = match mode {
-          PadNozero => {might_zero_pad:false, signed:false},
-          PadSigned => {might_zero_pad:true,  signed:true },
-          PadFloat => {might_zero_pad:true,  signed:true},
-          PadUnsigned => {might_zero_pad:true,  signed:false}
-        };
-        pure fn have_precision(cv: Conv) -> bool {
-            return match cv.precision { CountImplied => false, _ => true };
-        }
-        let zero_padding = {
-            if might_zero_pad && have_flag(cv.flags, flag_left_zero_pad) &&
-                (!have_precision(cv) || mode == PadFloat) {
-                padchar = '0';
-                true
-            } else {
-                false
-            }
-        };
-        let padstr = str::from_chars(vec::from_elem(diff, padchar));
-        // This is completely heinous. If we have a signed value then
-        // potentially rip apart the intermediate result and insert some
-        // zeros. It may make sense to convert zero padding to a precision
-        // instead.
-
-        if signed && zero_padding && s.len() > 0 {
-            let head = str::shift_char(&mut s);
-            if head == '+' || head == '-' || head == ' ' {
-                let headstr = str::from_chars(vec::from_elem(1u, head));
-                return headstr + padstr + s;
-            }
-            else {
-                str::unshift_char(&mut s, head);
-            }
-        }
-        return padstr + s;
-    }
-    pure fn have_flag(flags: u32, f: u32) -> bool {
+    pub pure fn have_flag(flags: u32, f: u32) -> bool {
         flags & f != 0
     }
 }
 
 #[cfg(test)]
 mod test {
-    #[legacy_exports];
     #[test]
     fn fmt_slice() {
         let s = "abc";
diff --git a/src/libcore/future.rs b/src/libcore/future.rs
index 11b6a2c01354..efd5ff65aa5f 100644
--- a/src/libcore/future.rs
+++ b/src/libcore/future.rs
@@ -1,5 +1,6 @@
 // NB: transitionary, de-mode-ing.
-// tjc: re-forbid deprecated modes after snapshot
+// tjc: allowing deprecated modes due to function issue.
+// can re-forbid them after snapshot
 #[forbid(deprecated_pattern)];
 
 /*!
@@ -86,7 +87,7 @@ pub fn from_port(port: future_pipe::client::waiting) ->
     }
 }
 
-pub fn from_fn(+f: ~fn() -> A) -> Future {
+pub fn from_fn(f: ~fn() -> A) -> Future {
     /*!
      * Create a future from a function.
      *
@@ -98,7 +99,7 @@ pub fn from_fn(+f: ~fn() -> A) -> Future {
     Future {state: Pending(move f)}
 }
 
-pub fn spawn(+blk: fn~() -> A) -> Future {
+pub fn spawn(blk: fn~() -> A) -> Future {
     /*!
      * Create a future from a unique closure.
      *
diff --git a/src/libcore/int-template.rs b/src/libcore/int-template.rs
index 6942d38d5d34..8cb689fd286a 100644
--- a/src/libcore/int-template.rs
+++ b/src/libcore/int-template.rs
@@ -1,5 +1,5 @@
 // NB: transitionary, de-mode-ing.
-// tjc: re-forbid deprecated modes after snapshot
+#[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
 use T = inst::T;
diff --git a/src/libcore/io.rs b/src/libcore/io.rs
index 2efc96933da8..865b8013fb04 100644
--- a/src/libcore/io.rs
+++ b/src/libcore/io.rs
@@ -4,6 +4,9 @@ Basic input/output
 
 */
 
+#[forbid(deprecated_mode)];
+#[forbid(deprecated_pattern)];
+
 use result::Result;
 
 use cmp::Eq;
diff --git a/src/libcore/iter-trait.rs b/src/libcore/iter-trait.rs
index 09bfe2eff36a..6de6633f5f8a 100644
--- a/src/libcore/iter-trait.rs
+++ b/src/libcore/iter-trait.rs
@@ -2,7 +2,8 @@
 // workaround our lack of traits and lack of macros.  See core.{rc,rs} for
 // how this file is used.
 
-#[warn(deprecated_mode)];
+#[forbid(deprecated_mode)];
+#[forbid(deprecated_pattern)];
 
 use cmp::{Eq, Ord};
 use inst::{IMPL_T, EACH, SIZE_HINT};
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index bf3e91f70719..322012db135b 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -4,6 +4,9 @@ The iteration traits and common implementation
 
 */
 
+#[forbid(deprecated_mode)];
+#[forbid(deprecated_pattern)];
+
 use cmp::{Eq, Ord};
 
 /// A function used to initialize the elements of a sequence
diff --git a/src/libcore/mutable.rs b/src/libcore/mutable.rs
index 5948c630cd85..b314ad61ee2a 100644
--- a/src/libcore/mutable.rs
+++ b/src/libcore/mutable.rs
@@ -8,7 +8,7 @@ dynamic checks: your program will fail if you attempt to perform
 mutation when the data structure should be immutable.
 
 */
-// tjc: re-forbid deprecated modes after snapshot
+#[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
 use util::with;
diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs
index 038c117b8bed..7c6bcf5bd51f 100644
--- a/src/libcore/ops.rs
+++ b/src/libcore/ops.rs
@@ -1,5 +1,8 @@
 // Core operators and kinds.
 
+#[forbid(deprecated_mode)];
+#[forbid(deprecated_pattern)];
+
 #[lang="const"]
 pub trait Const {
     // Empty.
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 6bd326186cb4..c60b7b401cc8 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -1,15 +1,37 @@
 /*!
- * Operations on the ubiquitous `option` type.
- *
- * Type `option` represents an optional value.
- *
- * Every `Option` value can either be `Some(T)` or `none`. Where in other
- * languages you might use a nullable type, in Rust you would use an option
- * type.
- */
 
-// NB: transitionary, de-mode-ing.
-#[warn(deprecated_mode)];
+Operations on the ubiquitous `Option` type.
+
+Type `Option` represents an optional value.
+
+Every `Option` value can either be `Some(T)` or `None`. Where in other
+languages you might use a nullable type, in Rust you would use an option
+type.
+
+Options are most commonly used with pattern matching to query the presence
+of a value and take action, always accounting for the `None` case.
+
+# Example
+
+~~~
+let msg = Some(~"howdy");
+
+// Take a reference to the contained string
+match msg {
+    Some(ref m) => io::println(m),
+    None => ()
+}
+
+// Remove the contained string, destroying the Option
+let unwrapped_msg = match move msg {
+    Some(move m) => m,
+    None => ~"default message"
+};
+~~~
+
+*/
+
+#[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
 use cmp::Eq;
@@ -22,12 +44,19 @@ pub enum Option {
 
 pub pure fn get(opt: &Option) -> T {
     /*!
-     * Gets the value out of an option
-     *
-     * # Failure
-     *
-     * Fails if the value equals `none`
-     */
+    Gets the value out of an option
+
+    # Failure
+
+    Fails if the value equals `None`
+
+    # Safety note
+
+    In general, because this function may fail, its use is discouraged
+    (calling `get` on `None` is akin to dereferencing a null pointer).
+    Instead, prefer to use pattern matching and handle the `None`
+    case explicitly.
+    */
 
     match *opt {
       Some(copy x) => return x,
@@ -37,11 +66,18 @@ pub pure fn get(opt: &Option) -> T {
 
 pub pure fn get_ref(opt: &r/Option) -> &r/T {
     /*!
-     * Gets an immutable reference to the value inside an option.
-     *
-     * # Failure
-     *
-     * Fails if the value equals `none`
+    Gets an immutable reference to the value inside an option.
+
+    # Failure
+
+    Fails if the value equals `None`
+
+    # Safety note
+
+    In general, because this function may fail, its use is discouraged
+    (calling `get` on `None` is akin to dereferencing a null pointer).
+    Instead, prefer to use pattern matching and handle the `None`
+    case explicitly.
      */
     match *opt {
         Some(ref x) => x,
@@ -154,10 +190,20 @@ pub pure fn iter(opt: &Option, f: fn(x: &T)) {
 #[inline(always)]
 pub pure fn unwrap(opt: Option) -> T {
     /*!
-     * Moves a value out of an option type and returns it.
-     *
-     * Useful primarily for getting strings, vectors and unique pointers out
-     * of option types without copying them.
+    Moves a value out of an option type and returns it.
+
+    Useful primarily for getting strings, vectors and unique pointers out
+    of option types without copying them.
+
+    # Failure
+
+    Fails if the value equals `None`.
+
+    # Safety note
+
+    In general, because this function may fail, its use is discouraged.
+    Instead, prefer to use pattern matching and handle the `None`
+    case explicitly.
      */
     match move opt {
         Some(move x) => move x,
@@ -165,9 +211,16 @@ pub pure fn unwrap(opt: Option) -> T {
     }
 }
 
-/// The ubiquitous option dance.
 #[inline(always)]
 pub fn swap_unwrap(opt: &mut Option) -> T {
+    /*!
+    The option dance. Moves a value out of an option type and returns it,
+    replacing the original with `None`.
+
+    # Failure
+
+    Fails if the value equals `None`.
+     */
     if opt.is_none() { fail ~"option::swap_unwrap none" }
     unwrap(util::replace(opt, None))
 }
@@ -201,18 +254,38 @@ impl &Option {
     pure fn iter(f: fn(x: &T)) { iter(self, f) }
     /// Maps a `some` value from one type to another by reference
     pure fn map(f: fn(x: &T) -> U) -> Option { map(self, f) }
-    /// Gets an immutable reference to the value inside a `some`.
+    /**
+    Gets an immutable reference to the value inside an option.
+
+    # Failure
+
+    Fails if the value equals `None`
+
+    # Safety note
+
+    In general, because this function may fail, its use is discouraged
+    (calling `get` on `None` is akin to dereferencing a null pointer).
+    Instead, prefer to use pattern matching and handle the `None`
+    case explicitly.
+     */
     pure fn get_ref() -> &self/T { get_ref(self) }
 }
 
 impl Option {
     /**
-     * Gets the value out of an option
-     *
-     * # Failure
-     *
-     * Fails if the value equals `none`
-     */
+    Gets the value out of an option
+
+    # Failure
+
+    Fails if the value equals `None`
+
+    # Safety note
+
+    In general, because this function may fail, its use is discouraged
+    (calling `get` on `None` is akin to dereferencing a null pointer).
+    Instead, prefer to use pattern matching and handle the `None`
+    case explicitly.
+    */
     pure fn get() -> T { get(&self) }
     pure fn get_default(def: T) -> T { get_default(&self, def) }
     /**
@@ -252,10 +325,10 @@ impl Option : Eq {
 #[test]
 fn test_unwrap_ptr() {
     let x = ~0;
-    let addr_x = ptr::p2::addr_of(&(*x));
+    let addr_x = ptr::addr_of(&(*x));
     let opt = Some(x);
     let y = unwrap(opt);
-    let addr_y = ptr::p2::addr_of(&(*y));
+    let addr_y = ptr::addr_of(&(*y));
     assert addr_x == addr_y;
 }
 
diff --git a/src/libcore/os.rs b/src/libcore/os.rs
index 68571da3a1e9..3fd98e7f2987 100644
--- a/src/libcore/os.rs
+++ b/src/libcore/os.rs
@@ -1,5 +1,5 @@
 // NB: transitionary, de-mode-ing.
-// tjc: re-forbid
+#[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
 /*!
@@ -132,7 +132,7 @@ mod global_env {
         let env_ch = get_global_env_chan();
         let po = comm::Port();
         comm::send(env_ch, MsgGetEnv(str::from_slice(n),
-                                     comm::Chan(po)));
+                                     comm::Chan(&po)));
         comm::recv(po)
     }
 
@@ -141,14 +141,14 @@ mod global_env {
         let po = comm::Port();
         comm::send(env_ch, MsgSetEnv(str::from_slice(n),
                                      str::from_slice(v),
-                                     comm::Chan(po)));
+                                     comm::Chan(&po)));
         comm::recv(po)
     }
 
     pub fn env() -> ~[(~str,~str)] {
         let env_ch = get_global_env_chan();
         let po = comm::Port();
-        comm::send(env_ch, MsgEnv(comm::Chan(po)));
+        comm::send(env_ch, MsgEnv(comm::Chan(&po)));
         comm::recv(po)
     }
 
diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs
index e34c0db35e9d..791c6bccde8c 100644
--- a/src/libcore/pipes.rs
+++ b/src/libcore/pipes.rs
@@ -73,7 +73,8 @@ bounded and unbounded protocols allows for less code duplication.
 */
 
 // NB: transitionary, de-mode-ing.
-// tjc: re-forbid deprecated modes after snapshot
+// tjc: allowing deprecated modes due to function issue,
+// re-forbid after snapshot
 #[forbid(deprecated_pattern)];
 
 use cmp::Eq;
@@ -859,7 +860,7 @@ endpoint is passed to the new task.
 pub fn spawn_service(
     init: extern fn() -> (SendPacketBuffered,
                           RecvPacketBuffered),
-    +service: fn~(v: RecvPacketBuffered))
+    service: fn~(v: RecvPacketBuffered))
     -> SendPacketBuffered
 {
     let (client, server) = init();
@@ -883,7 +884,7 @@ receive state.
 pub fn spawn_service_recv(
     init: extern fn() -> (RecvPacketBuffered,
                           SendPacketBuffered),
-    +service: fn~(v: SendPacketBuffered))
+    service: fn~(v: SendPacketBuffered))
     -> RecvPacketBuffered
 {
     let (client, server) = init();
diff --git a/src/libcore/private.rs b/src/libcore/private.rs
index c1b2b32edafc..c4ef136a592e 100644
--- a/src/libcore/private.rs
+++ b/src/libcore/private.rs
@@ -1,5 +1,6 @@
 // NB: transitionary, de-mode-ing.
-// tjc: re-forbid deprecated modes after snapshot
+// tjc: Re-forbid deprecated modes once a snapshot fixes the
+// function problem
 #[forbid(deprecated_pattern)];
 
 #[doc(hidden)];
@@ -45,7 +46,7 @@ type GlobalPtr = *libc::uintptr_t;
 pub unsafe fn chan_from_global_ptr(
     global: GlobalPtr,
     task_fn: fn() -> task::TaskBuilder,
-    +f: fn~(comm::Port)
+    f: fn~(comm::Port)
 ) -> comm::Chan {
 
     enum Msg {
@@ -63,7 +64,7 @@ pub unsafe fn chan_from_global_ptr(
         let (setup_po, setup_ch) = do task_fn().spawn_conversation
             |move f, setup_po, setup_ch| {
             let po = comm::Port::();
-            let ch = comm::Chan(po);
+            let ch = comm::Chan(&po);
             comm::send(setup_ch, ch);
 
             // Wait to hear if we are the official instance of
@@ -109,7 +110,7 @@ pub fn test_from_global_chan1() {
 
     // The global channel
     let globchan = 0;
-    let globchanp = ptr::p2::addr_of(&globchan);
+    let globchanp = ptr::addr_of(&globchan);
 
     // Create the global channel, attached to a new task
     let ch = unsafe {
@@ -122,7 +123,7 @@ pub fn test_from_global_chan1() {
     };
     // Talk to it
     let po = comm::Port();
-    comm::send(ch, comm::Chan(po));
+    comm::send(ch, comm::Chan(&po));
     assert comm::recv(po) == true;
 
     // This one just reuses the previous channel
@@ -135,7 +136,7 @@ pub fn test_from_global_chan1() {
 
     // Talk to the original global task
     let po = comm::Port();
-    comm::send(ch, comm::Chan(po));
+    comm::send(ch, comm::Chan(&po));
     assert comm::recv(po) == true;
 }
 
@@ -145,10 +146,10 @@ pub fn test_from_global_chan2() {
     for iter::repeat(100) {
         // The global channel
         let globchan = 0;
-        let globchanp = ptr::p2::addr_of(&globchan);
+        let globchanp = ptr::addr_of(&globchan);
 
         let resultpo = comm::Port();
-        let resultch = comm::Chan(resultpo);
+        let resultch = comm::Chan(&resultpo);
 
         // Spawn a bunch of tasks that all want to compete to
         // create the global channel
@@ -165,7 +166,7 @@ pub fn test_from_global_chan2() {
                     }
                 };
                 let po = comm::Port();
-                comm::send(ch, comm::Chan(po));
+                comm::send(ch, comm::Chan(&po));
                 // We are The winner if our version of the
                 // task was installed
                 let winner = comm::recv(po);
@@ -203,7 +204,7 @@ pub fn test_from_global_chan2() {
  */
 pub unsafe fn weaken_task(f: fn(comm::Port<()>)) {
     let po = comm::Port();
-    let ch = comm::Chan(po);
+    let ch = comm::Chan(&po);
     unsafe {
         rustrt::rust_task_weaken(cast::reinterpret_cast(&ch));
     }
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index fad7eddd2d8d..ffa11dcfc754 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -1,5 +1,8 @@
 //! Unsafe pointer utility functions
 
+#[forbid(deprecated_mode)];
+#[forbid(deprecated_pattern)];
+
 use cmp::{Eq, Ord};
 use libc::{c_void, size_t};
 
@@ -28,12 +31,6 @@ extern mod rusti {
 #[inline(always)]
 pub pure fn addr_of(val: &T) -> *T { unsafe { rusti::addr_of(*val) } }
 
-pub mod p2 {
-    /// Get an unsafe pointer to a value
-    #[inline(always)]
-    pub pure fn addr_of(val: &T) -> *T { unsafe { rusti::addr_of(*val) } }
-}
-
 /// Get an unsafe mut pointer to a value
 #[inline(always)]
 pub pure fn mut_addr_of(val: &T) -> *mut T {
diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs
index 32f77a533a67..786fed88de97 100644
--- a/src/libcore/rand.rs
+++ b/src/libcore/rand.rs
@@ -1,7 +1,7 @@
 //! Random number generation
 
 // NB: transitional, de-mode-ing.
-#[warn(deprecated_mode)];
+#[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
 #[allow(non_camel_case_types)] // runtime type
@@ -310,7 +310,7 @@ pub fn seeded_xorshift(x: u32, y: u32, z: u32, w: u32) -> Rng {
 
 
 // used to make space in TLS for a random number generator
-fn tls_rng_state(+_v: @RandRes) {}
+fn tls_rng_state(_v: @RandRes) {}
 
 /**
  * Gives back a lazily initialized task-local random number generator,
diff --git a/src/libcore/reflect.rs b/src/libcore/reflect.rs
index 41006e1dfb5e..505804b3da82 100644
--- a/src/libcore/reflect.rs
+++ b/src/libcore/reflect.rs
@@ -4,6 +4,9 @@ Runtime type reflection
 
 */
 
+#[forbid(deprecated_mode)];
+#[forbid(deprecated_pattern)];
+
 use intrinsic::{TyDesc, get_tydesc, visit_tydesc, TyVisitor};
 use libc::c_void;
 
diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs
index ff82ed3fb419..0501b032d2d5 100644
--- a/src/libcore/repr.rs
+++ b/src/libcore/repr.rs
@@ -4,6 +4,9 @@ More runtime type reflection
 
 */
 
+#[forbid(deprecated_mode)];
+#[forbid(deprecated_pattern)];
+
 use dvec::DVec;
 use io::{Writer, WriterUtil};
 use libc::c_void;
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index e61690d5b2c0..39fae8905f92 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -1,7 +1,8 @@
 //! A type representing either success or failure
 
 // NB: transitionary, de-mode-ing.
-// tjc: re-forbid deprecated modes after snapshot
+
+#[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
 use cmp::Eq;
diff --git a/src/libcore/run.rs b/src/libcore/run.rs
index f3e98f6ba827..0ff917492091 100644
--- a/src/libcore/run.rs
+++ b/src/libcore/run.rs
@@ -1,5 +1,5 @@
 // NB: transitionary, de-mode-ing.
-// tjc: re-forbid deprecated modes after snapshot
+#[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
 //! Process spawning
@@ -296,7 +296,7 @@ pub fn program_output(prog: &str, args: &[~str]) ->
     // or the other. FIXME (#2625): Surely there's a much more
     // clever way to do this.
     let p = comm::Port();
-    let ch = comm::Chan(p);
+    let ch = comm::Chan(&p);
     do task::spawn_sched(task::SingleThreaded) {
         let errput = readclose(pipe_err.in);
         comm::send(ch, (2, move errput));
diff --git a/src/libcore/stackwalk.rs b/src/libcore/stackwalk.rs
index 09973148c8c8..a88a44701ce8 100644
--- a/src/libcore/stackwalk.rs
+++ b/src/libcore/stackwalk.rs
@@ -3,8 +3,8 @@
 #[legacy_modes]; // tjc: remove after snapshot
 
 // NB: transitionary, de-mode-ing.
-// XXX: Can't do this because frame_address needs a deprecated mode.
-//#[forbid(deprecated_mode)];
+// XXX: Can't forbid this because frame_address needs a deprecated mode.
+#[allow(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
 use cast::reinterpret_cast;
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index cf996a8b254c..285b61149577 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -7,8 +7,8 @@
  * some heavy-duty uses, try std::rope.
  */
 
-#[warn(deprecated_mode)];
-#[warn(deprecated_pattern)];
+#[forbid(deprecated_mode)];
+#[forbid(deprecated_pattern)];
 
 use cmp::{Eq, Ord};
 use libc::size_t;
diff --git a/src/libcore/task.rs b/src/libcore/task.rs
index 5ca35a7f5623..8d7791d18d90 100644
--- a/src/libcore/task.rs
+++ b/src/libcore/task.rs
@@ -1,5 +1,6 @@
 // NB: transitionary, de-mode-ing.
-// tjc: re-forbid deprecated modes after snapshot
+// tjc: Deprecated modes allowed because of function arg issue
+// in task::spawn. Re-forbid after snapshot.
 #[forbid(deprecated_pattern)];
 
 /*!
@@ -219,7 +220,7 @@ pub type TaskOpts = {
 // FIXME (#2585): Replace the 'consumed' bit with move mode on self
 pub enum TaskBuilder = {
     opts: TaskOpts,
-    gen_body: fn@(+v: fn~()) -> fn~(),
+    gen_body: fn@(v: fn~()) -> fn~(),
     can_not_copy: Option,
     mut consumed: bool,
 };
@@ -232,7 +233,7 @@ pub enum TaskBuilder = {
 pub fn task() -> TaskBuilder {
     TaskBuilder({
         opts: default_task_opts(),
-        gen_body: |+body| move body, // Identity function
+        gen_body: |body| move body, // Identity function
         can_not_copy: None,
         mut consumed: false,
     })
@@ -409,7 +410,7 @@ impl TaskBuilder {
      * generator by applying the task body which results from the
      * existing body generator to the new body generator.
      */
-    fn add_wrapper(wrapper: fn@(+v: fn~()) -> fn~()) -> TaskBuilder {
+    fn add_wrapper(wrapper: fn@(v: fn~()) -> fn~()) -> TaskBuilder {
         let prev_gen_body = self.gen_body;
         let notify_chan = if self.opts.notify_chan.is_none() {
             None
@@ -441,7 +442,7 @@ impl TaskBuilder {
      * When spawning into a new scheduler, the number of threads requested
      * must be greater than zero.
      */
-    fn spawn(+f: fn~()) {
+    fn spawn(f: fn~()) {
         let notify_chan = if self.opts.notify_chan.is_none() {
             None
         } else {
@@ -459,7 +460,7 @@ impl TaskBuilder {
         spawn::spawn_raw(move opts, x.gen_body(move f));
     }
     /// Runs a task, while transfering ownership of one argument to the child.
-    fn spawn_with(arg: A, +f: fn~(+v: A)) {
+    fn spawn_with(arg: A, f: fn~(v: A)) {
         let arg = ~mut Some(move arg);
         do self.spawn |move arg, move f| {
             f(option::swap_unwrap(arg))
@@ -477,12 +478,12 @@ impl TaskBuilder {
      * otherwise be required to establish communication from the parent
      * to the child.
      */
-    fn spawn_listener(+f: fn~(comm::Port)) -> comm::Chan {
+    fn spawn_listener(f: fn~(comm::Port)) -> comm::Chan {
         let setup_po = comm::Port();
-        let setup_ch = comm::Chan(setup_po);
+        let setup_ch = comm::Chan(&setup_po);
         do self.spawn |move f| {
             let po = comm::Port();
-            let ch = comm::Chan(po);
+            let ch = comm::Chan(&po);
             comm::send(setup_ch, ch);
             f(move po);
         }
@@ -493,10 +494,10 @@ impl TaskBuilder {
      * Runs a new task, setting up communication in both directions
      */
     fn spawn_conversation
-        (+f: fn~(comm::Port, comm::Chan))
+        (f: fn~(comm::Port, comm::Chan))
         -> (comm::Port, comm::Chan) {
         let from_child = comm::Port();
-        let to_parent = comm::Chan(from_child);
+        let to_parent = comm::Chan(&from_child);
         let to_child = do self.spawn_listener |move f, from_parent| {
             f(from_parent, to_parent)
         };
@@ -516,9 +517,9 @@ impl TaskBuilder {
      * # Failure
      * Fails if a future_result was already set for this task.
      */
-    fn try(+f: fn~() -> T) -> Result {
+    fn try(f: fn~() -> T) -> Result {
         let po = comm::Port();
-        let ch = comm::Chan(po);
+        let ch = comm::Chan(&po);
         let mut result = None;
 
         let fr_task_builder = self.future_result(|+r| {
@@ -555,7 +556,7 @@ pub fn default_task_opts() -> TaskOpts {
 
 /* Spawn convenience functions */
 
-pub fn spawn(+f: fn~()) {
+pub fn spawn(f: fn~()) {
     /*!
      * Creates and executes a new child task
      *
@@ -568,7 +569,7 @@ pub fn spawn(+f: fn~()) {
     task().spawn(move f)
 }
 
-pub fn spawn_unlinked(+f: fn~()) {
+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.
@@ -577,7 +578,7 @@ pub fn spawn_unlinked(+f: fn~()) {
     task().unlinked().spawn(move f)
 }
 
-pub fn spawn_supervised(+f: fn~()) {
+pub fn spawn_supervised(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.
@@ -586,7 +587,7 @@ pub fn spawn_supervised(+f: fn~()) {
     task().supervised().spawn(move f)
 }
 
-pub fn spawn_with(+arg: A, +f: fn~(+v: A)) {
+pub fn spawn_with(arg: A, f: fn~(v: A)) {
     /*!
      * Runs a task, while transfering ownership of one argument to the
      * child.
@@ -600,7 +601,7 @@ pub fn spawn_with(+arg: A, +f: fn~(+v: A)) {
     task().spawn_with(move arg, move f)
 }
 
-pub fn spawn_listener(+f: fn~(comm::Port)) -> comm::Chan {
+pub fn spawn_listener(f: fn~(comm::Port)) -> comm::Chan {
     /*!
      * Runs a new task while providing a channel from the parent to the child
      *
@@ -611,7 +612,7 @@ pub fn spawn_listener(+f: fn~(comm::Port)) -> comm::Chan {
 }
 
 pub fn spawn_conversation
-    (+f: fn~(comm::Port, comm::Chan))
+    (f: fn~(comm::Port, comm::Chan))
     -> (comm::Port, comm::Chan) {
     /*!
      * Runs a new task, setting up communication in both directions
@@ -622,7 +623,7 @@ pub fn spawn_conversation
     task().spawn_conversation(move f)
 }
 
-pub fn spawn_sched(mode: SchedMode, +f: fn~()) {
+pub fn spawn_sched(mode: SchedMode, f: fn~()) {
     /*!
      * Creates a new scheduler and executes a task on it
      *
@@ -639,7 +640,7 @@ pub fn spawn_sched(mode: SchedMode, +f: fn~()) {
     task().sched_mode(mode).spawn(move f)
 }
 
-pub fn try(+f: fn~() -> T) -> Result {
+pub fn try(f: fn~() -> T) -> Result {
     /*!
      * Execute a function in another task and return either the return value
      * of the function or result::err.
@@ -772,7 +773,7 @@ fn test_cant_dup_task_builder() {
 #[test] #[ignore(cfg(windows))]
 fn test_spawn_unlinked_unsup_no_fail_down() { // grandchild sends on a port
     let po = comm::Port();
-    let ch = comm::Chan(po);
+    let ch = comm::Chan(&po);
     do spawn_unlinked {
         do spawn_unlinked {
             // Give middle task a chance to fail-but-not-kill-us.
@@ -802,7 +803,7 @@ 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 = comm::Port::<()>();
-    let _ch = comm::Chan(po);
+    let _ch = comm::Chan(&po);
     // 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()).
@@ -845,7 +846,7 @@ fn test_spawn_linked_sup_fail_down() { // parent fails; child fails
 #[test] #[should_fail] #[ignore(cfg(windows))]
 fn test_spawn_linked_unsup_fail_up() { // child fails; parent fails
     let po = comm::Port::<()>();
-    let _ch = comm::Chan(po);
+    let _ch = comm::Chan(&po);
     // Default options are to spawn linked & unsupervised.
     do spawn { fail; }
     comm::recv(po); // We should get punted awake
@@ -917,7 +918,7 @@ fn test_spawn_linked_sup_propagate_sibling() {
 #[test]
 fn test_run_basic() {
     let po = comm::Port();
-    let ch = comm::Chan(po);
+    let ch = comm::Chan(&po);
     do task().spawn {
         comm::send(ch, ());
     }
@@ -927,7 +928,7 @@ fn test_run_basic() {
 #[test]
 fn test_add_wrapper() {
     let po = comm::Port();
-    let ch = comm::Chan(po);
+    let ch = comm::Chan(&po);
     let b0 = task();
     let b1 = do b0.add_wrapper |body| {
         fn~() {
@@ -961,7 +962,7 @@ fn test_back_to_the_future_result() {
 #[test]
 fn test_spawn_listiner_bidi() {
     let po = comm::Port();
-    let ch = comm::Chan(po);
+    let ch = comm::Chan(&po);
     let ch = do spawn_listener |po| {
         // Now the child has a port called 'po' to read from and
         // an environment-captured channel called 'ch'.
@@ -1017,7 +1018,7 @@ fn test_spawn_sched_no_threads() {
 #[test]
 fn test_spawn_sched() {
     let po = comm::Port();
-    let ch = comm::Chan(po);
+    let ch = comm::Chan(&po);
 
     fn f(i: int, ch: comm::Chan<()>) {
         let parent_sched_id = rt::rust_get_sched_id();
@@ -1041,7 +1042,7 @@ fn test_spawn_sched() {
 #[test]
 fn test_spawn_sched_childs_on_same_sched() {
     let po = comm::Port();
-    let ch = comm::Chan(po);
+    let ch = comm::Chan(&po);
 
     do spawn_sched(SingleThreaded) {
         let parent_sched_id = rt::rust_get_sched_id();
@@ -1075,9 +1076,9 @@ fn test_spawn_sched_blocking() {
     for iter::repeat(20u) {
 
         let start_po = comm::Port();
-        let start_ch = comm::Chan(start_po);
+        let start_ch = comm::Chan(&start_po);
         let fin_po = comm::Port();
-        let fin_ch = comm::Chan(fin_po);
+        let fin_ch = comm::Chan(&fin_po);
 
         let lock = testrt::rust_dbg_lock_create();
 
@@ -1105,12 +1106,12 @@ fn test_spawn_sched_blocking() {
         }
 
         let setup_po = comm::Port();
-        let setup_ch = comm::Chan(setup_po);
+        let setup_ch = comm::Chan(&setup_po);
         let parent_po = comm::Port();
-        let parent_ch = comm::Chan(parent_po);
+        let parent_ch = comm::Chan(&parent_po);
         do spawn {
             let child_po = comm::Port();
-            comm::send(setup_ch, comm::Chan(child_po));
+            comm::send(setup_ch, comm::Chan(&child_po));
             pingpong(child_po, parent_ch);
         };
 
@@ -1126,15 +1127,15 @@ fn test_spawn_sched_blocking() {
 }
 
 #[cfg(test)]
-fn avoid_copying_the_body(spawnfn: fn(+v: fn~())) {
+fn avoid_copying_the_body(spawnfn: fn(v: fn~())) {
     let p = comm::Port::();
-    let ch = comm::Chan(p);
+    let ch = comm::Chan(&p);
 
     let x = ~1;
-    let x_in_parent = ptr::p2::addr_of(&(*x)) as uint;
+    let x_in_parent = ptr::addr_of(&(*x)) as uint;
 
     do spawnfn {
-        let x_in_child = ptr::p2::addr_of(&(*x)) as uint;
+        let x_in_child = ptr::addr_of(&(*x)) as uint;
         comm::send(ch, x_in_child);
     }
 
@@ -1149,7 +1150,7 @@ fn test_avoid_copying_the_body_spawn() {
 
 #[test]
 fn test_avoid_copying_the_body_spawn_listener() {
-    do avoid_copying_the_body |+f| {
+    do avoid_copying_the_body |f| {
         spawn_listener(fn~(move f, _po: comm::Port) {
             f();
         });
@@ -1167,7 +1168,7 @@ fn test_avoid_copying_the_body_task_spawn() {
 
 #[test]
 fn test_avoid_copying_the_body_spawn_listener_1() {
-    do avoid_copying_the_body |+f| {
+    do avoid_copying_the_body |f| {
         task().spawn_listener(fn~(move f, _po: comm::Port) {
             f();
         });
@@ -1195,7 +1196,7 @@ fn test_avoid_copying_the_body_unlinked() {
 #[test]
 fn test_platform_thread() {
     let po = comm::Port();
-    let ch = comm::Chan(po);
+    let ch = comm::Chan(&po);
     do task().sched_mode(PlatformThread).spawn {
         comm::send(ch, ());
     }
diff --git a/src/libcore/task/local_data.rs b/src/libcore/task/local_data.rs
index 2130354229a2..991011893152 100644
--- a/src/libcore/task/local_data.rs
+++ b/src/libcore/task/local_data.rs
@@ -78,7 +78,7 @@ pub unsafe fn local_data_modify(
 }
 
 #[test]
-pub fn test_tls_multitask() unsafe {
+fn test_tls_multitask() unsafe {
     fn my_key(_x: @~str) { }
     local_data_set(my_key, @~"parent data");
     do task::spawn unsafe {
@@ -94,7 +94,7 @@ pub fn test_tls_multitask() unsafe {
 }
 
 #[test]
-pub fn test_tls_overwrite() unsafe {
+fn test_tls_overwrite() unsafe {
     fn my_key(_x: @~str) { }
     local_data_set(my_key, @~"first data");
     local_data_set(my_key, @~"next data"); // Shouldn't leak.
@@ -102,7 +102,7 @@ pub fn test_tls_overwrite() unsafe {
 }
 
 #[test]
-pub fn test_tls_pop() unsafe {
+fn test_tls_pop() unsafe {
     fn my_key(_x: @~str) { }
     local_data_set(my_key, @~"weasel");
     assert *(local_data_pop(my_key).get()) == ~"weasel";
@@ -111,7 +111,7 @@ pub fn test_tls_pop() unsafe {
 }
 
 #[test]
-pub fn test_tls_modify() unsafe {
+fn test_tls_modify() unsafe {
     fn my_key(_x: @~str) { }
     local_data_modify(my_key, |data| {
         match data {
@@ -130,7 +130,7 @@ pub fn test_tls_modify() unsafe {
 }
 
 #[test]
-pub fn test_tls_crust_automorestack_memorial_bug() unsafe {
+fn test_tls_crust_automorestack_memorial_bug() unsafe {
     // This might result in a stack-canary clobber if the runtime fails to set
     // sp_limit to 0 when calling the cleanup extern - it might automatically
     // jump over to the rust stack, which causes next_c_sp to get recorded as
@@ -143,7 +143,7 @@ pub fn test_tls_crust_automorestack_memorial_bug() unsafe {
 }
 
 #[test]
-pub fn test_tls_multiple_types() unsafe {
+fn test_tls_multiple_types() unsafe {
     fn str_key(_x: @~str) { }
     fn box_key(_x: @@()) { }
     fn int_key(_x: @int) { }
@@ -155,7 +155,7 @@ pub fn test_tls_multiple_types() unsafe {
 }
 
 #[test]
-pub fn test_tls_overwrite_multiple_types() {
+fn test_tls_overwrite_multiple_types() {
     fn str_key(_x: @~str) { }
     fn box_key(_x: @@()) { }
     fn int_key(_x: @int) { }
@@ -171,7 +171,7 @@ pub fn test_tls_overwrite_multiple_types() {
 #[test]
 #[should_fail]
 #[ignore(cfg(windows))]
-pub fn test_tls_cleanup_on_failure() unsafe {
+fn test_tls_cleanup_on_failure() unsafe {
     fn str_key(_x: @~str) { }
     fn box_key(_x: @@()) { }
     fn int_key(_x: @int) { }
diff --git a/src/libcore/task/local_data_priv.rs b/src/libcore/task/local_data_priv.rs
index 9849ce7b68cd..e84e4dad164f 100644
--- a/src/libcore/task/local_data_priv.rs
+++ b/src/libcore/task/local_data_priv.rs
@@ -17,11 +17,11 @@ impl LocalData: Eq {
 
 // We use dvec because it's the best data structure in core. If TLS is used
 // heavily in future, this could be made more efficient with a proper map.
-pub type TaskLocalElement = (*libc::c_void, *libc::c_void, LocalData);
+type TaskLocalElement = (*libc::c_void, *libc::c_void, LocalData);
 // Has to be a pointer at outermost layer; the foreign call returns void *.
-pub type TaskLocalMap = @dvec::DVec>;
+type TaskLocalMap = @dvec::DVec>;
 
-pub extern fn cleanup_task_local_map(map_ptr: *libc::c_void) unsafe {
+extern fn cleanup_task_local_map(map_ptr: *libc::c_void) unsafe {
     assert !map_ptr.is_null();
     // Get and keep the single reference that was created at the beginning.
     let _map: TaskLocalMap = cast::reinterpret_cast(&map_ptr);
@@ -29,7 +29,7 @@ pub extern fn cleanup_task_local_map(map_ptr: *libc::c_void) unsafe {
 }
 
 // Gets the map from the runtime. Lazily initialises if not done so already.
-pub unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap {
+unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap {
 
     // Relies on the runtime initialising the pointer to null.
     // NOTE: The map's box lives in TLS invisibly referenced once. Each time
@@ -52,7 +52,7 @@ pub unsafe fn get_task_local_map(task: *rust_task) -> TaskLocalMap {
     }
 }
 
-pub unsafe fn key_to_key_value(
+unsafe fn key_to_key_value(
     key: LocalDataKey) -> *libc::c_void {
 
     // Keys are closures, which are (fnptr,envptr) pairs. Use fnptr.
@@ -62,7 +62,7 @@ pub unsafe fn key_to_key_value(
 }
 
 // If returning Some(..), returns with @T with the map's reference. Careful!
-pub unsafe fn local_data_lookup(
+unsafe fn local_data_lookup(
     map: TaskLocalMap, key: LocalDataKey)
     -> Option<(uint, *libc::c_void)> {
 
@@ -80,7 +80,7 @@ pub unsafe fn local_data_lookup(
     }
 }
 
-pub unsafe fn local_get_helper(
+unsafe fn local_get_helper(
     task: *rust_task, key: LocalDataKey,
     do_pop: bool) -> Option<@T> {
 
diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs
index 0e1284da3bcb..6eaace1fa1a1 100644
--- a/src/libcore/task/spawn.rs
+++ b/src/libcore/task/spawn.rs
@@ -61,6 +61,7 @@
  ****************************************************************************/
 
 #[doc(hidden)]; // FIXME #3538
+#[warn(deprecated_mode)];
 
 use rt::rust_task;
 use rt::rust_closure;
@@ -69,16 +70,16 @@ macro_rules! move_it (
     { $x:expr } => { unsafe { let y <- *ptr::addr_of(&($x)); move y } }
 )
 
-pub type TaskSet = send_map::linear::LinearMap<*rust_task,()>;
+type TaskSet = send_map::linear::LinearMap<*rust_task,()>;
 
-pub fn new_taskset() -> TaskSet {
+fn new_taskset() -> TaskSet {
     send_map::linear::LinearMap()
 }
-pub fn taskset_insert(tasks: &mut TaskSet, task: *rust_task) {
+fn taskset_insert(tasks: &mut TaskSet, task: *rust_task) {
     let didnt_overwrite = tasks.insert(task, ());
     assert didnt_overwrite;
 }
-pub fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) {
+fn taskset_remove(tasks: &mut TaskSet, task: *rust_task) {
     let was_present = tasks.remove(&task);
     assert was_present;
 }
@@ -87,7 +88,7 @@ pub fn taskset_each(tasks: &TaskSet, blk: fn(v: *rust_task) -> bool) {
 }
 
 // One of these per group of linked-failure tasks.
-pub type TaskGroupData = {
+type 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,
@@ -95,12 +96,12 @@ pub type TaskGroupData = {
     // tasks in this group.
     mut descendants: TaskSet,
 };
-pub type TaskGroupArc = private::Exclusive>;
+type TaskGroupArc = private::Exclusive>;
 
-pub type TaskGroupInner = &mut Option;
+type TaskGroupInner = &mut Option;
 
 // A taskgroup is 'dead' when nothing can cause it to fail; only members can.
-pub pure fn taskgroup_is_dead(tg: &TaskGroupData) -> bool {
+pure fn taskgroup_is_dead(tg: &TaskGroupData) -> bool {
     (&tg.members).is_empty()
 }
 
@@ -111,7 +112,7 @@ pub pure fn taskgroup_is_dead(tg: &TaskGroupData) -> bool {
 // taskgroup which was spawned-unlinked. Tasks from intermediate generations
 // have references to the middle of the list; when intermediate generations
 // die, their node in the list will be collected at a descendant's spawn-time.
-pub type AncestorNode = {
+type AncestorNode = {
     // Since the ancestor list is recursive, we end up with references to
     // exclusives within other exclusives. This is dangerous business (if
     // circular references arise, deadlock and memory leaks are imminent).
@@ -124,16 +125,16 @@ pub type AncestorNode = {
     // Recursive rest of the list.
     mut ancestors:    AncestorList,
 };
-pub enum AncestorList = Option>;
+enum AncestorList = Option>;
 
 // Accessors for taskgroup arcs and ancestor arcs that wrap the unsafety.
 #[inline(always)]
-pub fn access_group(x: &TaskGroupArc, blk: fn(TaskGroupInner) -> U) -> U {
+fn access_group(x: &TaskGroupArc, blk: fn(TaskGroupInner) -> U) -> U {
     unsafe { x.with(blk) }
 }
 
 #[inline(always)]
-pub fn access_ancestors(x: &private::Exclusive,
+fn access_ancestors(x: &private::Exclusive,
                        blk: fn(x: &mut AncestorNode) -> U) -> U {
     unsafe { x.with(blk) }
 }
@@ -146,7 +147,7 @@ pub fn access_ancestors(x: &private::Exclusive,
 // (3) As a bonus, coalesces away all 'dead' taskgroup nodes in the list.
 // FIXME(#2190): Change Option to Option, to save on
 // allocations. Once that bug is fixed, changing the sigil should suffice.
-pub fn each_ancestor(list:        &mut AncestorList,
+fn each_ancestor(list:        &mut AncestorList,
                      bail_opt:    Option,
                      forward_blk: fn(TaskGroupInner) -> bool)
         -> bool {
@@ -271,7 +272,7 @@ pub fn each_ancestor(list:        &mut AncestorList,
 }
 
 // One of these per task.
-pub struct TCB {
+struct TCB {
     me:            *rust_task,
     // List of tasks with whose fates this one's is intertwined.
     tasks:         TaskGroupArc, // 'none' means the group has failed.
@@ -303,7 +304,7 @@ pub struct TCB {
     }
 }
 
-pub fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList,
+fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList,
        is_main: bool, notifier: Option) -> TCB {
 
     let notifier = move notifier;
@@ -318,7 +319,7 @@ pub fn TCB(me: *rust_task, tasks: TaskGroupArc, ancestors: AncestorList,
     }
 }
 
-pub struct AutoNotify {
+struct AutoNotify {
     notify_chan: Chan,
     mut failed:  bool,
     drop {
@@ -327,14 +328,14 @@ pub struct AutoNotify {
     }
 }
 
-pub fn AutoNotify(chan: Chan) -> AutoNotify {
+fn AutoNotify(chan: Chan) -> AutoNotify {
     AutoNotify {
         notify_chan: chan,
         failed: true // Un-set above when taskgroup successfully made.
     }
 }
 
-pub fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task,
+fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task,
                            is_member: bool) -> bool {
     let newstate = util::replace(state, None);
     // If 'None', the group was failing. Can't enlist.
@@ -350,7 +351,7 @@ pub fn enlist_in_taskgroup(state: TaskGroupInner, me: *rust_task,
 }
 
 // NB: Runs in destructor/post-exit context. Can't 'fail'.
-pub fn leave_taskgroup(state: TaskGroupInner, me: *rust_task,
+fn leave_taskgroup(state: TaskGroupInner, me: *rust_task,
                        is_member: bool) {
     let newstate = util::replace(state, None);
     // If 'None', already failing and we've already gotten a kill signal.
@@ -363,7 +364,7 @@ pub fn leave_taskgroup(state: TaskGroupInner, me: *rust_task,
 }
 
 // NB: Runs in destructor/post-exit context. Can't 'fail'.
-pub fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) {
+fn kill_taskgroup(state: TaskGroupInner, me: *rust_task, is_main: bool) {
     // NB: We could do the killing iteration outside of the group arc, by
     // having "let mut newstate" here, swapping inside, and iterating after.
     // But that would let other exiting tasks fall-through and exit while we
@@ -405,7 +406,7 @@ macro_rules! taskgroup_key (
     () => (cast::transmute((-2 as uint, 0u)))
 )
 
-pub fn gen_child_taskgroup(linked: bool, supervised: bool)
+fn gen_child_taskgroup(linked: bool, supervised: bool)
     -> (TaskGroupArc, AncestorList, bool) {
     let spawner = rt::rust_get_task();
     /*######################################################################*
@@ -487,7 +488,7 @@ pub fn gen_child_taskgroup(linked: bool, supervised: bool)
     }
 }
 
-pub fn spawn_raw(opts: TaskOpts, +f: fn~()) {
+pub fn spawn_raw(opts: TaskOpts, f: fn~()) {
     let (child_tg, ancestors, is_main) =
         gen_child_taskgroup(opts.linked, opts.supervised);
 
@@ -532,7 +533,7 @@ pub fn spawn_raw(opts: TaskOpts, +f: fn~()) {
     fn make_child_wrapper(child: *rust_task, child_arc: TaskGroupArc,
                           ancestors: AncestorList, is_main: bool,
                           notify_chan: Option>,
-                          +f: fn~()) -> fn~() {
+                          f: fn~()) -> fn~() {
         let child_data = ~mut Some((move child_arc, move ancestors));
         return fn~(move notify_chan, move child_data, move f) {
             // Agh. Get move-mode items into the closure. FIXME (#2829)
@@ -636,7 +637,7 @@ pub fn spawn_raw(opts: TaskOpts, +f: fn~()) {
 #[test]
 fn test_spawn_raw_simple() {
     let po = comm::Port();
-    let ch = comm::Chan(po);
+    let ch = comm::Chan(&po);
     do spawn_raw(default_task_opts()) {
         comm::send(ch, ());
     }
diff --git a/src/libcore/util.rs b/src/libcore/util.rs
index aa1fe14ba882..6c633f16abf2 100644
--- a/src/libcore/util.rs
+++ b/src/libcore/util.rs
@@ -5,7 +5,7 @@ Miscellaneous helpers for common patterns.
 */
 
 // NB: transitionary, de-mode-ing.
-// tjc: re-forbid deprecated modes after snapshot
+#[forbid(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
 use cmp::Eq;
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index 0c822bd0a031..3a2b73f5b5b4 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -1,7 +1,7 @@
 //! Vectors
 
-#[warn(deprecated_mode)];
-#[warn(deprecated_pattern)];
+#[forbid(deprecated_mode)];
+#[forbid(deprecated_pattern)];
 #[warn(non_camel_case_types)];
 
 use cmp::{Eq, Ord};
@@ -18,9 +18,10 @@ extern mod rustrt {
 
 #[abi = "rust-intrinsic"]
 extern mod rusti {
-    fn move_val_init(&dst: T, -src: T);
+    fn move_val_init(dst: &mut T, -src: T);
 }
 
+
 /// Returns true if a vector contains no elements
 pub pure fn is_empty(v: &[const T]) -> bool {
     as_const_buf(v, |_p, len| len == 0u)
@@ -104,7 +105,7 @@ pub pure fn from_fn(n_elts: uint, op: iter::InitOp) -> ~[T] {
         do as_mut_buf(v) |p, _len| {
             let mut i: uint = 0u;
             while i < n_elts {
-                rusti::move_val_init(*ptr::mut_offset(p, i), op(i));
+                rusti::move_val_init(&mut(*ptr::mut_offset(p, i)), op(i));
                 i += 1u;
             }
         }
@@ -489,7 +490,7 @@ unsafe fn push_fast(v: &mut ~[T], initval: T) {
     (**repr).unboxed.fill += sys::size_of::();
     let p = addr_of(&((**repr).unboxed.data));
     let p = ptr::offset(p, fill) as *mut T;
-    rusti::move_val_init(*p, move initval);
+    rusti::move_val_init(&mut(*p), move initval);
 }
 
 #[inline(never)]
@@ -1769,7 +1770,7 @@ pub mod raw {
         do as_mut_buf(v) |p, _len| {
             let mut box2 = None;
             box2 <-> box;
-            rusti::move_val_init(*ptr::mut_offset(p, i),
+            rusti::move_val_init(&mut(*ptr::mut_offset(p, i)),
                                  option::unwrap(move box2));
         }
     }
@@ -1918,10 +1919,9 @@ impl &[A]: iter::CopyableIter {
     }
     pure fn to_vec() -> ~[A] { iter::to_vec(&self) }
 
-    // FIXME--bug in resolve prevents this from working (#2611)
-    // fn flat_map_to_vec>(op: fn(A) -> IB) -> ~[B] {
-    //     iter::flat_map_to_vec(self, op)
-    // }
+    pure fn flat_map_to_vec>(op: fn(A) -> IB) -> ~[B] {
+        iter::flat_map_to_vec(&self, op)
+    }
 
     pub pure fn find(p: fn(a: A) -> bool) -> Option {
         iter::find(&self, p)
diff --git a/src/libstd/arc.rs b/src/libstd/arc.rs
index 60db62ce01ae..addabb2ddb9b 100644
--- a/src/libstd/arc.rs
+++ b/src/libstd/arc.rs
@@ -1,5 +1,5 @@
 // NB: transitionary, de-mode-ing.
-// tjc: forbid deprecated modes again after snap
+#[forbid(deprecated_mode)];
 /**
  * Concurrency-enabled mechanisms for sharing mutable and/or immutable state
  * between tasks.
diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs
index 4d2b910fa851..6a2ac88f7143 100644
--- a/src/libstd/arena.rs
+++ b/src/libstd/arena.rs
@@ -31,9 +31,10 @@ use libc::size_t;
 
 #[abi = "rust-intrinsic"]
 extern mod rusti {
-    fn move_val_init(&dst: T, -src: T);
+    fn move_val_init(dst: &mut T, -src: T);
     fn needs_drop() -> bool;
 }
+
 extern mod rustrt {
     #[rust_stack]
     fn rust_call_tydesc_glue(root: *u8, tydesc: *TypeDesc, field: size_t);
@@ -127,7 +128,6 @@ unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) {
     (reinterpret_cast(&(p & !1)), p & 1 == 1)
 }
 
-// The duplication between the POD and non-POD functions is annoying.
 impl &Arena {
     // Functions for the POD part of the arena
     fn alloc_pod_grow(n_bytes: uint, align: uint) -> *u8 {
@@ -166,7 +166,7 @@ impl &Arena {
             let tydesc = sys::get_type_desc::();
             let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
             let ptr: *mut T = reinterpret_cast(&ptr);
-            rusti::move_val_init(*ptr, op());
+            rusti::move_val_init(&mut (*ptr), op());
             return reinterpret_cast(&ptr);
         }
     }
@@ -217,7 +217,7 @@ impl &Arena {
             // has *not* been initialized yet.
             *ty_ptr = reinterpret_cast(&tydesc);
             // Actually initialize it
-            rusti::move_val_init(*ptr, op());
+            rusti::move_val_init(&mut(*ptr), op());
             // Now that we are done, update the tydesc to indicate that
             // the object is there.
             *ty_ptr = bitpack_tydesc_ptr(tydesc, true);
diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs
index 77f0d39c338e..91af4a3d6531 100644
--- a/src/libstd/bitv.rs
+++ b/src/libstd/bitv.rs
@@ -1,4 +1,4 @@
-// tjc: forbid deprecated modes again after snap
+#[forbid(deprecated_mode)];
 
 use vec::{to_mut, from_elem};
 
@@ -553,7 +553,7 @@ pure fn land(w0: uint, w1: uint) -> uint { return w0 & w1; }
 pure fn right(_w0: uint, w1: uint) -> uint { return w1; }
 
 impl Bitv: ops::Index {
-    pure fn index(+i: uint) -> bool {
+    pure fn index(i: uint) -> bool {
         self.get(i)
     }
 }
diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs
index 1ff5b63ee12f..06d56ed1ae52 100644
--- a/src/libstd/c_vec.rs
+++ b/src/libstd/c_vec.rs
@@ -25,6 +25,7 @@
  * great care must be taken to ensure that a reference to the c_vec::t is
  * still held if needed.
  */
+#[forbid(deprecated_mode)];
 
 /**
  * The type representing a foreign chunk of memory
@@ -111,7 +112,7 @@ pub fn get(t: CVec, ofs: uint) -> T {
  *
  * Fails if `ofs` is greater or equal to the length of the vector
  */
-pub fn set(t: CVec, ofs: uint, +v: T) {
+pub fn set(t: CVec, ofs: uint, v: T) {
     assert ofs < len(t);
     unsafe { *ptr::mut_offset((*t).base, ofs) = v };
 }
diff --git a/src/libstd/cell.rs b/src/libstd/cell.rs
index 866dbce1c085..c888957728a3 100644
--- a/src/libstd/cell.rs
+++ b/src/libstd/cell.rs
@@ -1,4 +1,4 @@
-// tjc: forbid deprecated modes again after snap
+#[forbid(deprecated_mode)];
 /// A dynamic, mutable location.
 ///
 /// Similar to a mutable option type, but friendlier.
diff --git a/src/libstd/comm.rs b/src/libstd/comm.rs
index 4d87ebeac99d..1a897a2c2fa9 100644
--- a/src/libstd/comm.rs
+++ b/src/libstd/comm.rs
@@ -16,11 +16,11 @@ pub struct DuplexStream {
 }
 
 impl DuplexStream : Channel {
-    fn send(+x: T) {
+    fn send(x: T) {
         self.chan.send(move x)
     }
 
-    fn try_send(+x: T) -> bool {
+    fn try_send(x: T) -> bool {
         self.chan.try_send(move x)
     }
 }
diff --git a/src/libstd/dbg.rs b/src/libstd/dbg.rs
index f85d4655ad14..f141a028e652 100644
--- a/src/libstd/dbg.rs
+++ b/src/libstd/dbg.rs
@@ -1,4 +1,4 @@
-// tjc: forbid deprecated modes again after snap
+#[forbid(deprecated_mode)];
 //! Unsafe debugging functions for inspecting values.
 
 use cast::reinterpret_cast;
diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs
index f4fbc11c4f71..37798d9a6273 100644
--- a/src/libstd/deque.rs
+++ b/src/libstd/deque.rs
@@ -1,5 +1,5 @@
 //! A deque. Untested as of yet. Likely buggy
-// tjc: forbid deprecated modes again after snap
+#[forbid(deprecated_mode)];
 #[forbid(non_camel_case_types)];
 
 use option::{Some, None};
@@ -200,7 +200,7 @@ mod tests {
         assert (deq.get(3) == d);
     }
 
-    fn test_parameterized(a: T, +b: T, +c: T, +d: T) {
+    fn test_parameterized(a: T, b: T, c: T, d: T) {
         let deq: deque::Deque = deque::create::();
         assert (deq.size() == 0u);
         deq.add_front(a);
diff --git a/src/libstd/ebml.rs b/src/libstd/ebml.rs
index 238e9d77a771..3df5a70a0c1f 100644
--- a/src/libstd/ebml.rs
+++ b/src/libstd/ebml.rs
@@ -1,3 +1,4 @@
+#[forbid(deprecated_mode)];
 // Simple Extensible Binary Markup Language (ebml) reader and writer on a
 // cursor model. See the specification here:
 //     http://www.matroska.org/technical/specs/rfc/index.html
@@ -17,7 +18,7 @@ pub type Doc = {data: @~[u8], start: uint, end: uint};
 type TaggedDoc = {tag: uint, doc: Doc};
 
 impl Doc: ops::Index {
-    pure fn index(+tag: uint) -> Doc {
+    pure fn index(tag: uint) -> Doc {
         unsafe {
             get_doc(self, tag)
         }
@@ -563,11 +564,11 @@ impl EbmlDeserializer: serialization::Deserializer {
 
 #[test]
 fn test_option_int() {
-    fn serialize_1(&&s: S, v: int) {
+    fn serialize_1(s: &S, v: int) {
         s.emit_i64(v as i64);
     }
 
-    fn serialize_0(&&s: S, v: Option) {
+    fn serialize_0(s: &S, v: Option) {
         do s.emit_enum(~"core::option::t") {
             match v {
               None => s.emit_enum_variant(
@@ -581,11 +582,11 @@ fn test_option_int() {
         }
     }
 
-    fn deserialize_1(&&s: S) -> int {
+    fn deserialize_1(s: &S) -> int {
         s.read_i64() as int
     }
 
-    fn deserialize_0(&&s: S) -> Option {
+    fn deserialize_0(s: &S) -> Option {
         do s.read_enum(~"core::option::t") {
             do s.read_enum_variant |i| {
                 match i {
@@ -608,11 +609,11 @@ fn test_option_int() {
         debug!("v == %?", v);
         let bytes = do io::with_bytes_writer |wr| {
             let ebml_w = ebml::Writer(wr);
-            serialize_0(ebml_w, v);
+            serialize_0(&ebml_w, v);
         };
         let ebml_doc = ebml::Doc(@bytes);
         let deser = ebml_deserializer(ebml_doc);
-        let v1 = deserialize_0(deser);
+        let v1 = deserialize_0(&deser);
         debug!("v1 == %?", v1);
         assert v == v1;
     }
diff --git a/src/libstd/ebml2.rs b/src/libstd/ebml2.rs
index 30d68da06f56..f88aad1ac633 100644
--- a/src/libstd/ebml2.rs
+++ b/src/libstd/ebml2.rs
@@ -1,3 +1,4 @@
+#[forbid(deprecated_mode)];
 use serialization2;
 
 // Simple Extensible Binary Markup Language (ebml) reader and writer on a
@@ -31,7 +32,7 @@ struct TaggedDoc {
 }
 
 impl Doc: ops::Index {
-    pure fn index(+tag: uint) -> Doc {
+    pure fn index(tag: uint) -> Doc {
         unsafe {
             get_doc(self, tag)
         }
diff --git a/src/libstd/fun_treemap.rs b/src/libstd/fun_treemap.rs
index 2973c8cc9f78..a1e29b03b455 100644
--- a/src/libstd/fun_treemap.rs
+++ b/src/libstd/fun_treemap.rs
@@ -1,4 +1,4 @@
-#[warn(deprecated_mode)];
+#[forbid(deprecated_mode)];
 
 /*!
  * A functional key,value store that works on anything.
@@ -26,7 +26,7 @@ enum TreeNode {
 pub fn init() -> Treemap { @Empty }
 
 /// Insert a value into the map
-pub fn insert(m: Treemap, +k: K, +v: V)
+pub fn insert(m: Treemap, k: K, v: V)
   -> Treemap {
     @match m {
        @Empty => Node(@k, @v, @Empty, @Empty),
@@ -41,7 +41,7 @@ pub fn insert(m: Treemap, +k: K, +v: V)
 }
 
 /// Find a value based on the key
-pub fn find(m: Treemap, +k: K) -> Option {
+pub fn find(m: Treemap, k: K) -> Option {
     match *m {
       Empty => None,
       Node(@ref kk, @copy v, left, right) => {
diff --git a/src/libstd/getopts.rs b/src/libstd/getopts.rs
index 771eaaeca7fa..6da51571e34a 100644
--- a/src/libstd/getopts.rs
+++ b/src/libstd/getopts.rs
@@ -61,8 +61,7 @@
  *         do_work(input, output);
  *     }
  */
-
-// tjc: forbid deprecated modes again after snap
+#[forbid(deprecated_mode)];
 
 use core::cmp::Eq;
 use core::result::{Err, Ok};
@@ -162,7 +161,7 @@ fn name_str(nm: &Name) -> ~str {
     };
 }
 
-fn find_opt(opts: &[Opt], +nm: Name) -> Option {
+fn find_opt(opts: &[Opt], nm: Name) -> Option {
     vec::position(opts, |opt| opt.name == nm)
 }
 
@@ -214,7 +213,7 @@ pub type Result = result::Result;
  */
 pub fn getopts(args: &[~str], opts: &[Opt]) -> Result unsafe {
     let n_opts = vec::len::(opts);
-    fn f(+_x: uint) -> ~[Optval] { return ~[]; }
+    fn f(_x: uint) -> ~[Optval] { return ~[]; }
     let vals = vec::to_mut(vec::from_fn(n_opts, f));
     let mut free: ~[~str] = ~[];
     let l = vec::len(args);
diff --git a/src/libstd/json.rs b/src/libstd/json.rs
index f244f2869a60..09d002162093 100644
--- a/src/libstd/json.rs
+++ b/src/libstd/json.rs
@@ -1,6 +1,6 @@
 // Rust JSON serialization library
 // Copyright (c) 2011 Google Inc.
-// tjc: forbid deprecated modes again after snap
+#[forbid(deprecated_mode)];
 #[forbid(non_camel_case_types)];
 
 //! json serialization
@@ -399,7 +399,7 @@ priv impl Parser {
         while char::is_whitespace(self.ch) { self.bump(); }
     }
 
-    fn parse_ident(ident: &str, +value: Json) -> Result {
+    fn parse_ident(ident: &str, value: Json) -> Result {
         if str::all(ident, |c| c == self.next_char()) {
             self.bump();
             Ok(move value)
diff --git a/src/libstd/list.rs b/src/libstd/list.rs
index 4ff493f5ab91..396edb548850 100644
--- a/src/libstd/list.rs
+++ b/src/libstd/list.rs
@@ -1,5 +1,5 @@
 //! A standard linked list
-#[warn(deprecated_mode)];
+#[forbid(deprecated_mode)];
 
 use core::cmp::Eq;
 use core::option;
@@ -56,7 +56,7 @@ pub fn find(ls: @List, f: fn((&T)) -> bool) -> Option {
 }
 
 /// Returns true if a list contains an element with the given value
-pub fn has(ls: @List, +elt: T) -> bool {
+pub fn has(ls: @List, elt: T) -> bool {
     for each(ls) |e| {
         if *e == elt { return true; }
     }
@@ -114,7 +114,7 @@ pub pure fn append(l: @List, m: @List) -> @List {
 /*
 /// Push one element into the front of a list, returning a new list
 /// THIS VERSION DOESN'T ACTUALLY WORK
-pure fn push(ll: &mut @list, +vv: T) {
+pure fn push(ll: &mut @list, vv: T) {
     ll = &mut @cons(vv, *ll)
 }
 */
diff --git a/src/libstd/map.rs b/src/libstd/map.rs
index cc42c5623762..765d40339d3c 100644
--- a/src/libstd/map.rs
+++ b/src/libstd/map.rs
@@ -1,6 +1,5 @@
 //! A map type
-
-// tjc: forbid deprecated modes again after snap
+#[forbid(deprecated_mode)];
 
 use io::WriterUtil;
 use to_str::ToStr;
@@ -28,7 +27,7 @@ pub trait Map {
      *
      * Returns true if the key did not already exist in the map
      */
-    fn insert(v: K, +v: V) -> bool;
+    fn insert(v: K, v: V) -> bool;
 
     /// Returns true if the map contains a value for the specified key
     fn contains_key(key: K) -> bool;
@@ -59,7 +58,7 @@ pub trait Map {
     fn clear();
 
     /// Iterate over all the key/value pairs in the map by value
-    pure fn each(fn(key: K, +value: V) -> bool);
+    pure fn each(fn(key: K, value: V) -> bool);
 
     /// Iterate over all the keys in the map by value
     pure fn each_key(fn(key: K) -> bool);
@@ -213,7 +212,7 @@ pub mod chained {
             }
         }
 
-        fn insert(k: K, +v: V) -> bool {
+        fn insert(k: K, v: V) -> bool {
             let hash = k.hash_keyed(0,0) as uint;
             match self.search_tbl(&k, hash) {
               NotFound => {
@@ -294,7 +293,7 @@ pub mod chained {
             self.chains = chains(initial_capacity);
         }
 
-        pure fn each(blk: fn(key: K, +value: V) -> bool) {
+        pure fn each(blk: fn(key: K, value: V) -> bool) {
             self.each_ref(|k, v| blk(*k, *v))
         }
 
@@ -348,7 +347,7 @@ pub mod chained {
     }
 
     impl T: ops::Index {
-        pure fn index(+k: K) -> V {
+        pure fn index(k: K) -> V {
             unsafe {
                 self.get(k)
             }
@@ -382,7 +381,7 @@ pub fn set_add(set: Set, key: K) -> bool {
 }
 
 /// Convert a set into a vector.
-pub fn vec_from_set(s: Set) -> ~[T] {
+pub pure fn vec_from_set(s: Set) -> ~[T] {
     do vec::build_sized(s.size()) |push| {
         for s.each_key() |k| {
             push(k);
@@ -459,7 +458,7 @@ impl @Mut>:
         }
     }
 
-    pure fn each(op: fn(key: K, +value: V) -> bool) {
+    pure fn each(op: fn(key: K, value: V) -> bool) {
         unsafe {
             do self.borrow_imm |p| {
                 p.each(|k, v| op(*k, *v))
diff --git a/src/libstd/net_tcp.rs b/src/libstd/net_tcp.rs
index 546231da6333..249551fbb7df 100644
--- a/src/libstd/net_tcp.rs
+++ b/src/libstd/net_tcp.rs
@@ -1,4 +1,6 @@
 //! High-level interface to libuv's TCP functionality
+// XXX Need FFI fixes
+#[allow(deprecated_mode)];
 
 use ip = net_ip;
 use uv::iotask;
@@ -121,8 +123,8 @@ pub fn connect(input_ip: ip::IpAddr, port: uint,
     let result_po = core::comm::Port::();
     let closed_signal_po = core::comm::Port::<()>();
     let conn_data = {
-        result_ch: core::comm::Chan(result_po),
-        closed_signal_ch: core::comm::Chan(closed_signal_po)
+        result_ch: core::comm::Chan(&result_po),
+        closed_signal_ch: core::comm::Chan(&closed_signal_po)
     };
     let conn_data_ptr = ptr::addr_of(&conn_data);
     let reader_po = core::comm::Port::>();
@@ -130,7 +132,7 @@ pub fn connect(input_ip: ip::IpAddr, port: uint,
     *(stream_handle_ptr as *mut uv::ll::uv_tcp_t) = uv::ll::tcp_t();
     let socket_data = @{
         reader_po: reader_po,
-        reader_ch: core::comm::Chan(reader_po),
+        reader_ch: core::comm::Chan(&reader_po),
         stream_handle_ptr: stream_handle_ptr,
         connect_req: uv::ll::connect_t(),
         write_req: uv::ll::write_t(),
@@ -324,7 +326,7 @@ pub fn read_start(sock: &TcpSocket)
  * * `sock` - a `net::tcp::tcp_socket` that you wish to stop reading on
  */
 pub fn read_stop(sock: &TcpSocket,
-             +read_port: comm::Port>) ->
+             read_port: comm::Port>) ->
     result::Result<(), TcpErrData> unsafe {
     log(debug, fmt!("taking the read_port out of commission %?", read_port));
     let socket_data = ptr::addr_of(&(*sock.socket_data));
@@ -471,7 +473,7 @@ pub fn accept(new_conn: TcpNewConnection)
         *(stream_handle_ptr as *mut uv::ll::uv_tcp_t) = uv::ll::tcp_t();
         let client_socket_data = @{
             reader_po: reader_po,
-            reader_ch: core::comm::Chan(reader_po),
+            reader_ch: core::comm::Chan(&reader_po),
             stream_handle_ptr : stream_handle_ptr,
             connect_req : uv::ll::connect_t(),
             write_req : uv::ll::write_t(),
@@ -482,7 +484,7 @@ pub fn accept(new_conn: TcpNewConnection)
             (*client_socket_data_ptr).stream_handle_ptr;
 
         let result_po = core::comm::Port::>();
-        let result_ch = core::comm::Chan(result_po);
+        let result_ch = core::comm::Chan(&result_po);
 
         // UNSAFE LIBUV INTERACTION BEGIN
         // .. normally this happens within the context of
@@ -558,8 +560,8 @@ pub fn accept(new_conn: TcpNewConnection)
  */
 pub fn listen(host_ip: ip::IpAddr, port: uint, backlog: uint,
           iotask: IoTask,
-          +on_establish_cb: fn~(comm::Chan>),
-          +new_connect_cb: fn~(TcpNewConnection,
+          on_establish_cb: fn~(comm::Chan>),
+          new_connect_cb: fn~(TcpNewConnection,
                                comm::Chan>))
     -> result::Result<(), TcpListenErrData> unsafe {
     do listen_common(move host_ip, port, backlog, iotask, on_establish_cb)
@@ -575,17 +577,17 @@ pub fn listen(host_ip: ip::IpAddr, port: uint, backlog: uint,
 
 fn listen_common(host_ip: ip::IpAddr, port: uint, backlog: uint,
           iotask: IoTask,
-          +on_establish_cb: fn~(comm::Chan>),
-          +on_connect_cb: fn~(*uv::ll::uv_tcp_t))
+          on_establish_cb: fn~(comm::Chan>),
+          on_connect_cb: fn~(*uv::ll::uv_tcp_t))
     -> result::Result<(), TcpListenErrData> unsafe {
     let stream_closed_po = core::comm::Port::<()>();
     let kill_po = core::comm::Port::>();
-    let kill_ch = core::comm::Chan(kill_po);
+    let kill_ch = core::comm::Chan(&kill_po);
     let server_stream = uv::ll::tcp_t();
     let server_stream_ptr = ptr::addr_of(&server_stream);
     let server_data = {
         server_stream_ptr: server_stream_ptr,
-        stream_closed_ch: core::comm::Chan(stream_closed_po),
+        stream_closed_ch: core::comm::Chan(&stream_closed_po),
         kill_ch: kill_ch,
         on_connect_cb: move on_connect_cb,
         iotask: iotask,
@@ -749,7 +751,7 @@ impl TcpSocket {
 
 /// Implementation of `io::reader` trait for a buffered `net::tcp::tcp_socket`
 impl TcpSocketBuf: io::Reader {
-    fn read(buf: &[mut u8], +len: uint) -> uint {
+    fn read(buf: &[mut u8], len: uint) -> uint {
         // Loop until our buffer has enough data in it for us to read from.
         while self.data.buf.len() < len {
             let read_result = read(&self.data.sock, 0u);
@@ -785,13 +787,13 @@ impl TcpSocketBuf: io::Reader {
         let mut bytes = ~[0];
         if self.read(bytes, 1u) == 0 { fail } else { bytes[0] as int }
     }
-    fn unread_byte(+amt: int) {
+    fn unread_byte(amt: int) {
         self.data.buf.unshift(amt as u8);
     }
     fn eof() -> bool {
         false // noop
     }
-    fn seek(+dist: int, +seek: io::SeekStyle) {
+    fn seek(dist: int, seek: io::SeekStyle) {
         log(debug, fmt!("tcp_socket_buf seek stub %? %?", dist, seek));
         // noop
     }
@@ -813,7 +815,7 @@ impl TcpSocketBuf: io::Writer {
                              err_data.err_name, err_data.err_msg));
         }
     }
-    fn seek(+dist: int, +seek: io::SeekStyle) {
+    fn seek(dist: int, seek: io::SeekStyle) {
       log(debug, fmt!("tcp_socket_buf seek stub %? %?", dist, seek));
         // noop
     }
@@ -832,7 +834,7 @@ impl TcpSocketBuf: io::Writer {
 
 fn tear_down_socket_data(socket_data: @TcpSocketData) unsafe {
     let closed_po = core::comm::Port::<()>();
-    let closed_ch = core::comm::Chan(closed_po);
+    let closed_ch = core::comm::Chan(&closed_po);
     let close_data = {
         closed_ch: closed_ch
     };
@@ -895,7 +897,7 @@ fn read_stop_common_impl(socket_data: *TcpSocketData) ->
     result::Result<(), TcpErrData> unsafe {
     let stream_handle_ptr = (*socket_data).stream_handle_ptr;
     let stop_po = core::comm::Port::>();
-    let stop_ch = core::comm::Chan(stop_po);
+    let stop_ch = core::comm::Chan(&stop_po);
     do iotask::interact((*socket_data).iotask) |loop_ptr| unsafe {
         log(debug, ~"in interact cb for tcp::read_stop");
         match uv::ll::read_stop(stream_handle_ptr as *uv::ll::uv_stream_t) {
@@ -922,7 +924,7 @@ fn read_start_common_impl(socket_data: *TcpSocketData)
         result::Result<~[u8], TcpErrData>>, TcpErrData> unsafe {
     let stream_handle_ptr = (*socket_data).stream_handle_ptr;
     let start_po = core::comm::Port::>();
-    let start_ch = core::comm::Chan(start_po);
+    let start_ch = core::comm::Chan(&start_po);
     log(debug, ~"in tcp::read_start before interact loop");
     do iotask::interact((*socket_data).iotask) |loop_ptr| unsafe {
         log(debug, fmt!("in tcp::read_start interact cb %?", loop_ptr));
@@ -961,7 +963,7 @@ fn write_common_impl(socket_data_ptr: *TcpSocketData,
     let write_buf_vec_ptr = ptr::addr_of(&write_buf_vec);
     let result_po = core::comm::Port::();
     let write_data = {
-        result_ch: core::comm::Chan(result_po)
+        result_ch: core::comm::Chan(&result_po)
     };
     let write_data_ptr = ptr::addr_of(&write_data);
     do iotask::interact((*socket_data_ptr).iotask) |loop_ptr| unsafe {
@@ -1277,10 +1279,10 @@ mod test {
         let expected_resp = ~"pong";
 
         let server_result_po = core::comm::Port::<~str>();
-        let server_result_ch = core::comm::Chan(server_result_po);
+        let server_result_ch = core::comm::Chan(&server_result_po);
 
         let cont_po = core::comm::Port::<()>();
-        let cont_ch = core::comm::Chan(cont_po);
+        let cont_ch = core::comm::Chan(&cont_po);
         // server
         do task::spawn_sched(task::ManualThreads(1u)) {
             let actual_req = do comm::listen |server_ch| {
@@ -1343,10 +1345,10 @@ mod test {
         let expected_resp = ~"pong";
 
         let server_result_po = core::comm::Port::<~str>();
-        let server_result_ch = core::comm::Chan(server_result_po);
+        let server_result_ch = core::comm::Chan(&server_result_po);
 
         let cont_po = core::comm::Port::<()>();
-        let cont_ch = core::comm::Chan(cont_po);
+        let cont_ch = core::comm::Chan(&cont_po);
         // server
         do task::spawn_sched(task::ManualThreads(1u)) {
             let actual_req = do comm::listen |server_ch| {
@@ -1474,7 +1476,7 @@ mod test {
         str::from_bytes(new_bytes)
     }
 
-    fn run_tcp_test_server(server_ip: &str, server_port: uint, +resp: ~str,
+    fn run_tcp_test_server(server_ip: &str, server_port: uint, resp: ~str,
                           server_ch: comm::Chan<~str>,
                           cont_ch: comm::Chan<()>,
                           iotask: IoTask) -> ~str {
diff --git a/src/libstd/net_url.rs b/src/libstd/net_url.rs
index 40c9f96f5e84..0ab4d89f3635 100644
--- a/src/libstd/net_url.rs
+++ b/src/libstd/net_url.rs
@@ -1,5 +1,5 @@
 //! Types/fns concerning URLs (see RFC 3986)
-// tjc: forbid deprecated modes again after a snapshot
+#[forbid(deprecated_mode)];
 
 use core::cmp::Eq;
 use map::HashMap;
@@ -27,15 +27,15 @@ type UserInfo = {
 
 pub type Query = ~[(~str, ~str)];
 
-pub fn Url(scheme: ~str, +user: Option, +host: ~str,
-       +port: Option<~str>, +path: ~str, +query: Query,
-       +fragment: Option<~str>) -> Url {
+pub fn Url(scheme: ~str, user: Option, host: ~str,
+       port: Option<~str>, path: ~str, query: Query,
+       fragment: Option<~str>) -> Url {
     Url { scheme: move scheme, user: move user, host: move host,
          port: move port, path: move path, query: move query,
          fragment: move fragment }
 }
 
-fn UserInfo(user: ~str, +pass: Option<~str>) -> UserInfo {
+fn UserInfo(user: ~str, pass: Option<~str>) -> UserInfo {
     {user: move user, pass: move pass}
 }
 
@@ -726,7 +726,7 @@ impl Url : Eq {
 }
 
 impl Url: IterBytes {
-    pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) {
+    pure fn iter_bytes(lsb0: bool, f: to_bytes::Cb) {
         unsafe { self.to_str() }.iter_bytes(lsb0, f)
     }
 }
diff --git a/src/libstd/par.rs b/src/libstd/par.rs
index 65e41dba5d83..e5336b7204d2 100644
--- a/src/libstd/par.rs
+++ b/src/libstd/par.rs
@@ -1,3 +1,5 @@
+#[forbid(deprecated_mode)];
+
 use future_spawn = future::spawn;
 
 
@@ -72,7 +74,7 @@ fn map_slices(
 }
 
 /// A parallel version of map.
-pub fn map(xs: &[A], +f: fn~((&A)) -> B) -> ~[B] {
+pub fn map(xs: &[A], f: fn~((&A)) -> B) -> ~[B] {
     vec::concat(map_slices(xs, || {
         fn~(_base: uint, slice : &[A], copy f) -> ~[B] {
             vec::map(slice, |x| f(x))
@@ -82,7 +84,7 @@ pub fn map(xs: &[A], +f: fn~((&A)) -> B) -> ~[B] {
 
 /// A parallel version of mapi.
 pub fn mapi(xs: &[A],
-                                    +f: fn~(uint, (&A)) -> B) -> ~[B] {
+                                    f: fn~(uint, (&A)) -> B) -> ~[B] {
     let slices = map_slices(xs, || {
         fn~(base: uint, slice : &[A], copy f) -> ~[B] {
             vec::mapi(slice, |i, x| {
@@ -119,7 +121,7 @@ pub fn mapi_factory(
 }
 
 /// Returns true if the function holds for all elements in the vector.
-pub fn alli(xs: &[A], +f: fn~(uint, (&A)) -> bool) -> bool {
+pub fn alli(xs: &[A], f: fn~(uint, (&A)) -> bool) -> bool {
     do vec::all(map_slices(xs, || {
         fn~(base: uint, slice : &[A], copy f) -> bool {
             vec::alli(slice, |i, x| {
@@ -130,7 +132,7 @@ pub fn alli(xs: &[A], +f: fn~(uint, (&A)) -> bool) -> bool {
 }
 
 /// Returns true if the function holds for any elements in the vector.
-pub fn any(xs: &[A], +f: fn~(&(A)) -> bool) -> bool {
+pub fn any(xs: &[A], f: fn~(&(A)) -> bool) -> bool {
     do vec::any(map_slices(xs, || {
         fn~(_base : uint, slice: &[A], copy f) -> bool {
             vec::any(slice, |x| f(x))
diff --git a/src/libstd/serialization.rs b/src/libstd/serialization.rs
index e9067bc64042..8ba00e65dec9 100644
--- a/src/libstd/serialization.rs
+++ b/src/libstd/serialization.rs
@@ -1,10 +1,12 @@
 //! Support code for serialization.
 
+#[allow(deprecated_mode)];
+
 /*
 Core serialization interfaces.
 */
 
-trait Serializer {
+pub trait Serializer {
     // Primitive types:
     fn emit_nil();
     fn emit_uint(v: uint);
@@ -37,7 +39,7 @@ trait Serializer {
     fn emit_tup_elt(idx: uint, f: fn());
 }
 
-trait Deserializer {
+pub trait Deserializer {
     // Primitive types:
     fn read_nil() -> ();
 
@@ -81,7 +83,7 @@ trait Deserializer {
 //
 // In some cases, these should eventually be coded as traits.
 
-fn emit_from_vec(&&s: S, &&v: ~[T], f: fn(&&x: T)) {
+pub fn emit_from_vec(&&s: S, &&v: ~[T], f: fn(&&x: T)) {
     do s.emit_vec(vec::len(v)) {
         for vec::eachi(v) |i,e| {
             do s.emit_vec_elt(i) {
@@ -91,7 +93,7 @@ fn emit_from_vec(&&s: S, &&v: ~[T], f: fn(&&x: T)) {
     }
 }
 
-fn read_to_vec(&&d: D, f: fn() -> T) -> ~[T] {
+pub fn read_to_vec(&&d: D, f: fn() -> T) -> ~[T] {
     do d.read_vec |len| {
         do vec::from_fn(len) |i| {
             d.read_vec_elt(i, || f())
@@ -99,7 +101,7 @@ fn read_to_vec(&&d: D, f: fn() -> T) -> ~[T] {
     }
 }
 
-trait SerializerHelpers {
+pub trait SerializerHelpers {
     fn emit_from_vec(&&v: ~[T], f: fn(&&x: T));
 }
 
@@ -109,7 +111,7 @@ impl S: SerializerHelpers {
     }
 }
 
-trait DeserializerHelpers {
+pub trait DeserializerHelpers {
     fn read_to_vec(f: fn() -> T) -> ~[T];
 }
 
@@ -119,127 +121,128 @@ impl D: DeserializerHelpers {
     }
 }
 
-fn serialize_uint(&&s: S, v: uint) {
+pub fn serialize_uint(&&s: S, v: uint) {
     s.emit_uint(v);
 }
 
-fn deserialize_uint(&&d: D) -> uint {
+pub fn deserialize_uint(&&d: D) -> uint {
     d.read_uint()
 }
 
-fn serialize_u8(&&s: S, v: u8) {
+pub fn serialize_u8(&&s: S, v: u8) {
     s.emit_u8(v);
 }
 
-fn deserialize_u8(&&d: D) -> u8 {
+pub fn deserialize_u8(&&d: D) -> u8 {
     d.read_u8()
 }
 
-fn serialize_u16(&&s: S, v: u16) {
+pub fn serialize_u16(&&s: S, v: u16) {
     s.emit_u16(v);
 }
 
-fn deserialize_u16(&&d: D) -> u16 {
+pub fn deserialize_u16(&&d: D) -> u16 {
     d.read_u16()
 }
 
-fn serialize_u32(&&s: S, v: u32) {
+pub fn serialize_u32(&&s: S, v: u32) {
     s.emit_u32(v);
 }
 
-fn deserialize_u32(&&d: D) -> u32 {
+pub fn deserialize_u32(&&d: D) -> u32 {
     d.read_u32()
 }
 
-fn serialize_u64(&&s: S, v: u64) {
+pub fn serialize_u64(&&s: S, v: u64) {
     s.emit_u64(v);
 }
 
-fn deserialize_u64(&&d: D) -> u64 {
+pub fn deserialize_u64(&&d: D) -> u64 {
     d.read_u64()
 }
 
-fn serialize_int(&&s: S, v: int) {
+pub fn serialize_int(&&s: S, v: int) {
     s.emit_int(v);
 }
 
-fn deserialize_int(&&d: D) -> int {
+pub fn deserialize_int(&&d: D) -> int {
     d.read_int()
 }
 
-fn serialize_i8(&&s: S, v: i8) {
+pub fn serialize_i8(&&s: S, v: i8) {
     s.emit_i8(v);
 }
 
-fn deserialize_i8(&&d: D) -> i8 {
+pub fn deserialize_i8(&&d: D) -> i8 {
     d.read_i8()
 }
 
-fn serialize_i16(&&s: S, v: i16) {
+pub fn serialize_i16(&&s: S, v: i16) {
     s.emit_i16(v);
 }
 
-fn deserialize_i16(&&d: D) -> i16 {
+pub fn deserialize_i16(&&d: D) -> i16 {
     d.read_i16()
 }
 
-fn serialize_i32(&&s: S, v: i32) {
+pub fn serialize_i32(&&s: S, v: i32) {
     s.emit_i32(v);
 }
 
-fn deserialize_i32(&&d: D) -> i32 {
+pub fn deserialize_i32(&&d: D) -> i32 {
     d.read_i32()
 }
 
-fn serialize_i64(&&s: S, v: i64) {
+pub fn serialize_i64(&&s: S, v: i64) {
     s.emit_i64(v);
 }
 
-fn deserialize_i64(&&d: D) -> i64 {
+pub fn deserialize_i64(&&d: D) -> i64 {
     d.read_i64()
 }
 
-fn serialize_str(&&s: S, v: &str) {
+pub fn serialize_str(&&s: S, v: &str) {
     s.emit_str(v);
 }
 
-fn deserialize_str(&&d: D) -> ~str {
+pub fn deserialize_str(&&d: D) -> ~str {
     d.read_str()
 }
 
-fn serialize_float(&&s: S, v: float) {
+pub fn serialize_float(&&s: S, v: float) {
     s.emit_float(v);
 }
 
-fn deserialize_float(&&d: D) -> float {
+pub fn deserialize_float(&&d: D) -> float {
     d.read_float()
 }
 
-fn serialize_f32(&&s: S, v: f32) {
+pub fn serialize_f32(&&s: S, v: f32) {
     s.emit_f32(v);
 }
 
-fn deserialize_f32(&&d: D) -> f32 {
+pub fn deserialize_f32(&&d: D) -> f32 {
     d.read_f32()
 }
 
-fn serialize_f64(&&s: S, v: f64) {
+pub fn serialize_f64(&&s: S, v: f64) {
     s.emit_f64(v);
 }
 
-fn deserialize_f64(&&d: D) -> f64 {
+pub fn deserialize_f64(&&d: D) -> f64 {
     d.read_f64()
 }
 
-fn serialize_bool(&&s: S, v: bool) {
+pub fn serialize_bool(&&s: S, v: bool) {
     s.emit_bool(v);
 }
 
-fn deserialize_bool(&&d: D) -> bool {
+pub fn deserialize_bool(&&d: D) -> bool {
     d.read_bool()
 }
 
-fn serialize_Option(&&s: S, &&v: Option, st: fn(&&x: T)) {
+pub fn serialize_Option(&&s: S, &&v: Option,
+                                         st: fn(&&x: T)) {
     do s.emit_enum(~"option") {
         match v {
           None => do s.emit_enum_variant(~"none", 0u, 0u) {
@@ -254,7 +257,7 @@ fn serialize_Option(&&s: S, &&v: Option, st: fn(&&x: T)) {
     }
 }
 
-fn deserialize_Option(&&d: D, st: fn() -> T)
+pub fn deserialize_Option(&&d: D, st: fn() -> T)
     -> Option {
     do d.read_enum(~"option") {
         do d.read_enum_variant |i| {
diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs
index 58ecbb0d6c3a..1582d90ce2d6 100644
--- a/src/libstd/smallintmap.rs
+++ b/src/libstd/smallintmap.rs
@@ -2,7 +2,7 @@
  * A simple map based on a vector for small integer keys. Space requirements
  * are O(highest integer key).
  */
-// tjc: forbid deprecated modes again after snap
+#[forbid(deprecated_mode)];
 
 use core::option;
 use core::option::{Some, None};
@@ -103,7 +103,7 @@ impl SmallIntMap: map::Map {
     pure fn find(key: uint) -> Option { find(self, key) }
     fn rehash() { fail }
 
-    pure fn each(it: fn(key: uint, +value: V) -> bool) {
+    pure fn each(it: fn(key: uint, value: V) -> bool) {
         self.each_ref(|k, v| it(*k, *v))
     }
     pure fn each_key(it: fn(key: uint) -> bool) {
@@ -131,7 +131,7 @@ impl SmallIntMap: map::Map {
 }
 
 impl SmallIntMap: ops::Index {
-    pure fn index(+key: uint) -> V {
+    pure fn index(key: uint) -> V {
         unsafe {
             get(self, key)
         }
diff --git a/src/libstd/std.rc b/src/libstd/std.rc
index 6a5658d24eb0..7fc3004bbcfa 100644
--- a/src/libstd/std.rc
+++ b/src/libstd/std.rc
@@ -18,86 +18,72 @@ not required in or otherwise suitable for the core library.
 
 #[no_core];
 
-#[legacy_exports];
-
 #[allow(vecs_implicitly_copyable)];
 #[deny(non_camel_case_types)];
+// XXX this is set to allow because there are two methods in serialization
+// that can't be silenced otherwise. Most every module is set to forbid
+#[allow(deprecated_mode)];
 #[forbid(deprecated_pattern)];
 
 extern mod core(vers = "0.4");
 use core::*;
 
-export net, net_tcp, net_ip, net_url;
-export uv, uv_ll, uv_iotask, uv_global_loop;
-export c_vec, timer;
-export sync, arc, comm;
-export bitv, deque, fun_treemap, list, map;
-export smallintmap, sort, treemap;
-export rope, arena, par;
-export ebml, ebml2;
-export dbg, getopts, json, rand, sha1, term, time;
-export prettyprint, prettyprint2;
-export test, tempfile, serialization, serialization2;
-export cmp;
-export base64;
-export cell;
-
 // General io and system-services modules
 
-mod net;
-mod net_ip;
-mod net_tcp;
-mod net_url;
+pub mod net;
+pub mod net_ip;
+pub mod net_tcp;
+pub mod net_url;
 
 // libuv modules
-mod uv;
-mod uv_ll;
-mod uv_iotask;
-mod uv_global_loop;
+pub mod uv;
+pub mod uv_ll;
+pub mod uv_iotask;
+pub mod uv_global_loop;
 
 
 // Utility modules
 
-mod c_vec;
-mod timer;
-mod cell;
+pub mod c_vec;
+pub mod timer;
+pub mod cell;
 
 // Concurrency
 
-mod sync;
-mod arc;
-mod comm;
+pub mod sync;
+pub mod arc;
+pub mod comm;
 
 // Collections
 
-mod bitv;
-mod deque;
-mod fun_treemap;
-mod list;
-mod map;
-mod rope;
-mod smallintmap;
-mod sort;
-mod treemap;
+pub mod bitv;
+pub mod deque;
+pub mod fun_treemap;
+pub mod list;
+pub mod map;
+pub mod rope;
+pub mod smallintmap;
+pub mod sort;
+pub mod treemap;
 
 // And ... other stuff
 
-mod ebml;
-mod ebml2;
-mod dbg;
-mod getopts;
-mod json;
-mod sha1;
-mod md4;
-mod tempfile;
-mod term;
-mod time;
-mod prettyprint;
-mod prettyprint2;
-mod arena;
-mod par;
-mod cmp;
-mod base64;
+pub mod ebml;
+pub mod ebml2;
+pub mod dbg;
+pub mod getopts;
+pub mod json;
+pub mod sha1;
+pub mod md4;
+pub mod tempfile;
+pub mod term;
+pub mod time;
+pub mod prettyprint;
+pub mod prettyprint2;
+pub mod arena;
+pub mod par;
+pub mod cmp;
+pub mod base64;
 
 #[cfg(unicode)]
 mod unicode;
@@ -105,10 +91,9 @@ mod unicode;
 
 // Compiler support modules
 
-mod test;
-#[legacy_exports]
-mod serialization;
-mod serialization2;
+pub mod test;
+pub mod serialization;
+pub mod serialization2;
 
 // Local Variables:
 // mode: rust;
diff --git a/src/libstd/sync.rs b/src/libstd/sync.rs
index f66134d38923..908f3936f4e1 100644
--- a/src/libstd/sync.rs
+++ b/src/libstd/sync.rs
@@ -1,5 +1,5 @@
 // NB: transitionary, de-mode-ing.
-// tjc: forbid deprecated modes again after snap
+#[forbid(deprecated_mode)];
 /**
  * The concurrency primitives you know and love.
  *
@@ -773,7 +773,7 @@ mod tests {
         let m = ~Mutex();
         let m2 = ~m.clone();
         let mut sharedstate = ~0;
-        let ptr = ptr::p2::addr_of(&(*sharedstate));
+        let ptr = ptr::addr_of(&(*sharedstate));
         do task::spawn {
             let sharedstate: &mut int =
                 unsafe { cast::reinterpret_cast(&ptr) };
@@ -1045,7 +1045,7 @@ mod tests {
         let (c,p) = pipes::stream();
         let x2 = ~x.clone();
         let mut sharedstate = ~0;
-        let ptr = ptr::p2::addr_of(&(*sharedstate));
+        let ptr = ptr::addr_of(&(*sharedstate));
         do task::spawn {
             let sharedstate: &mut int =
                 unsafe { cast::reinterpret_cast(&ptr) };
diff --git a/src/libstd/test.rs b/src/libstd/test.rs
index 5fb7df1f68c6..9790622332a2 100644
--- a/src/libstd/test.rs
+++ b/src/libstd/test.rs
@@ -5,7 +5,7 @@
 // simplest interface possible for representing and running tests
 // while providing a base that other test frameworks may build off of.
 
-#[warn(deprecated_mode)];
+#[forbid(deprecated_mode)];
 
 use core::cmp::Eq;
 use either::Either;
@@ -286,7 +286,7 @@ fn run_tests(opts: &TestOpts, tests: &[TestDesc],
     let mut done_idx = 0;
 
     let p = core::comm::Port();
-    let ch = core::comm::Chan(p);
+    let ch = core::comm::Chan(&p);
 
     while done_idx < total {
         while wait_idx < concurrency && run_idx < total {
@@ -421,7 +421,7 @@ mod tests {
             should_fail: false
         };
         let p = core::comm::Port();
-        let ch = core::comm::Chan(p);
+        let ch = core::comm::Chan(&p);
         run_test(desc, ch);
         let (_, res) = core::comm::recv(p);
         assert res != TrOk;
@@ -437,7 +437,7 @@ mod tests {
             should_fail: false
         };
         let p = core::comm::Port();
-        let ch = core::comm::Chan(p);
+        let ch = core::comm::Chan(&p);
         run_test(desc, ch);
         let (_, res) = core::comm::recv(p);
         assert res == TrIgnored;
@@ -454,7 +454,7 @@ mod tests {
             should_fail: true
         };
         let p = core::comm::Port();
-        let ch = core::comm::Chan(p);
+        let ch = core::comm::Chan(&p);
         run_test(desc, ch);
         let (_, res) = core::comm::recv(p);
         assert res == TrOk;
@@ -470,7 +470,7 @@ mod tests {
             should_fail: true
         };
         let p = core::comm::Port();
-        let ch = core::comm::Chan(p);
+        let ch = core::comm::Chan(&p);
         run_test(desc, ch);
         let (_, res) = core::comm::recv(p);
         assert res == TrFailed;
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index aef3bb2ac0ad..65872a013aba 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -1,4 +1,4 @@
-// tjc: forbid deprecated modes again after snap
+#[forbid(deprecated_mode)];
 
 use core::cmp::Eq;
 use libc::{c_char, c_int, c_long, size_t, time_t};
@@ -7,16 +7,17 @@ use result::{Result, Ok, Err};
 
 #[abi = "cdecl"]
 extern mod rustrt {
-    #[legacy_exports];
-    fn get_time(&sec: i64, &nsec: i32);
-    fn precise_time_ns(&ns: u64);
+    #[legacy_exports]
+    fn get_time(sec: &mut i64, nsec: &mut i32);
+
+    fn precise_time_ns(ns: &mut u64);
 
     fn rust_tzset();
     // FIXME: The i64 values can be passed by-val when #2064 is fixed.
     fn rust_gmtime(&&sec: i64, &&nsec: i32, &&result: Tm);
     fn rust_localtime(&&sec: i64, &&nsec: i32, &&result: Tm);
-    fn rust_timegm(&&tm: Tm, &sec: i64);
-    fn rust_mktime(&&tm: Tm, &sec: i64);
+    fn rust_timegm(&&tm: Tm, sec: &mut i64);
+    fn rust_mktime(&&tm: Tm, sec: &mut i64);
 }
 
 /// A record specifying a time value in seconds and nanoseconds.
@@ -36,20 +37,22 @@ impl Timespec : Eq {
 pub fn get_time() -> Timespec {
     let mut sec = 0i64;
     let mut nsec = 0i32;
-    rustrt::get_time(sec, nsec);
+    rustrt::get_time(&mut sec, &mut nsec);
     return {sec: sec, nsec: nsec};
 }
 
+
 /**
  * Returns the current value of a high-resolution performance counter
  * in nanoseconds since an unspecified epoch.
  */
 pub fn precise_time_ns() -> u64 {
     let mut ns = 0u64;
-    rustrt::precise_time_ns(ns);
+    rustrt::precise_time_ns(&mut ns);
     ns
 }
 
+
 /**
  * Returns the current value of a high-resolution performance counter
  * in seconds since an unspecified epoch.
@@ -762,9 +765,9 @@ impl Tm {
     fn to_timespec() -> Timespec {
         let mut sec = 0i64;
         if self.tm_gmtoff == 0_i32 {
-            rustrt::rust_timegm(self, sec);
+            rustrt::rust_timegm(self, &mut sec);
         } else {
-            rustrt::rust_mktime(self, sec);
+            rustrt::rust_mktime(self, &mut sec);
         }
         { sec: sec, nsec: self.tm_nsec }
     }
diff --git a/src/libstd/timer.rs b/src/libstd/timer.rs
index 2aca87b942ec..c9c28c4e1f08 100644
--- a/src/libstd/timer.rs
+++ b/src/libstd/timer.rs
@@ -1,6 +1,6 @@
 //! Utilities that leverage libuv's `uv_timer_*` API
 
-// tjc: forbid deprecated modes again after snap
+#[forbid(deprecated_mode)];
 
 use uv = uv;
 use uv::iotask;
@@ -27,7 +27,7 @@ pub fn delayed_send(iotask: IoTask,
                                   msecs: uint, ch: comm::Chan, val: T) {
         unsafe {
             let timer_done_po = core::comm::Port::<()>();
-            let timer_done_ch = core::comm::Chan(timer_done_po);
+            let timer_done_ch = core::comm::Chan(&timer_done_po);
             let timer_done_ch_ptr = ptr::addr_of(&timer_done_ch);
             let timer = uv::ll::timer_t();
             let timer_ptr = ptr::addr_of(&timer);
@@ -74,7 +74,7 @@ pub fn delayed_send(iotask: IoTask,
  */
 pub fn sleep(iotask: IoTask, msecs: uint) {
     let exit_po = core::comm::Port::<()>();
-    let exit_ch = core::comm::Chan(exit_po);
+    let exit_ch = core::comm::Chan(&exit_po);
     delayed_send(iotask, msecs, exit_ch, ());
     core::comm::recv(exit_po);
 }
@@ -103,7 +103,7 @@ pub fn recv_timeout(iotask: IoTask,
                               msecs: uint,
                               wait_po: comm::Port) -> Option {
     let timeout_po = comm::Port::<()>();
-    let timeout_ch = comm::Chan(timeout_po);
+    let timeout_ch = comm::Chan(&timeout_po);
     delayed_send(iotask, msecs, timeout_ch, ());
     // FIXME: This could be written clearer (#2618)
     either::either(
@@ -162,7 +162,7 @@ mod test {
     #[test]
     fn test_gl_timer_sleep_stress2() {
         let po = core::comm::Port();
-        let ch = core::comm::Chan(po);
+        let ch = core::comm::Chan(&po);
         let hl_loop = uv::global_loop::get();
 
         let repeat = 20u;
@@ -240,7 +240,7 @@ mod test {
         for iter::repeat(times as uint) {
             let expected = rand::Rng().gen_str(16u);
             let test_po = core::comm::Port::<~str>();
-            let test_ch = core::comm::Chan(test_po);
+            let test_ch = core::comm::Chan(&test_po);
 
             do task::spawn() {
                 delayed_send(hl_loop, 50u, test_ch, expected);
diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs
index 184dfd362796..8ab0dc7f2e7d 100644
--- a/src/libstd/treemap.rs
+++ b/src/libstd/treemap.rs
@@ -5,7 +5,7 @@
  * very naive algorithm, but it will probably be updated to be a
  * red-black tree or something else.
  */
-#[warn(deprecated_mode)];
+#[forbid(deprecated_mode)];
 
 use core::cmp::{Eq, Ord};
 use core::option::{Some, None};
@@ -26,7 +26,7 @@ enum TreeNode = {
 pub fn TreeMap() -> TreeMap { @mut None }
 
 /// Insert a value into the map
-pub fn insert(m: &mut TreeEdge, +k: K, +v: V) {
+pub fn insert(m: &mut TreeEdge, k: K, v: V) {
     match copy *m {
       None => {
         *m = Some(@TreeNode({key: k,
@@ -48,7 +48,7 @@ pub fn insert(m: &mut TreeEdge, +k: K, +v: V) {
 }
 
 /// Find a value based on the key
-pub fn find(m: &const TreeEdge, +k: K)
+pub fn find(m: &const TreeEdge, k: K)
                               -> Option {
     match copy *m {
       None => None,
@@ -121,7 +121,7 @@ mod tests {
         insert(m, 1, ());
 
         let n = @mut 0;
-        fn t(n: @mut int, +k: int, +_v: ()) {
+        fn t(n: @mut int, k: int, _v: ()) {
             assert (*n == k); *n += 1;
         }
         traverse(m, |x,y| t(n, *x, *y));
diff --git a/src/libstd/uv_global_loop.rs b/src/libstd/uv_global_loop.rs
index 869c3efa38f9..79f6bafb4a48 100644
--- a/src/libstd/uv_global_loop.rs
+++ b/src/libstd/uv_global_loop.rs
@@ -133,12 +133,12 @@ mod test {
 
     fn impl_uv_hl_simple_timer(iotask: IoTask) unsafe {
         let exit_po = core::comm::Port::();
-        let exit_ch = core::comm::Chan(exit_po);
-        let exit_ch_ptr = ptr::p2::addr_of(&exit_ch);
+        let exit_ch = core::comm::Chan(&exit_po);
+        let exit_ch_ptr = ptr::addr_of(&exit_ch);
         log(debug, fmt!("EXIT_CH_PTR newly created exit_ch_ptr: %?",
                        exit_ch_ptr));
         let timer_handle = ll::timer_t();
-        let timer_ptr = ptr::p2::addr_of(&timer_handle);
+        let timer_ptr = ptr::addr_of(&timer_handle);
         do iotask::interact(iotask) |loop_ptr| unsafe {
             log(debug, ~"user code inside interact loop!!!");
             let init_status = ll::timer_init(loop_ptr, timer_ptr);
@@ -166,7 +166,7 @@ mod test {
     fn test_gl_uv_global_loop_high_level_global_timer() unsafe {
         let hl_loop = get_gl();
         let exit_po = comm::Port::<()>();
-        let exit_ch = comm::Chan(exit_po);
+        let exit_ch = comm::Chan(&exit_po);
         task::spawn_sched(task::ManualThreads(1u), || {
             impl_uv_hl_simple_timer(hl_loop);
             core::comm::send(exit_ch, ());
@@ -182,7 +182,7 @@ mod test {
     fn test_stress_gl_uv_global_loop_high_level_global_timer() unsafe {
         let hl_loop = get_gl();
         let exit_po = core::comm::Port::<()>();
-        let exit_ch = core::comm::Chan(exit_po);
+        let exit_ch = core::comm::Chan(&exit_po);
         let cycles = 5000u;
         for iter::repeat(cycles) {
             task::spawn_sched(task::ManualThreads(1u), || {
diff --git a/src/libstd/uv_iotask.rs b/src/libstd/uv_iotask.rs
index 4a4a34704be2..ad40d96e4f77 100644
--- a/src/libstd/uv_iotask.rs
+++ b/src/libstd/uv_iotask.rs
@@ -4,11 +4,10 @@
  * The I/O task runs in its own single-threaded scheduler.  By using the
  * `interact` function you can execute code in a uv callback.
  */
-
-// tjc: forbid deprecated modes again after a snapshot
+#[forbid(deprecated_mode)];
 
 use libc::c_void;
-use ptr::p2::addr_of;
+use ptr::addr_of;
 use comm = core::comm;
 use comm::{Port, Chan, listen};
 use task::TaskBuilder;
@@ -60,7 +59,7 @@ pub fn spawn_iotask(task: task::TaskBuilder) -> IoTask {
  * via ports/chans.
  */
 pub unsafe fn interact(iotask: IoTask,
-                   +cb: fn~(*c_void)) {
+                   cb: fn~(*c_void)) {
     send_msg(iotask, Interaction(move cb));
 }
 
@@ -125,7 +124,7 @@ type IoTaskLoopData = {
 };
 
 fn send_msg(iotask: IoTask,
-            +msg: IoTaskMsg) unsafe {
+            msg: IoTaskMsg) unsafe {
     iotask.op_chan.send(move msg);
     ll::async_send(iotask.async_handle);
 }
@@ -184,7 +183,7 @@ mod test {
         let async_handle = ll::async_t();
         let ah_ptr = ptr::addr_of(&async_handle);
         let exit_po = core::comm::Port::<()>();
-        let exit_ch = core::comm::Chan(exit_po);
+        let exit_ch = core::comm::Chan(&exit_po);
         let ah_data = {
             iotask: iotask,
             exit_ch: exit_ch
@@ -202,7 +201,7 @@ mod test {
     // high_level_loop
     unsafe fn spawn_test_loop(exit_ch: comm::Chan<()>) -> IoTask {
         let iotask_port = comm::Port::();
-        let iotask_ch = comm::Chan(iotask_port);
+        let iotask_ch = comm::Chan(&iotask_port);
         do task::spawn_sched(task::ManualThreads(1u)) {
             run_loop(iotask_ch);
             exit_ch.send(());
@@ -223,7 +222,7 @@ mod test {
     #[test]
     fn test_uv_iotask_async() unsafe {
         let exit_po = core::comm::Port::<()>();
-        let exit_ch = core::comm::Chan(exit_po);
+        let exit_ch = core::comm::Chan(&exit_po);
         let iotask = spawn_test_loop(exit_ch);
 
         // using this handle to manage the lifetime of the high_level_loop,
@@ -233,7 +232,7 @@ mod test {
         // lives until, at least, all of the impl_uv_hl_async() runs have been
         // called, at least.
         let work_exit_po = core::comm::Port::<()>();
-        let work_exit_ch = core::comm::Chan(work_exit_po);
+        let work_exit_ch = core::comm::Chan(&work_exit_po);
         for iter::repeat(7u) {
             do task::spawn_sched(task::ManualThreads(1u)) {
                 impl_uv_iotask_async(iotask);
diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs
index f0594475d04e..f8c3882d15eb 100644
--- a/src/libstd/uv_ll.rs
+++ b/src/libstd/uv_ll.rs
@@ -1466,12 +1466,12 @@ pub mod test {
         let kill_server_msg = ~"does a dog have buddha nature?";
         let server_resp_msg = ~"mu!";
         let client_port = core::comm::Port::<~str>();
-        let client_chan = core::comm::Chan::<~str>(client_port);
+        let client_chan = core::comm::Chan::<~str>(&client_port);
         let server_port = core::comm::Port::<~str>();
-        let server_chan = core::comm::Chan::<~str>(server_port);
+        let server_chan = core::comm::Chan::<~str>(&server_port);
 
         let continue_port = core::comm::Port::();
-        let continue_chan = core::comm::Chan::(continue_port);
+        let continue_chan = core::comm::Chan::(&continue_port);
         let continue_chan_ptr = ptr::addr_of(&continue_chan);
 
         do task::spawn_sched(task::ManualThreads(1)) {
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index e17b52fb27d1..a50189cf5989 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -574,7 +574,7 @@ impl inferable : cmp::Eq {
 
 // "resolved" mode: the real modes.
 #[auto_serialize]
-enum rmode { by_ref, by_val, by_mutbl_ref, by_move, by_copy }
+enum rmode { by_ref, by_val, by_move, by_copy }
 
 impl rmode : to_bytes::IterBytes {
     pure fn iter_bytes(+lsb0: bool, f: to_bytes::Cb) {
diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs
index bfe0f4dd0e64..4da9992b0dd3 100644
--- a/src/libsyntax/ext/pipes/ast_builder.rs
+++ b/src/libsyntax/ext/pipes/ast_builder.rs
@@ -48,7 +48,6 @@ trait ext_ctxt_ast_builder {
     fn ty_param(id: ast::ident, +bounds: ~[ast::ty_param_bound])
         -> ast::ty_param;
     fn arg(name: ident, ty: @ast::ty) -> ast::arg;
-    fn arg_mode(name: ident, ty: @ast::ty, mode: ast::rmode) -> ast::arg;
     fn expr_block(e: @ast::expr) -> ast::blk;
     fn fn_decl(+inputs: ~[ast::arg], output: @ast::ty) -> ast::fn_decl;
     fn item(name: ident, span: span, +node: ast::item_) -> @ast::item;
@@ -177,13 +176,6 @@ impl ext_ctxt: ext_ctxt_ast_builder {
          id: self.next_id()}
     }
 
-    fn arg_mode(name: ident, ty: @ast::ty, mode: ast::rmode) -> ast::arg {
-        {mode: ast::expl(mode),
-         ty: ty,
-         ident: name,
-         id: self.next_id()}
-    }
-
     fn block(+stmts: ~[@ast::stmt], e: @ast::expr) -> ast::blk {
         let blk = {view_items: ~[],
                    stmts: stmts,
diff --git a/src/libsyntax/ext/pipes/pipec.rs b/src/libsyntax/ext/pipes/pipec.rs
index 9c10d228a23f..874ea01e9b01 100644
--- a/src/libsyntax/ext/pipes/pipec.rs
+++ b/src/libsyntax/ext/pipes/pipec.rs
@@ -47,16 +47,15 @@ impl message: gen_send {
             let arg_names = tys.mapi(|i, _ty| cx.ident_of(~"x_"+i.to_str()));
 
             let args_ast = (arg_names, tys).map(
-                |n, t| cx.arg_mode(*n, *t, ast::by_copy)
+                |n, t| cx.arg(*n, *t)
             );
 
             let pipe_ty = cx.ty_path_ast_builder(
                 path(~[this.data_name()], span)
                 .add_tys(cx.ty_vars(this.ty_params)));
             let args_ast = vec::append(
-                ~[cx.arg_mode(cx.ident_of(~"pipe"),
-                              pipe_ty,
-                              ast::by_copy)],
+                ~[cx.arg(cx.ident_of(~"pipe"),
+                              pipe_ty)],
                 args_ast);
 
             let mut body = ~"{\n";
@@ -129,15 +128,14 @@ impl message: gen_send {
                 let arg_names = tys.mapi(|i, _ty| (~"x_" + i.to_str()));
 
                 let args_ast = (arg_names, tys).map(
-                    |n, t| cx.arg_mode(cx.ident_of(*n), *t, ast::by_copy)
+                    |n, t| cx.arg(cx.ident_of(*n), *t)
                 );
 
                 let args_ast = vec::append(
-                    ~[cx.arg_mode(cx.ident_of(~"pipe"),
+                    ~[cx.arg(cx.ident_of(~"pipe"),
                                   cx.ty_path_ast_builder(
                                       path(~[this.data_name()], span)
-                                      .add_tys(cx.ty_vars(this.ty_params))),
-                                  ast::by_copy)],
+                                      .add_tys(cx.ty_vars(this.ty_params))))],
                     args_ast);
 
                 let message_args = if arg_names.len() == 0 {
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs
index cb8416501b37..4f265e1919c2 100644
--- a/src/libsyntax/parse/comments.rs
+++ b/src/libsyntax/parse/comments.rs
@@ -127,14 +127,14 @@ fn consume_non_eol_whitespace(rdr: string_reader) {
     }
 }
 
-fn push_blank_line_comment(rdr: string_reader, &comments: ~[cmnt]) {
+fn push_blank_line_comment(rdr: string_reader, comments: &mut ~[cmnt]) {
     debug!(">>> blank-line comment");
     let v: ~[~str] = ~[];
     comments.push({style: blank_line, lines: v, pos: rdr.chpos});
 }
 
 fn consume_whitespace_counting_blank_lines(rdr: string_reader,
-                                           &comments: ~[cmnt]) {
+                                           comments: &mut ~[cmnt]) {
     while is_whitespace(rdr.curr) && !is_eof(rdr) {
         if rdr.col == 0u && rdr.curr == '\n' {
             push_blank_line_comment(rdr, comments);
@@ -145,7 +145,7 @@ fn consume_whitespace_counting_blank_lines(rdr: string_reader,
 
 
 fn read_shebang_comment(rdr: string_reader, code_to_the_left: bool,
-                                                        &comments: ~[cmnt]) {
+                                            comments: &mut ~[cmnt]) {
     debug!(">>> shebang comment");
     let p = rdr.chpos;
     debug!("<<< shebang comment");
@@ -157,7 +157,7 @@ fn read_shebang_comment(rdr: string_reader, code_to_the_left: bool,
 }
 
 fn read_line_comments(rdr: string_reader, code_to_the_left: bool,
-                                                        &comments: ~[cmnt]) {
+                                          comments: &mut ~[cmnt]) {
     debug!(">>> line comments");
     let p = rdr.chpos;
     let mut lines: ~[~str] = ~[];
@@ -188,8 +188,8 @@ fn all_whitespace(s: ~str, begin: uint, end: uint) -> bool {
     return true;
 }
 
-fn trim_whitespace_prefix_and_push_line(&lines: ~[~str],
-                                        s: ~str, col: uint) unsafe {
+fn trim_whitespace_prefix_and_push_line(lines: &mut ~[~str],
+                                        s: ~str, col: uint) {
     let mut s1;
     let len = str::len(s);
     if all_whitespace(s, 0u, uint::min(len, col)) {
@@ -202,7 +202,7 @@ fn trim_whitespace_prefix_and_push_line(&lines: ~[~str],
 }
 
 fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
-                                                        &comments: ~[cmnt]) {
+                                          comments: &mut ~[cmnt]) {
     debug!(">>> block comment");
     let p = rdr.chpos;
     let mut lines: ~[~str] = ~[];
@@ -228,7 +228,7 @@ fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
         debug!("=== block comment level %d", level);
         if is_eof(rdr) {(rdr as reader).fatal(~"unterminated block comment");}
         if rdr.curr == '\n' {
-            trim_whitespace_prefix_and_push_line(lines, curr_line, col);
+            trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
             curr_line = ~"";
             bump(rdr);
         } else {
@@ -248,8 +248,8 @@ fn read_block_comment(rdr: string_reader, code_to_the_left: bool,
             }
         }
     }
-    if str::len(curr_line) != 0u {
-        trim_whitespace_prefix_and_push_line(lines, curr_line, col);
+    if str::len(curr_line) != 0 {
+        trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
     }
     let mut style = if code_to_the_left { trailing } else { isolated };
     consume_non_eol_whitespace(rdr);
@@ -267,7 +267,7 @@ fn peeking_at_comment(rdr: string_reader) -> bool {
 }
 
 fn consume_comment(rdr: string_reader, code_to_the_left: bool,
-                   &comments: ~[cmnt]) {
+                   comments: &mut ~[cmnt]) {
     debug!(">>> consume comment");
     if rdr.curr == '/' && nextch(rdr) == '/' {
         read_line_comments(rdr, code_to_the_left, comments);
@@ -299,11 +299,11 @@ fn gather_comments_and_literals(span_diagnostic: diagnostic::span_handler,
             consume_non_eol_whitespace(rdr);
             if rdr.curr == '\n' {
                 code_to_the_left = false;
-                consume_whitespace_counting_blank_lines(rdr, comments);
+                consume_whitespace_counting_blank_lines(rdr, &mut comments);
             }
             while peeking_at_comment(rdr) {
-                consume_comment(rdr, code_to_the_left, comments);
-                consume_whitespace_counting_blank_lines(rdr, comments);
+                consume_comment(rdr, code_to_the_left, &mut comments);
+                consume_whitespace_counting_blank_lines(rdr, &mut comments);
             }
             break;
         }
diff --git a/src/libsyntax/parse/eval.rs b/src/libsyntax/parse/eval.rs
index 14dc490346eb..c91060284910 100644
--- a/src/libsyntax/parse/eval.rs
+++ b/src/libsyntax/parse/eval.rs
@@ -10,8 +10,8 @@ type ctx =
 fn eval_crate_directives(cx: ctx,
                          cdirs: ~[@ast::crate_directive],
                          prefix: &Path,
-                         &view_items: ~[@ast::view_item],
-                         &items: ~[@ast::item]) {
+                         view_items: &mut~[@ast::view_item],
+                         items: &mut~[@ast::item]) {
     for cdirs.each |sub_cdir| {
         eval_crate_directive(cx, *sub_cdir, prefix, view_items, items);
     }
@@ -24,7 +24,7 @@ fn eval_crate_directives_to_mod(cx: ctx, cdirs: ~[@ast::crate_directive],
         = parse_companion_mod(cx, prefix, suffix);
     let mut view_items: ~[@ast::view_item] = ~[];
     let mut items: ~[@ast::item] = ~[];
-    eval_crate_directives(cx, cdirs, prefix, view_items, items);
+    eval_crate_directives(cx, cdirs, prefix, &mut view_items, &mut items);
     return ({view_items: vec::append(view_items, cview_items),
           items: vec::append(items, citems)},
          cattrs);
@@ -82,8 +82,8 @@ fn cdir_path_opt(default: ~str, attrs: ~[ast::attribute]) -> ~str {
 }
 
 fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &Path,
-                        &view_items: ~[@ast::view_item],
-                        &items: ~[@ast::item]) {
+                        view_items: &mut ~[@ast::view_item],
+                        items: &mut ~[@ast::item]) {
     match cdir.node {
       ast::cdir_src_mod(vis, id, attrs) => {
         let file_path = Path(cdir_path_opt(
diff --git a/src/libsyntax/parse/obsolete.rs b/src/libsyntax/parse/obsolete.rs
index 782535f5c2b2..828d498ca3c2 100644
--- a/src/libsyntax/parse/obsolete.rs
+++ b/src/libsyntax/parse/obsolete.rs
@@ -22,7 +22,8 @@ pub enum ObsoleteSyntax {
     ObsoleteClassMethod,
     ObsoleteClassTraits,
     ObsoletePrivSection,
-    ObsoleteModeInFnType
+    ObsoleteModeInFnType,
+    ObsoleteByMutRefMode
 }
 
 impl ObsoleteSyntax : cmp::Eq {
@@ -94,6 +95,10 @@ impl parser : ObsoleteReporter {
                 "to use a (deprecated) mode in a fn type, you should \
                  give the argument an explicit name (like `&&v: int`)"
             ),
+            ObsoleteByMutRefMode => (
+                "by-mutable-reference mode",
+                "Declare an argument of type &mut T instead"
+            ),
         };
 
         self.report(sp, kind, kind_str, desc);
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8860d1b5cea8..22c25186c918 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -20,13 +20,13 @@ use obsolete::{
     ObsoleteLowerCaseKindBounds, ObsoleteLet,
     ObsoleteFieldTerminator, ObsoleteStructCtor,
     ObsoleteWith, ObsoleteClassMethod, ObsoleteClassTraits,
-    ObsoleteModeInFnType
+    ObsoleteModeInFnType, ObsoleteByMutRefMode
 };
 use ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute,
              bind_by_ref, bind_by_implicit_ref, bind_by_value, bind_by_move,
              bitand, bitor, bitxor, blk, blk_check_mode, bound_const,
              bound_copy, bound_send, bound_trait, bound_owned, box, by_copy,
-             by_move, by_mutbl_ref, by_ref, by_val, capture_clause,
+             by_move, by_ref, by_val, capture_clause,
              capture_item, cdir_dir_mod, cdir_src_mod, cdir_view_item,
              class_immutable, class_mutable,
              crate, crate_cfg, crate_directive, decl, decl_item, decl_local,
@@ -570,7 +570,10 @@ impl parser {
 
     fn parse_arg_mode() -> mode {
         if self.eat(token::BINOP(token::AND)) {
-            expl(by_mutbl_ref)
+            self.obsolete(copy self.span,
+                          ObsoleteByMutRefMode);
+            // Bogus mode, but doesn't matter since it's an error
+            expl(by_ref)
         } else if self.eat(token::BINOP(token::MINUS)) {
             expl(by_move)
         } else if self.eat(token::ANDAND) {
@@ -1275,7 +1278,8 @@ impl parser {
 
         return match self.token {
           token::LPAREN | token::LBRACE | token::LBRACKET => {
-            let ket = token::flip_delimiter(self.token);
+              // tjc: ??????
+            let ket = token::flip_delimiter(copy self.token);
             tt_delim(vec::append(
                 ~[parse_tt_tok(self, true)],
                 vec::append(
@@ -1296,7 +1300,8 @@ impl parser {
         return match self.token {
           token::LBRACE | token::LPAREN | token::LBRACKET => {
             self.parse_matcher_subseq(name_idx, copy self.token,
-                                      token::flip_delimiter(self.token))
+                                      // tjc: not sure why we need a copy
+                                      token::flip_delimiter(copy self.token))
           }
           _ => self.fatal(~"expected open delimiter")
         }
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index a328ff1bdf64..99b789cf63fc 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -230,7 +230,7 @@ pure fn can_begin_expr(t: token) -> bool {
 }
 
 /// what's the opposite delimiter?
-fn flip_delimiter(&t: token::token) -> token::token {
+fn flip_delimiter(t: token::token) -> token::token {
     match t {
       token::LPAREN => token::RPAREN,
       token::LBRACE => token::RBRACE,
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index d08b20eed843..bff356e5cb72 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1688,7 +1688,6 @@ fn print_fn_block_args(s: ps, decl: ast::fn_decl,
 
 fn mode_to_str(m: ast::mode) -> ~str {
     match m {
-      ast::expl(ast::by_mutbl_ref) => ~"&",
       ast::expl(ast::by_move) => ~"-",
       ast::expl(ast::by_ref) => ~"&&",
       ast::expl(ast::by_val) => ~"++",
diff --git a/src/llvm b/src/llvm
index c51053bf71de..dc4cdbf05228 160000
--- a/src/llvm
+++ b/src/llvm
@@ -1 +1 @@
-Subproject commit c51053bf71de475df6a91204acd9ad78f4747c38
+Subproject commit dc4cdbf052288794ac418f310e7f5cfa609f5902
diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp
index 11e65347f11b..805ec37bfeae 100644
--- a/src/rt/rust.cpp
+++ b/src/rt/rust.cpp
@@ -67,11 +67,6 @@ command_line_args : public kernel_owned
     }
 };
 
-// A global that indicates whether Rust typestate claim statements should be
-// executed Generated code will read this variable directly (I think).
-// FIXME (#2670): This belongs somewhere else
-int check_claims = 0;
-
 void* global_crate_map = NULL;
 
 /**
@@ -94,9 +89,6 @@ rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) {
 
     update_log_settings(crate_map, env->logspec);
 
-    // Maybe turn on typestate claim checking
-    check_claims = env->check_claims;
-
     rust_kernel *kernel = new rust_kernel(env);
 
     // Create the main scheduler and the main task
diff --git a/src/rt/rust_env.cpp b/src/rt/rust_env.cpp
index 4e653c8f9e63..268aca965d70 100644
--- a/src/rt/rust_env.cpp
+++ b/src/rt/rust_env.cpp
@@ -10,7 +10,6 @@
 #define RUST_MIN_STACK "RUST_MIN_STACK"
 #define RUST_MAX_STACK "RUST_MAX_STACK"
 #define RUST_LOG "RUST_LOG"
-#define CHECK_CLAIMS "CHECK_CLAIMS"
 #define DETAILED_LEAKS "DETAILED_LEAKS"
 #define RUST_SEED "RUST_SEED"
 #define RUST_POISON_ON_FREE "RUST_POISON_ON_FREE"
@@ -114,7 +113,6 @@ load_env(int argc, char **argv) {
     env->min_stack_size = get_min_stk_size();
     env->max_stack_size = get_max_stk_size();
     env->logspec = copyenv(RUST_LOG);
-    env->check_claims = getenv(CHECK_CLAIMS) != NULL;
     env->detailed_leaks = getenv(DETAILED_LEAKS) != NULL;
     env->rust_seed = copyenv(RUST_SEED);
     env->poison_on_free = getenv(RUST_POISON_ON_FREE) != NULL;
diff --git a/src/rt/rust_env.h b/src/rt/rust_env.h
index 0e3af9eae60c..8a0ff4d1df18 100644
--- a/src/rt/rust_env.h
+++ b/src/rt/rust_env.h
@@ -9,7 +9,6 @@ struct rust_env {
     size_t min_stack_size;
     size_t max_stack_size;
     char* logspec;
-    bool check_claims;
     bool detailed_leaks;
     char* rust_seed;
     bool poison_on_free;
diff --git a/src/rt/rust_globals.h b/src/rt/rust_globals.h
index 84c5eca0afb6..ec60af87b6b2 100644
--- a/src/rt/rust_globals.h
+++ b/src/rt/rust_globals.h
@@ -69,10 +69,6 @@ extern "C" {
 #define FASTCALL
 #endif
 
-/* Controls whether claims are turned into checks */
-/* Variable name must be kept consistent with trans.rs */
-extern "C" int check_claims;
-
 #define CHECKED(call)                                               \
     {                                                               \
     int res = (call);                                               \
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index 7412f06d8cd8..890aa352c927 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -1,4 +1,3 @@
-check_claims
 debug_box
 debug_fn
 debug_opaque
diff --git a/src/rustc/driver/rustc.rs b/src/rustc/driver/rustc.rs
index c6b93fc0603a..c60904419d5f 100644
--- a/src/rustc/driver/rustc.rs
+++ b/src/rustc/driver/rustc.rs
@@ -22,15 +22,15 @@ use syntax::diagnostic;
 use rustc::driver::session;
 use rustc::middle::lint;
 
-fn version(argv0: ~str) {
+fn version(argv0: &str) {
     let mut vers = ~"unknown version";
     let env_vers = env!("CFG_VERSION");
-    if str::len(env_vers) != 0u { vers = env_vers; }
+    if env_vers.len() != 0 { vers = env_vers; }
     io::println(fmt!("%s %s", argv0, vers));
     io::println(fmt!("host: %s", host_triple()));
 }
 
-fn usage(argv0: ~str) {
+fn usage(argv0: &str) {
     io::println(fmt!("Usage: %s [options] \n", argv0) +
                  ~"
 Options:
@@ -86,7 +86,7 @@ fn describe_warnings() {
     let lint_dict = lint::get_lint_dict();
     let mut max_key = 0;
     for lint_dict.each_key |k| { max_key = uint::max(k.len(), max_key); }
-    fn padded(max: uint, s: ~str) -> ~str {
+    fn padded(max: uint, s: &str) -> ~str {
         str::from_bytes(vec::from_elem(max - s.len(), ' ' as u8)) + s
     }
     io::println(fmt!("\nAvailable lint checks:\n"));
@@ -117,14 +117,14 @@ fn describe_debug_flags() {
     }
 }
 
-fn run_compiler(args: ~[~str], demitter: diagnostic::emitter) {
+fn run_compiler(args: &~[~str], demitter: diagnostic::emitter) {
     // Don't display log spew by default. Can override with RUST_LOG.
     logging::console_off();
 
-    let mut args = args;
+    let mut args = *args;
     let binary = args.shift();
 
-    if vec::len(args) == 0u { usage(binary); return; }
+    if args.is_empty() { usage(binary); return; }
 
     let matches =
         match getopts::getopts(args, opts()) {
@@ -229,7 +229,7 @@ bug and need to present an error.
 */
 fn monitor(+f: fn~(diagnostic::emitter)) {
     let p = comm::Port();
-    let ch = comm::Chan(p);
+    let ch = comm::Chan(&p);
 
     match do task::try |move f| {
 
@@ -277,9 +277,10 @@ fn monitor(+f: fn~(diagnostic::emitter)) {
     }
 }
 
-fn main(args: ~[~str]) {
-    do monitor |demitter| {
-        run_compiler(args, demitter);
+fn main() {
+    let mut args = os::args();
+    do monitor |move args, demitter| {
+        run_compiler(&args, demitter);
     }
 }
 
diff --git a/src/rustc/front/test.rs b/src/rustc/front/test.rs
index 952d7b9ab793..1a6cc6dd895e 100644
--- a/src/rustc/front/test.rs
+++ b/src/rustc/front/test.rs
@@ -415,34 +415,12 @@ fn mk_test_wrapper(cx: test_ctxt,
 }
 
 fn mk_main(cx: test_ctxt) -> @ast::item {
-    let str_pt = path_node(~[cx.sess.ident_of(~"str")]);
-    let str_ty_inner = @{id: cx.sess.next_node_id(),
-                         node: ast::ty_path(str_pt, cx.sess.next_node_id()),
-                         span: dummy_sp()};
-    let str_ty = @{id: cx.sess.next_node_id(),
-                   node: ast::ty_uniq({ty: str_ty_inner, mutbl: ast::m_imm}),
-                   span: dummy_sp()};
-    let args_mt = {ty: str_ty, mutbl: ast::m_imm};
-    let args_ty_inner = @{id: cx.sess.next_node_id(),
-                          node: ast::ty_vec(args_mt),
-                          span: dummy_sp()};
-    let args_ty = {id: cx.sess.next_node_id(),
-                   node: ast::ty_uniq({ty: args_ty_inner, mutbl: ast::m_imm}),
-                   span: dummy_sp()};
-
-
-    let args_arg: ast::arg =
-        {mode: ast::expl(ast::by_val),
-         ty: @args_ty,
-         ident: cx.sess.ident_of(~"args"),
-         id: cx.sess.next_node_id()};
-
     let ret_ty = {id: cx.sess.next_node_id(),
                   node: ast::ty_nil,
                   span: dummy_sp()};
 
     let decl: ast::fn_decl =
-        {inputs: ~[args_arg],
+        {inputs: ~[],
          output: @ret_ty,
          cf: ast::return_val};
 
@@ -465,9 +443,11 @@ fn mk_main(cx: test_ctxt) -> @ast::item {
 }
 
 fn mk_test_main_call(cx: test_ctxt) -> @ast::expr {
-
-    // Get the args passed to main so we can pass the to test_main
-    let args_path = path_node(~[cx.sess.ident_of(~"args")]);
+    // Call os::args to generate the vector of test_descs
+    let args_path = path_node(~[
+        cx.sess.ident_of(~"os"),
+        cx.sess.ident_of(~"args")
+    ]);
 
     let args_path_expr_: ast::expr_ = ast::expr_path(args_path);
 
@@ -475,6 +455,12 @@ fn mk_test_main_call(cx: test_ctxt) -> @ast::expr {
         {id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(),
          node: args_path_expr_, span: dummy_sp()};
 
+    let args_call_expr_ = ast::expr_call(@args_path_expr, ~[], false);
+
+    let args_call_expr: ast::expr =
+        {id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(),
+         node: args_call_expr_, span: dummy_sp()};
+
     // Call __test::test to generate the vector of test_descs
     let test_path = path_node(~[cx.sess.ident_of(~"tests")]);
 
@@ -503,7 +489,7 @@ fn mk_test_main_call(cx: test_ctxt) -> @ast::expr {
 
     let test_main_call_expr_: ast::expr_ =
         ast::expr_call(@test_main_path_expr,
-                       ~[@args_path_expr, @test_call_expr], false);
+                       ~[@args_call_expr, @test_call_expr], false);
 
     let test_main_call_expr: ast::expr =
         {id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(),
diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs
index 17d686b41d1a..a65c25a46eff 100644
--- a/src/rustc/metadata/encoder.rs
+++ b/src/rustc/metadata/encoder.rs
@@ -34,6 +34,7 @@ export metadata_encoding_version;
 export def_to_str;
 export encode_ctxt;
 export write_type;
+export write_vstore;
 export encode_def_id;
 
 type abbrev_map = map::HashMap;
@@ -116,7 +117,7 @@ fn encode_mutability(ebml_w: ebml::Writer, mt: class_mutability) {
 type entry = {val: T, pos: uint};
 
 fn add_to_index(ecx: @encode_ctxt, ebml_w: ebml::Writer, path: &[ident],
-                &index: ~[entry<~str>], name: ident) {
+                index: &mut ~[entry<~str>], name: ident) {
     let mut full_path = ~[];
     full_path.push_all(path);
     full_path.push(name);
@@ -180,6 +181,16 @@ fn write_type(ecx: @encode_ctxt, ebml_w: ebml::Writer, typ: ty::t) {
     tyencode::enc_ty(ebml_w.writer, ty_str_ctxt, typ);
 }
 
+fn write_vstore(ecx: @encode_ctxt, ebml_w: ebml::Writer, vstore: ty::vstore) {
+    let ty_str_ctxt =
+        @{diag: ecx.diag,
+          ds: def_to_str,
+          tcx: ecx.tcx,
+          reachable: |a| reachable(ecx, a),
+          abbrevs: tyencode::ac_use_abbrevs(ecx.type_abbrevs)};
+    tyencode::enc_vstore(ebml_w.writer, ty_str_ctxt, vstore);
+}
+
 fn encode_type(ecx: @encode_ctxt, ebml_w: ebml::Writer, typ: ty::t) {
     ebml_w.start_tag(tag_items_data_item_type);
     write_type(ecx, ebml_w, typ);
diff --git a/src/rustc/metadata/tydecode.rs b/src/rustc/metadata/tydecode.rs
index f3fa0e3f3507..1375ff2d0be0 100644
--- a/src/rustc/metadata/tydecode.rs
+++ b/src/rustc/metadata/tydecode.rs
@@ -394,7 +394,6 @@ fn parse_arg(st: @pstate, conv: conv_did) -> ty::arg {
 
 fn parse_mode(st: @pstate) -> ast::mode {
     let m = ast::expl(match next(st) {
-        '&' => ast::by_mutbl_ref,
         '-' => ast::by_move,
         '+' => ast::by_copy,
         '=' => ast::by_ref,
diff --git a/src/rustc/metadata/tyencode.rs b/src/rustc/metadata/tyencode.rs
index 88d83ca23f4c..69689b16e154 100644
--- a/src/rustc/metadata/tyencode.rs
+++ b/src/rustc/metadata/tyencode.rs
@@ -16,6 +16,7 @@ export enc_ty;
 export enc_bounds;
 export enc_mode;
 export enc_arg;
+export enc_vstore;
 
 type ctxt = {
     diag: span_handler,
@@ -332,7 +333,6 @@ fn enc_arg(w: io::Writer, cx: @ctxt, arg: ty::arg) {
 
 fn enc_mode(w: io::Writer, cx: @ctxt, m: mode) {
     match ty::resolved_mode(cx.tcx, m) {
-      by_mutbl_ref => w.write_char('&'),
       by_move => w.write_char('-'),
       by_copy => w.write_char('+'),
       by_ref => w.write_char('='),
diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs
index 29368ae95b80..a364c1d75d43 100644
--- a/src/rustc/middle/astencode.rs
+++ b/src/rustc/middle/astencode.rs
@@ -490,8 +490,11 @@ impl method_origin: tr {
           typeck::method_param(mp) => {
             typeck::method_param({trait_id:mp.trait_id.tr(xcx),.. mp})
           }
-          typeck::method_trait(did, m) => {
-            typeck::method_trait(did.tr(xcx), m)
+          typeck::method_trait(did, m, vstore) => {
+            typeck::method_trait(did.tr(xcx), m, vstore)
+          }
+          typeck::method_self(did, m) => {
+            typeck::method_self(did.tr(xcx), m)
           }
         }
     }
@@ -631,6 +634,7 @@ impl @e::encode_ctxt: get_ty_str_ctxt {
 trait ebml_writer_helpers {
     fn emit_arg(ecx: @e::encode_ctxt, arg: ty::arg);
     fn emit_ty(ecx: @e::encode_ctxt, ty: ty::t);
+    fn emit_vstore(ecx: @e::encode_ctxt, vstore: ty::vstore);
     fn emit_tys(ecx: @e::encode_ctxt, tys: ~[ty::t]);
     fn emit_bounds(ecx: @e::encode_ctxt, bs: ty::param_bounds);
     fn emit_tpbt(ecx: @e::encode_ctxt, tpbt: ty::ty_param_bounds_and_ty);
@@ -643,6 +647,12 @@ impl ebml::Writer: ebml_writer_helpers {
         }
     }
 
+    fn emit_vstore(ecx: @e::encode_ctxt, vstore: ty::vstore) {
+        do self.emit_opaque {
+            e::write_vstore(ecx, self, vstore)
+        }
+    }
+
     fn emit_arg(ecx: @e::encode_ctxt, arg: ty::arg) {
         do self.emit_opaque {
             tyencode::enc_arg(self.writer, ecx.ty_str_ctxt(), arg);
diff --git a/src/rustc/middle/borrowck.rs b/src/rustc/middle/borrowck.rs
index 414890cbd7c6..e2f7ba20642a 100644
--- a/src/rustc/middle/borrowck.rs
+++ b/src/rustc/middle/borrowck.rs
@@ -396,10 +396,10 @@ type req_maps = {
     pure_map: HashMap
 };
 
-fn save_and_restore(&save_and_restore_t: T, f: fn() -> U) -> U {
-    let old_save_and_restore_t = save_and_restore_t;
+fn save_and_restore(save_and_restore_t: &mut T, f: fn() -> U) -> U {
+    let old_save_and_restore_t = *save_and_restore_t;
     let u <- f();
-    save_and_restore_t = old_save_and_restore_t;
+    *save_and_restore_t = old_save_and_restore_t;
     move u
 }
 
diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs
index 0c79c0fcd7f3..cc8d89a8ace7 100644
--- a/src/rustc/middle/borrowck/check_loans.rs
+++ b/src/rustc/middle/borrowck/check_loans.rs
@@ -529,7 +529,7 @@ impl check_loan_ctxt {
                 ast::by_move => {
                     self.check_move_out(*arg);
                 }
-                ast::by_mutbl_ref | ast::by_ref |
+                ast::by_ref |
                 ast::by_copy | ast::by_val => {
                 }
             }
@@ -542,9 +542,9 @@ fn check_loans_in_fn(fk: visit::fn_kind, decl: ast::fn_decl, body: ast::blk,
                      visitor: visit::vt) {
 
     debug!("purity on entry=%?", copy self.declared_purity);
-    do save_and_restore(self.in_ctor) {
-        do save_and_restore(self.declared_purity) {
-            do save_and_restore(self.fn_args) {
+    do save_and_restore(&mut(self.in_ctor)) {
+        do save_and_restore(&mut(self.declared_purity)) {
+            do save_and_restore(&mut(self.fn_args)) {
                 let is_stack_closure = self.is_stack_closure(id);
                 let fty = ty::node_id_to_type(self.tcx(), id);
                 self.declared_purity = ty::determine_inherited_purity(
@@ -667,7 +667,7 @@ fn check_loans_in_expr(expr: @ast::expr,
 fn check_loans_in_block(blk: ast::blk,
                         &&self: check_loan_ctxt,
                         vt: visit::vt) {
-    do save_and_restore(self.declared_purity) {
+    do save_and_restore(&mut(self.declared_purity)) {
         self.check_for_conflicting_loans(blk.node.id);
 
         match blk.node.rules {
diff --git a/src/rustc/middle/borrowck/gather_loans.rs b/src/rustc/middle/borrowck/gather_loans.rs
index 327db51518be..5dfde8c9af64 100644
--- a/src/rustc/middle/borrowck/gather_loans.rs
+++ b/src/rustc/middle/borrowck/gather_loans.rs
@@ -115,10 +115,6 @@ fn req_loans_in_expr(ex: @ast::expr,
         let scope_r = ty::re_scope(ex.id);
         for vec::each2(args, arg_tys) |arg, arg_ty| {
             match ty::resolved_mode(self.tcx(), arg_ty.mode) {
-              ast::by_mutbl_ref => {
-                let arg_cmt = self.bccx.cat_expr(*arg);
-                self.guarantee_valid(arg_cmt, m_mutbl, scope_r);
-              }
               ast::by_ref => {
                 let arg_cmt = self.bccx.cat_expr(*arg);
                 self.guarantee_valid(arg_cmt, m_imm,  scope_r);
diff --git a/src/rustc/middle/kind.rs b/src/rustc/middle/kind.rs
index 9aff382775c8..e2b85441a8fd 100644
--- a/src/rustc/middle/kind.rs
+++ b/src/rustc/middle/kind.rs
@@ -323,7 +323,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt) {
         for ty::ty_fn_args(ty::expr_ty(cx.tcx, f)).each |arg_t| {
             match ty::arg_mode(cx.tcx, *arg_t) {
               by_copy => maybe_copy(cx, args[i], None),
-              by_ref | by_val | by_mutbl_ref | by_move => ()
+              by_ref | by_val | by_move => ()
             }
             i += 1u;
         }
@@ -335,7 +335,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt) {
             Some(ref mme) => {
                 match ty::arg_mode(cx.tcx, mme.self_arg) {
                     by_copy => maybe_copy(cx, lhs, None),
-                    by_ref | by_val | by_mutbl_ref | by_move => ()
+                    by_ref | by_val | by_move => ()
                 }
             }
             _ => ()
@@ -465,14 +465,7 @@ fn check_imm_free_var(cx: ctx, def: def, sp: span) {
             cx.tcx.sess.span_err(sp, msg);
         }
       }
-      def_arg(_, mode) => {
-        match ty::resolved_mode(cx.tcx, mode) {
-          by_ref | by_val | by_move | by_copy => { /* ok */ }
-          by_mutbl_ref => {
-            cx.tcx.sess.span_err(sp, msg);
-          }
-        }
-      }
+      def_arg(*) => { /* ok */ }
       def_upvar(_, def1, _, _) => {
         check_imm_free_var(cx, *def1, sp);
       }
diff --git a/src/rustc/middle/liveness.rs b/src/rustc/middle/liveness.rs
index 69b325b03a4a..12d63cdacbf6 100644
--- a/src/rustc/middle/liveness.rs
+++ b/src/rustc/middle/liveness.rs
@@ -398,7 +398,7 @@ impl IrMaps {
 
             (*v).push(id);
           }
-          Arg(_, _, by_ref) | Arg(_, _, by_mutbl_ref) |
+          Arg(_, _, by_ref) |
           Arg(_, _, by_val) | Self | Field(_) | ImplicitRet |
           Local(LocalInfo {kind: FromMatch(bind_by_implicit_ref), _}) => {
             debug!("--but it is not owned");
@@ -831,9 +831,9 @@ 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,
-                                       self.users[idx].reader);
+                                       &mut self.users[idx].reader);
             changed |= copy_if_invalid(copy self.users[succ_idx].writer,
-                                       self.users[idx].writer);
+                                       &mut self.users[idx].writer);
             if self.users[succ_idx].used && !self.users[idx].used {
                 self.users[idx].used = true;
                 changed = true;
@@ -844,10 +844,10 @@ impl Liveness {
                ln.to_str(), self.ln_str(succ_ln), first_merge, changed);
         return changed;
 
-        fn copy_if_invalid(src: LiveNode, &dst: LiveNode) -> bool {
+        fn copy_if_invalid(src: LiveNode, dst: &mut LiveNode) -> bool {
             if src.is_valid() {
                 if !dst.is_valid() {
-                    dst = src;
+                    *dst = src;
                     return true;
                 }
             }
@@ -919,7 +919,7 @@ impl Liveness {
         // inputs passed by & mode should be considered live on exit:
         for decl.inputs.each |arg| {
             match ty::resolved_mode(self.tcx, arg.mode) {
-              by_mutbl_ref | by_ref | by_val => {
+              by_ref | by_val => {
                 // These are "non-owned" modes, so register a read at
                 // the end.  This will prevent us from moving out of
                 // such variables but also prevent us from registering
@@ -1573,7 +1573,7 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) {
         let targs = ty::ty_fn_args(ty::expr_ty(self.tcx, f));
         for vec::each2(args, targs) |arg_expr, arg_ty| {
             match ty::resolved_mode(self.tcx, arg_ty.mode) {
-                by_val | by_copy | by_ref | by_mutbl_ref => {}
+                by_val | by_copy | by_ref => {}
                 by_move => {
                     self.check_move_from_expr(*arg_expr, vt);
                 }
@@ -1865,24 +1865,7 @@ impl @Liveness {
     fn warn_about_unused_args(sp: span, decl: fn_decl, entry_ln: LiveNode) {
         for decl.inputs.each |arg| {
             let var = self.variable(arg.id, arg.ty.span);
-            match ty::resolved_mode(self.tcx, arg.mode) {
-              by_mutbl_ref => {
-                // for mutable reference arguments, something like
-                //    x = 1;
-                // is not worth warning about, as it has visible
-                // side effects outside the fn.
-                match self.assigned_on_entry(entry_ln, var) {
-                  Some(_) => { /*ok*/ }
-                  None => {
-                    // but if it is not written, it ought to be used
-                    self.warn_about_unused(sp, entry_ln, var);
-                  }
-                }
-              }
-              by_val | by_ref | by_move | by_copy => {
-                self.warn_about_unused(sp, entry_ln, var);
-              }
-            }
+            self.warn_about_unused(sp, entry_ln, var);
         }
     }
 
diff --git a/src/rustc/middle/mem_categorization.rs b/src/rustc/middle/mem_categorization.rs
index fe465db1312c..dc5874ea2cfa 100644
--- a/src/rustc/middle/mem_categorization.rs
+++ b/src/rustc/middle/mem_categorization.rs
@@ -523,9 +523,6 @@ impl &mem_categorization_ctxt {
             // m: mutability of the argument
             // lp: loan path, must be none for aliasable things
             let {m,lp} = match ty::resolved_mode(self.tcx, mode) {
-              ast::by_mutbl_ref => {
-                {m: m_mutbl, lp: None}
-              }
               ast::by_move | ast::by_copy => {
                 {m: m_imm, lp: Some(@lp_arg(vid))}
               }
diff --git a/src/rustc/middle/privacy.rs b/src/rustc/middle/privacy.rs
index 4d291ceb590d..98260a0d0819 100644
--- a/src/rustc/middle/privacy.rs
+++ b/src/rustc/middle/privacy.rs
@@ -8,8 +8,8 @@ use syntax::ast::{item_trait, local_crate, node_id, pat_struct, private};
 use syntax::ast::{provided, required};
 use syntax::ast_map::{node_item, node_method};
 use ty::ty_class;
-use typeck::{method_map, method_origin, method_param, method_static};
-use typeck::{method_trait};
+use typeck::{method_map, method_origin, method_param, method_self};
+use typeck::{method_static, method_trait};
 
 use core::util::ignore;
 use dvec::DVec;
@@ -81,7 +81,8 @@ fn check_crate(tcx: ty::ctxt, method_map: &method_map, crate: @ast::crate) {
                 }
             }
             method_param({trait_id: trait_id, method_num: method_num, _}) |
-            method_trait(trait_id, method_num) => {
+            method_trait(trait_id, method_num, _) |
+            method_self(trait_id, method_num) => {
                 if trait_id.crate == local_crate {
                     match tcx.items.find(trait_id.node) {
                         Some(node_item(item, _)) => {
diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs
index eca0687f2fda..5f30346a28e8 100644
--- a/src/rustc/middle/resolve.rs
+++ b/src/rustc/middle/resolve.rs
@@ -4181,9 +4181,9 @@ impl Resolver {
         }
 
         return self.resolve_identifier(path.idents.last(),
-                                    namespace,
-                                    check_ribs,
-                                    path.span);
+                                       namespace,
+                                       check_ribs,
+                                       path.span);
     }
 
     fn resolve_identifier(identifier: ident,
diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs
index 0631d7b1ea4d..95711f8da36a 100644
--- a/src/rustc/middle/trans/base.rs
+++ b/src/rustc/middle/trans/base.rs
@@ -21,7 +21,7 @@ use session::session;
 use syntax::attr;
 use back::{link, abi, upcall};
 use syntax::{ast, ast_util, codemap, ast_map};
-use ast_util::{local_def, path_to_ident};
+use ast_util::{def_id_of_def, local_def, path_to_ident};
 use syntax::visit;
 use syntax::codemap::span;
 use syntax::print::pprust::{expr_to_str, stmt_to_str, path_to_str};
@@ -1503,7 +1503,7 @@ fn copy_args_to_allocas(fcx: fn_ctxt,
         // the event it's not truly needed.
         let llarg;
         match ty::resolved_mode(tcx, arg_ty.mode) {
-            ast::by_ref | ast::by_mutbl_ref => {
+            ast::by_ref => {
                 llarg = raw_llarg;
             }
             ast::by_move | ast::by_copy => {
@@ -1847,8 +1847,48 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
             }
         }
       }
-      ast::item_impl(tps, _, _, ms) => {
-        meth::trans_impl(ccx, *path, item.ident, ms, tps);
+      ast::item_impl(tps, trait_refs, self_ast_ty, ms) => {
+        meth::trans_impl(ccx, *path, item.ident, ms, tps, None);
+
+        // Translate any methods that have provided implementations.
+        for trait_refs.each |trait_ref_ptr| {
+            let trait_def = ccx.tcx.def_map.get(trait_ref_ptr.ref_id);
+
+            // XXX: Cross-crate default methods.
+            let trait_id = def_id_of_def(trait_def);
+            if trait_id.crate != ast::local_crate {
+                loop;
+            }
+
+            // Get the self type.
+            let self_ty;
+            match ccx.tcx.ast_ty_to_ty_cache.get(self_ast_ty) {
+                ty::atttce_resolved(self_type) => self_ty = self_type,
+                ty::atttce_unresolved => {
+                    ccx.tcx.sess.impossible_case(item.span,
+                                                 ~"didn't cache self ast ty");
+                }
+            }
+
+            match ccx.tcx.items.get(trait_id.node) {
+                ast_map::node_item(trait_item, _) => {
+                    match trait_item.node {
+                        ast::item_trait(tps, _, trait_methods) => {
+                            trans_trait(ccx, tps, trait_methods, path,
+                                        item.ident, self_ty);
+                        }
+                        _ => {
+                            ccx.tcx.sess.impossible_case(item.span,
+                                                         ~"trait item not a \
+                                                           trait");
+                        }
+                    }
+                }
+                _ => {
+                    ccx.tcx.sess.impossible_case(item.span, ~"no trait item");
+                }
+            }
+        }
       }
       ast::item_mod(m) => {
         trans_mod(ccx, m);
@@ -1873,9 +1913,6 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
       ast::item_class(struct_def, tps) => {
         trans_struct_def(ccx, struct_def, tps, path, item.ident, item.id);
       }
-      ast::item_trait(tps, _, trait_methods) => {
-        trans_trait(ccx, tps, trait_methods, path, item.ident);
-      }
       _ => {/* fall through */ }
     }
 }
@@ -1900,15 +1937,16 @@ fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def,
     // If there are ty params, the ctor will get monomorphized
 
     // Translate methods
-    meth::trans_impl(ccx, *path, ident, struct_def.methods, tps);
+    meth::trans_impl(ccx, *path, ident, struct_def.methods, tps, None);
 }
 
 fn trans_trait(ccx: @crate_ctxt, tps: ~[ast::ty_param],
                trait_methods: ~[ast::trait_method],
-               path: @ast_map::path, ident: ast::ident) {
+               path: @ast_map::path, ident: ast::ident,
+               self_ty: ty::t) {
     // Translate any methods that have provided implementations
     let (_, provided_methods) = ast_util::split_trait_methods(trait_methods);
-    meth::trans_impl(ccx, *path, ident, provided_methods, tps);
+    meth::trans_impl(ccx, *path, ident, provided_methods, tps, Some(self_ty));
 }
 
 // Translate a module. Doing this amounts to translating the items in the
@@ -1953,32 +1991,23 @@ fn register_fn_fuller(ccx: @crate_ctxt, sp: span, path: path,
            ast_map::path_to_str(path, ccx.sess.parse_sess.interner));
 
     let is_main = is_main_name(path) && !ccx.sess.building_library;
-    if is_main { create_main_wrapper(ccx, sp, llfn, node_type); }
+    if is_main { create_main_wrapper(ccx, sp, llfn); }
     llfn
 }
 
 // Create a _rust_main(args: ~[str]) function which will be called from the
 // runtime rust_start function
-fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
-                       main_node_type: ty::t) {
+fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef) {
 
     if ccx.main_fn != None:: {
         ccx.sess.span_fatal(sp, ~"multiple 'main' functions");
     }
 
-    let main_takes_argv =
-        // invariant!
-        match ty::get(main_node_type).sty {
-          ty::ty_fn(ref fn_ty) => fn_ty.sig.inputs.len() != 0u,
-          _ => ccx.sess.span_fatal(sp, ~"main has a non-function type")
-        };
-
-    let llfn = create_main(ccx, main_llfn, main_takes_argv);
+    let llfn = create_main(ccx, main_llfn);
     ccx.main_fn = Some(llfn);
     create_entry_fn(ccx, llfn);
 
-    fn create_main(ccx: @crate_ctxt, main_llfn: ValueRef,
-                   takes_argv: bool) -> ValueRef {
+    fn create_main(ccx: @crate_ctxt, main_llfn: ValueRef) -> ValueRef {
         let unit_ty = ty::mk_estr(ccx.tcx, ty::vstore_uniq);
         let vecarg_ty: ty::arg =
             {mode: ast::expl(ast::by_val),
@@ -1998,9 +2027,6 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef,
         let lloutputarg = llvm::LLVMGetParam(llfdecl, 0 as c_uint);
         let llenvarg = llvm::LLVMGetParam(llfdecl, 1 as c_uint);
         let mut args = ~[lloutputarg, llenvarg];
-        if takes_argv {
-            args.push(llvm::LLVMGetParam(llfdecl, 2 as c_uint));
-        }
         Call(bcx, main_llfn, args);
 
         build_return(bcx);
diff --git a/src/rustc/middle/trans/callee.rs b/src/rustc/middle/trans/callee.rs
index e7b4dd171e31..c851c5bc7250 100644
--- a/src/rustc/middle/trans/callee.rs
+++ b/src/rustc/middle/trans/callee.rs
@@ -592,7 +592,7 @@ fn trans_arg_expr(bcx: block,
             DoAutorefArg => { val = arg_datum.to_ref_llval(bcx); }
             DontAutorefArg => {
                 match arg_mode {
-                    ast::by_ref | ast::by_mutbl_ref => {
+                    ast::by_ref => {
                         val = arg_datum.to_ref_llval(bcx);
                     }
 
diff --git a/src/rustc/middle/trans/common.rs b/src/rustc/middle/trans/common.rs
index 6768f3e71a0d..68e957bfe709 100644
--- a/src/rustc/middle/trans/common.rs
+++ b/src/rustc/middle/trans/common.rs
@@ -963,8 +963,13 @@ fn T_captured_tydescs(cx: @crate_ctxt, n: uint) -> TypeRef {
     return T_struct(vec::from_elem::(n, T_ptr(cx.tydesc_type)));
 }
 
-fn T_opaque_trait(cx: @crate_ctxt) -> TypeRef {
-    T_struct(~[T_ptr(cx.tydesc_type), T_opaque_box_ptr(cx)])
+fn T_opaque_trait(cx: @crate_ctxt, vstore: ty::vstore) -> TypeRef {
+    match vstore {
+        ty::vstore_box =>
+            T_struct(~[T_ptr(cx.tydesc_type), T_opaque_box_ptr(cx)]),
+        _ =>
+            T_struct(~[T_ptr(cx.tydesc_type), T_ptr(T_i8())])
+    }
 }
 
 fn T_opaque_port_ptr() -> TypeRef { return T_ptr(T_i8()); }
diff --git a/src/rustc/middle/trans/glue.rs b/src/rustc/middle/trans/glue.rs
index a8a750cd4be4..d60a5a0bd7df 100644
--- a/src/rustc/middle/trans/glue.rs
+++ b/src/rustc/middle/trans/glue.rs
@@ -477,10 +477,13 @@ fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) {
       ty::ty_fn(_) => {
         closure::make_fn_glue(bcx, v0, t, drop_ty)
       }
-      ty::ty_trait(_, _, _) => {
+      ty::ty_trait(_, _, ty::vstore_box) => {
         let llbox = Load(bcx, GEPi(bcx, v0, [0u, 1u]));
         decr_refcnt_maybe_free(bcx, llbox, ty::mk_opaque_box(ccx.tcx))
       }
+      ty::ty_trait(_, _, ty::vstore_uniq) => {
+        ccx.tcx.sess.unimpl(~"drop of unique trait");
+      }
       ty::ty_opaque_closure_ptr(ck) => {
         closure::make_opaque_cbox_drop_glue(bcx, ck, v0)
       }
diff --git a/src/rustc/middle/trans/meth.rs b/src/rustc/middle/trans/meth.rs
index a94519306a48..d8a2fda4d14b 100644
--- a/src/rustc/middle/trans/meth.rs
+++ b/src/rustc/middle/trans/meth.rs
@@ -27,7 +27,8 @@ be generated once they are invoked with specific type parameters,
 see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`.
 */
 fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
-              methods: ~[@ast::method], tps: ~[ast::ty_param]) {
+              methods: ~[@ast::method], tps: ~[ast::ty_param],
+              self_ty: Option) {
     let _icx = ccx.insn_ctxt("impl::trans_impl");
     if tps.len() > 0u { return; }
     let sub_path = vec::append_one(path, path_name(name));
@@ -35,7 +36,7 @@ fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
         if method.tps.len() == 0u {
             let llfn = get_item_val(ccx, method.id);
             let path = vec::append_one(sub_path, path_name(method.ident));
-            trans_method(ccx, path, *method, None, llfn);
+            trans_method(ccx, path, *method, None, self_ty, llfn);
         }
     }
 }
@@ -49,12 +50,16 @@ Translates a (possibly monomorphized) method body.
 - `method`: the AST node for the method
 - `param_substs`: if this is a generic method, the current values for
   type parameters and so forth, else none
+- `base_self_ty`: optionally, the explicit self type for this method. This
+  will be none if this is not a default method and must always be present
+  if this is a default method.
 - `llfn`: the LLVM ValueRef for the method
 */
 fn trans_method(ccx: @crate_ctxt,
                 path: path,
                 method: &ast::method,
                 param_substs: Option,
+                base_self_ty: Option,
                 llfn: ValueRef) {
 
     // figure out how self is being passed
@@ -65,7 +70,11 @@ fn trans_method(ccx: @crate_ctxt,
       _ => {
         // determine the (monomorphized) type that `self` maps to for
         // this method
-        let self_ty = ty::node_id_to_type(ccx.tcx, method.self_id);
+        let self_ty;
+        match base_self_ty {
+            None => self_ty = ty::node_id_to_type(ccx.tcx, method.self_id),
+            Some(provided_self_ty) => self_ty = provided_self_ty
+        }
         let self_ty = match param_substs {
           None => self_ty,
           Some({tys: ref tys, _}) => ty::subst_tps(ccx.tcx, *tys, self_ty)
@@ -142,8 +151,11 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id,
                 None => fail ~"trans_method_callee: missing param_substs"
             }
         }
-        typeck::method_trait(_, off) => {
-            trans_trait_callee(bcx, callee_id, off, self)
+        typeck::method_trait(_, off, vstore) => {
+            trans_trait_callee(bcx, callee_id, off, self, vstore)
+        }
+        typeck::method_self(*) => {
+            bcx.tcx().sess.span_bug(self.span, ~"self method call");
         }
     }
 }
@@ -288,8 +300,8 @@ fn trans_monomorphized_callee(bcx: block,
               })
           }
       }
-      typeck::vtable_trait(*) => {
-          trans_trait_callee(bcx, callee_id, n_method, base)
+      typeck::vtable_trait(_, _) => {
+          trans_trait_callee(bcx, callee_id, n_method, base, ty::vstore_box)
       }
       typeck::vtable_param(*) => {
           fail ~"vtable_param left in monomorphized function's vtable substs";
@@ -390,7 +402,8 @@ fn combine_impl_and_methods_origins(bcx: block,
 fn trans_trait_callee(bcx: block,
                       callee_id: ast::node_id,
                       n_method: uint,
-                      self_expr: @ast::expr)
+                      self_expr: @ast::expr,
+                      vstore: ty::vstore)
     -> Callee
 {
     //!
@@ -398,8 +411,8 @@ fn trans_trait_callee(bcx: block,
     // Create a method callee where the method is coming from a trait
     // instance (e.g., @Trait type).  In this case, we must pull the
     // fn pointer out of the vtable that is packaged up with the
-    // @Trait instance.  @Traits are represented as a pair, so we first
-    // evaluate the self expression (expected a by-ref result) and then
+    // @/~/&Trait instance.  @/~/&Traits are represented as a pair, so we
+    // first evaluate the self expression (expected a by-ref result) and then
     // extract the self data and vtable out of the pair.
 
     let _icx = bcx.insn_ctxt("impl::trans_trait_callee");
@@ -407,13 +420,14 @@ fn trans_trait_callee(bcx: block,
     let self_datum = unpack_datum!(bcx, expr::trans_to_datum(bcx, self_expr));
     let llpair = self_datum.to_ref_llval(bcx);
     let callee_ty = node_id_type(bcx, callee_id);
-    trans_trait_callee_from_llval(bcx, callee_ty, n_method, llpair)
+    trans_trait_callee_from_llval(bcx, callee_ty, n_method, llpair, vstore)
 }
 
 fn trans_trait_callee_from_llval(bcx: block,
                                  callee_ty: ty::t,
                                  n_method: uint,
-                                 llpair: ValueRef)
+                                 llpair: ValueRef,
+                                 vstore: ty::vstore)
     -> Callee
 {
     //!
@@ -431,9 +445,21 @@ fn trans_trait_callee_from_llval(bcx: block,
                                   GEPi(bcx, llpair, [0u, 0u]),
                                   T_ptr(T_ptr(T_vtable()))));
 
-    // Load the box from the @Trait pair and GEP over the box header:
+    // Load the box from the @Trait pair and GEP over the box header if
+    // necessary:
+    let llself;
     let llbox = Load(bcx, GEPi(bcx, llpair, [0u, 1u]));
-    let llself = GEPi(bcx, llbox, [0u, abi::box_field_body]);
+    match vstore {
+        ty::vstore_box | ty::vstore_uniq => {
+            llself = GEPi(bcx, llbox, [0u, abi::box_field_body]);
+        }
+        ty::vstore_slice(_) => {
+            llself = llbox;
+        }
+        ty::vstore_fixed(*) => {
+            bcx.tcx().sess.bug(~"vstore_fixed trait");
+        }
+    }
 
     // Load the function from the vtable and cast it to the expected type.
     let llcallee_ty = type_of::type_of_fn_from_ty(ccx, callee_ty);
@@ -503,7 +529,7 @@ fn make_impl_vtable(ccx: @crate_ctxt, impl_id: ast::def_id, substs: ~[ty::t],
     // XXX: This should support multiple traits.
     let trt_id = driver::session::expect(
         tcx.sess,
-        ty::ty_to_def_id(ty::impl_traits(tcx, impl_id)[0]),
+        ty::ty_to_def_id(ty::impl_traits(tcx, impl_id, ty::vstore_box)[0]),
         || ~"make_impl_vtable: non-trait-type implemented");
 
     let has_tps = (*ty::lookup_item_type(ccx.tcx, impl_id).bounds).len() > 0u;
diff --git a/src/rustc/middle/trans/monomorphize.rs b/src/rustc/middle/trans/monomorphize.rs
index cd8cffa297a6..17eaf591c9f3 100644
--- a/src/rustc/middle/trans/monomorphize.rs
+++ b/src/rustc/middle/trans/monomorphize.rs
@@ -156,9 +156,10 @@ fn monomorphic_fn(ccx: @crate_ctxt,
         d
       }
       ast_map::node_method(mth, _, _) => {
+        // XXX: What should the self type be here?
         let d = mk_lldecl();
         set_inline_hint_if_appr(mth.attrs, d);
-        meth::trans_method(ccx, pt, mth, psubsts, d);
+        meth::trans_method(ccx, pt, mth, psubsts, None, d);
         d
       }
       ast_map::node_ctor(_, tps, ctor, parent_id, _) => {
diff --git a/src/rustc/middle/trans/reflect.rs b/src/rustc/middle/trans/reflect.rs
index cdd11ee85c57..c105caecaebb 100644
--- a/src/rustc/middle/trans/reflect.rs
+++ b/src/rustc/middle/trans/reflect.rs
@@ -70,10 +70,12 @@ impl reflector {
         }
         let bool_ty = ty::mk_bool(tcx);
         let scratch = scratch_datum(bcx, bool_ty, false);
+        // XXX: Should not be vstore_box!
         let bcx = callee::trans_call_inner(
             self.bcx, None, mth_ty, bool_ty,
             |bcx| meth::trans_trait_callee_from_llval(bcx, mth_ty,
-                                                      mth_idx, v),
+                                                      mth_idx, v,
+                                                      ty::vstore_box),
             ArgVals(args), SaveIn(scratch.val), DontAutorefArg);
         let result = scratch.to_value_llval(bcx);
         let next_bcx = sub_block(bcx, ~"next");
@@ -208,7 +210,6 @@ impl reflector {
                   ast::expl(e) => match e {
                     ast::by_ref => 1u,
                     ast::by_val => 2u,
-                    ast::by_mutbl_ref => 3u,
                     ast::by_move => 4u,
                     ast::by_copy => 5u
                   }
diff --git a/src/rustc/middle/trans/shape.rs b/src/rustc/middle/trans/shape.rs
index cf58b5b51c4c..127af4388073 100644
--- a/src/rustc/middle/trans/shape.rs
+++ b/src/rustc/middle/trans/shape.rs
@@ -49,12 +49,16 @@ fn mk_ctxt(llmod: ModuleRef) -> ctxt {
     return {mut next_tag_id: 0u16, pad: 0u16, pad2: 0u32};
 }
 
-fn add_u16(&dest: ~[u8], val: u16) {
-    dest += ~[(val & 0xffu16) as u8, (val >> 8u16) as u8];
+/*
+Although these two functions are never called, they are here
+for a VERY GOOD REASON. See #3670
+*/
+fn add_u16(dest: &mut ~[u8], val: u16) {
+    *dest += ~[(val & 0xffu16) as u8, (val >> 8u16) as u8];
 }
 
-fn add_substr(&dest: ~[u8], src: ~[u8]) {
+fn add_substr(dest: &mut ~[u8], src: ~[u8]) {
     add_u16(dest, vec::len(src) as u16);
-    dest += src;
+    *dest += src;
 }
 
diff --git a/src/rustc/middle/trans/type_of.rs b/src/rustc/middle/trans/type_of.rs
index b45da3b27004..7b5a912ed7f2 100644
--- a/src/rustc/middle/trans/type_of.rs
+++ b/src/rustc/middle/trans/type_of.rs
@@ -159,7 +159,7 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
         T_struct(~[T_struct(tys)])
       }
       ty::ty_fn(_) => T_fn_pair(cx, type_of_fn_from_ty(cx, t)),
-      ty::ty_trait(_, _, _) => T_opaque_trait(cx),
+      ty::ty_trait(_, _, vstore) => T_opaque_trait(cx, vstore),
       ty::ty_type => T_ptr(cx.tydesc_type),
       ty::ty_tup(elts) => {
         let mut tys = ~[];
diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs
index 6bd3c22f626a..ee247eb5db79 100644
--- a/src/rustc/middle/trans/type_use.rs
+++ b/src/rustc/middle/trans/type_use.rs
@@ -53,7 +53,7 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
                     by_val | by_move | by_copy => {
                         type_needs(cx, use_repr, arg.ty);
                     }
-                    by_ref | by_mutbl_ref => {}
+                    by_ref => {}
                 }
             }
         }
@@ -247,7 +247,7 @@ fn mark_for_expr(cx: ctx, e: @expr) {
               typeck::method_param({param_num: param, _}) => {
                 cx.uses[param] |= use_tydesc;
               }
-              typeck::method_trait(_, _) => (),
+              typeck::method_trait(*) | typeck::method_self(*) => (),
             }
         }
       }
diff --git a/src/rustc/middle/trans/uniq.rs b/src/rustc/middle/trans/uniq.rs
index 6ab91c4a1d79..50ea363ace2a 100644
--- a/src/rustc/middle/trans/uniq.rs
+++ b/src/rustc/middle/trans/uniq.rs
@@ -3,7 +3,6 @@ use lib::llvm::ValueRef;
 use common::*;
 use build::*;
 use base::*;
-use shape::llsize_of;
 use datum::immediate_rvalue;
 
 export make_free_glue, autoderef, duplicate;
diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs
index 109db9ace099..f2f7b32b6706 100644
--- a/src/rustc/middle/ty.rs
+++ b/src/rustc/middle/ty.rs
@@ -90,6 +90,7 @@ export ty_estr, mk_estr, type_is_str;
 export ty_evec, mk_evec, type_is_vec;
 export ty_unboxed_vec, mk_unboxed_vec, mk_mut_unboxed_vec;
 export vstore, vstore_fixed, vstore_uniq, vstore_box, vstore_slice;
+export serialize_vstore, deserialize_vstore;
 export ty_nil, mk_nil, type_is_nil;
 export ty_trait, mk_trait;
 export ty_param, mk_param, ty_params_to_tys;
@@ -217,6 +218,7 @@ type method = {ident: ast::ident,
 
 type mt = {ty: t, mutbl: ast::mutability};
 
+#[auto_serialize]
 enum vstore {
     vstore_fixed(uint),
     vstore_uniq,
@@ -1624,7 +1626,10 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
       ty_evec(_, vstore_uniq) |
       ty_evec(_, vstore_box) => true,
 
-      ty_trait(*) => true,
+      ty_trait(_, _, vstore_box) |
+      ty_trait(_, _, vstore_uniq) => true,
+      ty_trait(_, _, vstore_fixed(_)) |
+      ty_trait(_, _, vstore_slice(_)) => false,
 
       ty_param(*) | ty_infer(*) => true,
 
@@ -2821,7 +2826,8 @@ fn method_call_bounds(tcx: ctxt, method_map: typeck::method_map,
           }
           typeck::method_param({trait_id:trt_id,
                                 method_num:n_mth, _}) |
-          typeck::method_trait(trt_id, n_mth) => {
+          typeck::method_trait(trt_id, n_mth, _) |
+          typeck::method_self(trt_id, n_mth) => {
             // ...trait methods bounds, in contrast, include only the
             // method bounds, so we must preprend the tps from the
             // trait itself.  This ought to be harmonized.
@@ -3362,7 +3368,15 @@ fn trait_methods(cx: ctxt, id: ast::def_id) -> @~[method] {
 /*
   Could this return a list of (def_id, substs) pairs?
  */
-fn impl_traits(cx: ctxt, id: ast::def_id) -> ~[t] {
+fn impl_traits(cx: ctxt, id: ast::def_id, vstore: vstore) -> ~[t] {
+    fn vstoreify(cx: ctxt, ty: t, vstore: vstore) -> t {
+        match ty::get(ty).sty {
+            ty::ty_trait(_, _, trait_vstore) if vstore == trait_vstore => ty,
+            ty::ty_trait(did, substs, _) => mk_trait(cx, did, substs, vstore),
+            _ => cx.sess.bug(~"impl_traits: not a trait")
+        }
+    }
+
     if id.crate == ast::local_crate {
         debug!("(impl_traits) searching for trait impl %?", id);
         match cx.items.find(id.node) {
@@ -3372,19 +3386,23 @@ fn impl_traits(cx: ctxt, id: ast::def_id) -> ~[t] {
                     _)) => {
 
                do option::map_default(&opt_trait, ~[]) |trait_ref| {
-                       ~[node_id_to_type(cx, trait_ref.ref_id)]
+                       ~[vstoreify(cx,
+                                   node_id_to_type(cx, trait_ref.ref_id),
+                                   vstore)]
                    }
            }
            Some(ast_map::node_item(@{node: ast::item_class(sd,_),
                            _},_)) => {
                do vec::map(sd.traits) |trait_ref| {
-                    node_id_to_type(cx, trait_ref.ref_id)
+                    vstoreify(cx, node_id_to_type(cx, trait_ref.ref_id),
+                              vstore)
                 }
            }
            _ => ~[]
         }
     } else {
-        csearch::get_impl_traits(cx, id)
+        vec::map(csearch::get_impl_traits(cx, id),
+                 |x| vstoreify(cx, *x, vstore))
     }
 }
 
diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs
index e0b2ca5ae642..514fc2cfbb32 100644
--- a/src/rustc/middle/typeck.rs
+++ b/src/rustc/middle/typeck.rs
@@ -73,7 +73,7 @@ export deserialize_method_map_entry;
 export vtable_map;
 export vtable_res;
 export vtable_origin;
-export method_static, method_param, method_trait;
+export method_static, method_param, method_trait, method_self;
 export vtable_static, vtable_param, vtable_trait;
 export provided_methods_map;
 
@@ -86,7 +86,10 @@ enum method_origin {
     method_param(method_param),
 
     // method invoked on a trait instance
-    method_trait(ast::def_id, uint),
+    method_trait(ast::def_id, uint, ty::vstore),
+
+    // method invoked on "self" inside a default method
+    method_self(ast::def_id, uint),
 }
 
 // details for a method invoked with a receiver whose type is a type parameter
@@ -301,14 +304,12 @@ fn check_main_fn_ty(ccx: @crate_ctxt,
             }
             let mut ok = ty::type_is_nil(fn_ty.sig.output);
             let num_args = vec::len(fn_ty.sig.inputs);
-            ok &= num_args == 0u || num_args == 1u &&
-                arg_is_argv_ty(tcx, fn_ty.sig.inputs[0]);
+            ok &= num_args == 0u;
             if !ok {
                 tcx.sess.span_err(
                     main_span,
                     fmt!("Wrong type in main function: found `%s`, \
-                          expected `extern fn(++v: ~[~str]) -> ()` \
-                          or `extern fn() -> ()`",
+                          expected `fn() -> ()`",
                          ty_to_str(tcx, main_t)));
             }
         }
diff --git a/src/rustc/middle/typeck/astconv.rs b/src/rustc/middle/typeck/astconv.rs
index 45a7c22e2f90..14797fcdd6bb 100644
--- a/src/rustc/middle/typeck/astconv.rs
+++ b/src/rustc/middle/typeck/astconv.rs
@@ -189,16 +189,19 @@ fn ast_ty_to_ty(
                                                        type_def_id, path);
                 match ty::get(result.ty).sty {
                     ty::ty_trait(trait_def_id, substs, _) => {
-                        if vst != ty::vstore_box {
-                            tcx.sess.span_unimpl(path.span,
-                                                 ~"`~trait` and `&trait` are \
-                                                   unimplemented; use \
-                                                   `@trait` instead for now");
+                        match vst {
+                            ty::vstore_box | ty::vstore_slice(*) => {}
+                            _ => {
+                                tcx.sess.span_unimpl(path.span,
+                                                     ~"`~trait` is \
+                                                       unimplemented; use \
+                                                       `@trait` instead for \
+                                                       now");
+                            }
                         }
                         return ty::mk_trait(tcx, trait_def_id, substs, vst);
                     }
-                    _ =>
-                        {}
+                    _ => {}
                 }
               }
               _ => ()
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index 368b69cafaba..7cc2c8b0ad76 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/src/rustc/middle/typeck/check.rs
@@ -2601,7 +2601,9 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
       ~"addr_of" => (1u, ~[arg(ast::by_ref, param(ccx, 0u))],
                       ty::mk_imm_ptr(tcx, param(ccx, 0u))),
       ~"move_val" | ~"move_val_init" => {
-        (1u, ~[arg(ast::by_mutbl_ref, param(ccx, 0u)),
+          (1u, ~[arg(ast::by_copy,
+                     ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)),
+                                     param(ccx, 0u))),
                arg(ast::by_move, param(ccx, 0u))],
          ty::mk_nil(tcx))
       }
diff --git a/src/rustc/middle/typeck/check/method.rs b/src/rustc/middle/typeck/check/method.rs
index d08d3e9b8478..f3b2c8f1b7ed 100644
--- a/src/rustc/middle/typeck/check/method.rs
+++ b/src/rustc/middle/typeck/check/method.rs
@@ -221,9 +221,9 @@ impl LookupContext {
                 ty_param(p) => {
                     self.push_inherent_candidates_from_param(p);
                 }
-                ty_trait(did, ref substs, _) => {
+                ty_trait(did, ref substs, vstore) => {
                     self.push_inherent_candidates_from_trait(
-                        self_ty, did, substs);
+                        self_ty, did, substs, vstore);
                     self.push_inherent_impl_candidates_for_type(did);
                 }
                 ty_self => {
@@ -232,7 +232,7 @@ impl LookupContext {
                     let self_did = self.fcx.self_impl_def_id.expect(
                         ~"unexpected `none` for self_impl_def_id");
                     let substs = {self_r: None, self_ty: None, tps: ~[]};
-                    self.push_inherent_candidates_from_trait(
+                    self.push_inherent_candidates_from_self(
                         self_ty, self_did, &substs);
                 }
                 ty_enum(did, _) | ty_class(did, _) => {
@@ -347,7 +347,8 @@ impl LookupContext {
     fn push_inherent_candidates_from_trait(&self,
                                            self_ty: ty::t,
                                            did: def_id,
-                                           substs: &ty::substs)
+                                           substs: &ty::substs,
+                                           vstore: ty::vstore)
     {
         debug!("push_inherent_candidates_from_trait(did=%s, substs=%s)",
                self.did_to_str(did),
@@ -391,7 +392,34 @@ impl LookupContext {
             rcvr_substs: move rcvr_substs,
             num_method_tps: method.tps.len(),
             self_mode: get_mode_from_self_type(method.self_ty),
-            origin: method_trait(did, index)
+            origin: method_trait(did, index, vstore)
+        });
+    }
+
+    fn push_inherent_candidates_from_self(&self,
+                                          self_ty: ty::t,
+                                          did: def_id,
+                                          substs: &ty::substs) {
+        let tcx = self.tcx();
+        let methods = ty::trait_methods(tcx, did);  // XXX: Inherited methods.
+        let index;
+        match vec::position(*methods, |m| m.ident == self.m_name) {
+            Some(i) => index = i,
+            None => return
+        }
+        let method = &methods[index];
+
+        let rcvr_substs = { self_ty: Some(self_ty), ..*substs };
+        let (rcvr_ty, rcvr_substs) =
+            self.create_rcvr_ty_and_substs_for_method(
+                method.self_ty, self_ty, move rcvr_substs);
+
+        self.inherent_candidates.push(Candidate {
+            rcvr_ty: rcvr_ty,
+            rcvr_substs: move rcvr_substs,
+            num_method_tps: method.tps.len(),
+            self_mode: get_mode_from_self_type(method.self_ty),
+            origin: method_self(did, index)
         });
     }
 
@@ -735,7 +763,7 @@ impl LookupContext {
          * vtable and hence cannot be monomorphized. */
 
         match candidate.origin {
-            method_static(*) | method_param(*) => {
+            method_static(*) | method_param(*) | method_self(*) => {
                 return; // not a call to a trait instance
             }
             method_trait(*) => {}
@@ -770,7 +798,7 @@ impl LookupContext {
             method_param(ref mp) => {
                 type_of_trait_method(self.tcx(), mp.trait_id, mp.method_num)
             }
-            method_trait(did, idx) => {
+            method_trait(did, idx, _) | method_self(did, idx) => {
                 type_of_trait_method(self.tcx(), did, idx)
             }
         };
@@ -791,7 +819,7 @@ impl LookupContext {
             method_param(mp) => {
                 self.report_param_candidate(idx, mp.trait_id)
             }
-            method_trait(trait_did, _) => {
+            method_trait(trait_did, _, _) | method_self(trait_did, _) => {
                 self.report_param_candidate(idx, trait_did)
             }
         }
diff --git a/src/rustc/middle/typeck/check/regionck.rs b/src/rustc/middle/typeck/check/regionck.rs
index d8ea330ee11f..0b258da5672d 100644
--- a/src/rustc/middle/typeck/check/regionck.rs
+++ b/src/rustc/middle/typeck/check/regionck.rs
@@ -221,11 +221,7 @@ fn visit_expr(expr: @ast::expr, &&rcx: @rcx, v: rvt) {
                 result::Err(_) => { return; /*typeck will fail anyhow*/ }
                 result::Ok(target_ty) => {
                     match ty::get(target_ty).sty {
-                        ty::ty_trait(_, substs, _) => {
-                            let trait_region = match substs.self_r {
-                                Some(r) => {r}
-                                None => {ty::re_static}
-                            };
+                        ty::ty_trait(_, _, vstore_slice(trait_region)) => {
                             let source_ty = rcx.fcx.expr_ty(source);
                             constrain_regions_in_type(rcx, trait_region,
                                                       expr.span, source_ty);
diff --git a/src/rustc/middle/typeck/check/vtable.rs b/src/rustc/middle/typeck/check/vtable.rs
index e8595b2f50a1..00fb134f2be5 100644
--- a/src/rustc/middle/typeck/check/vtable.rs
+++ b/src/rustc/middle/typeck/check/vtable.rs
@@ -51,8 +51,8 @@ fn lookup_vtables(fcx: @fn_ctxt,
             match *bound {
               ty::bound_trait(i_ty) => {
                 let i_ty = ty::subst(tcx, substs, i_ty);
-                match lookup_vtable(fcx, expr, *ty, i_ty, allow_unsafe,
-                                    is_early) {
+                match lookup_vtable_covariant(fcx, expr, *ty, i_ty,
+                                              allow_unsafe, is_early) {
                     Some(vtable) => result.push(vtable),
                     None => {
                         fcx.tcx().sess.span_fatal(
@@ -91,28 +91,75 @@ fn relate_trait_tys(fcx: @fn_ctxt, expr: @ast::expr,
     demand::suptype(fcx, expr.span, exp_trait_ty, act_trait_ty)
 }
 
-/*
-Look up the vtable to use when treating an item of type 
-as if it has type 
-*/
-fn lookup_vtable(fcx: @fn_ctxt,
-                 expr: @ast::expr,
-                 ty: ty::t,
-                 trait_ty: ty::t,
-                 allow_unsafe: bool,
-                 is_early: bool)
-    -> Option
-{
+// Look up the vtable to use when treating an item of type `t` as if it has
+// type `trait_ty`. This does allow subtraits.
+fn lookup_vtable_covariant(fcx: @fn_ctxt,
+                           expr: @ast::expr,
+                           ty: ty::t,
+                           trait_ty: ty::t,
+                           allow_unsafe: bool,
+                           is_early: bool)
+                        -> Option {
+    let worklist = dvec::DVec();
+    worklist.push(trait_ty);
+    while worklist.len() > 0 {
+        let trait_ty = worklist.pop();
+        let result = lookup_vtable_invariant(fcx, expr, ty, trait_ty,
+                                             allow_unsafe, is_early);
+        if result.is_some() {
+            return result;
+        }
 
-    debug!("lookup_vtable(ty=%s, trait_ty=%s)",
+        // Add subtraits to the worklist, if applicable.
+        match ty::get(trait_ty).sty {
+            ty::ty_trait(trait_id, _, _) => {
+                let table = fcx.ccx.coherence_info.supertrait_to_subtraits;
+                match table.find(trait_id) {
+                    None => {}
+                    Some(subtraits) => {
+                        for subtraits.each |subtrait_id| {
+                            // XXX: This is wrong; subtraits should themselves
+                            // have substs.
+                            let substs =
+                                { self_r: None, self_ty: None, tps: ~[] };
+                            let trait_ty = ty::mk_trait(fcx.ccx.tcx,
+                                                        *subtrait_id,
+                                                        substs,
+                                                        ty::vstore_box);
+                            worklist.push(trait_ty);
+                        }
+                    }
+                }
+            }
+            _ => {
+                fcx.ccx.tcx.sess.impossible_case(expr.span,
+                                                 "lookup_vtable_covariant: \
+                                                  non-trait in worklist");
+            }
+        }
+    }
+
+    return None;
+}
+
+// Look up the vtable to use when treating an item of type `t` as if it has
+// type `trait_ty`. This does not allow subtraits.
+fn lookup_vtable_invariant(fcx: @fn_ctxt,
+                           expr: @ast::expr,
+                           ty: ty::t,
+                           trait_ty: ty::t,
+                           allow_unsafe: bool,
+                           is_early: bool)
+                        -> Option {
+    debug!("lookup_vtable_invariant(ty=%s, trait_ty=%s)",
            fcx.infcx().ty_to_str(ty), fcx.inh.infcx.ty_to_str(trait_ty));
     let _i = indenter();
 
     let tcx = fcx.ccx.tcx;
-    let (trait_id, trait_substs) = match ty::get(trait_ty).sty {
-        ty::ty_trait(did, substs, _) => (did, substs),
+    let (trait_id, trait_substs, trait_vstore) = match ty::get(trait_ty).sty {
+        ty::ty_trait(did, substs, vstore) => (did, substs, vstore),
         _ => tcx.sess.impossible_case(expr.span,
-                                      "lookup_vtable: \
+                                      "lookup_vtable_invariant: \
                                        don't know how to handle a non-trait")
     };
     let ty = match fixup_ty(fcx, expr, ty, is_early) {
@@ -150,7 +197,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
                             }
                             _ => tcx.sess.impossible_case(
                                 expr.span,
-                                "lookup_vtable: in loop, \
+                                "lookup_vtable_invariant: in loop, \
                                  don't know how to handle a non-trait ity")
                         }
                         n_bound += 1u;
@@ -223,7 +270,8 @@ fn lookup_vtable(fcx: @fn_ctxt,
                         // it's the same trait as trait_ty, we need to
                         // unify it with trait_ty in order to get all
                         // the ty vars sorted out.
-                        for vec::each(ty::impl_traits(tcx, im.did)) |of_ty| {
+                        for vec::each(ty::impl_traits(tcx, im.did,
+                                                      trait_vstore)) |of_ty| {
                             match ty::get(*of_ty).sty {
                                 ty::ty_trait(id, _, _) => {
                                     // Not the trait we're looking for
@@ -331,7 +379,8 @@ fn lookup_vtable(fcx: @fn_ctxt,
                             // lists of types to unify pairwise.
 
                             connect_trait_tps(fcx, expr, substs_f.tps,
-                                              trait_tps, im.did);
+                                              trait_tps, im.did,
+                                              trait_vstore);
                             let subres = lookup_vtables(
                                 fcx, expr, im_bs, &substs_f,
                                 false, is_early);
@@ -389,11 +438,12 @@ fn fixup_ty(fcx: @fn_ctxt,
 }
 
 fn connect_trait_tps(fcx: @fn_ctxt, expr: @ast::expr, impl_tys: ~[ty::t],
-                     trait_tys: ~[ty::t], impl_did: ast::def_id) {
+                     trait_tys: ~[ty::t], impl_did: ast::def_id,
+                     vstore: ty::vstore) {
     let tcx = fcx.ccx.tcx;
 
     // XXX: This should work for multiple traits.
-    let ity = ty::impl_traits(tcx, impl_did)[0];
+    let ity = ty::impl_traits(tcx, impl_did, vstore)[0];
     let trait_ty = ty::subst_tps(tcx, impl_tys, ity);
     debug!("(connect trait tps) trait type is %?, impl did is %?",
            ty::get(trait_ty).sty, impl_did);
@@ -461,37 +511,85 @@ fn early_resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, is_early: bool) {
       ast::expr_cast(src, _) => {
         let target_ty = fcx.expr_ty(ex);
         match ty::get(target_ty).sty {
-          ty::ty_trait(*) => {
-            /*
-            Look up vtables for the type we're casting to,
-            passing in the source and target type
-            */
+          ty::ty_trait(_, _, vstore) => {
+            // Look up vtables for the type we're casting to, passing in the
+            // source and target type.
+            //
+            // XXX: This is invariant and shouldn't be. --pcw
+
             let ty = fcx.expr_ty(src);
-            let vtable_opt = lookup_vtable(fcx, ex, ty, target_ty, true,
-                                           is_early);
+            let vtable_opt = lookup_vtable_invariant(fcx, ex, ty, target_ty,
+                                                     true, is_early);
             match vtable_opt {
                 None => {
                     // Try the new-style boxed trait; "@int as @Trait".
+                    // Or the new-style region trait; "&int as &Trait".
                     let mut err = false;
                     let ty = structurally_resolved_type(fcx, ex.span, ty);
                     match ty::get(ty).sty {
-                        ty::ty_box(boxed_ty) => {
-                            let vtable_opt = lookup_vtable(fcx, ex,
-                                                           boxed_ty.ty,
-                                                           target_ty, true,
-                                                           is_early);
-                            match vtable_opt {
-                                Some(vtable) => {
-                                    /*
-                                    Map this expression to that vtable (that
-                                    is: "ex has vtable ")
-                                    */
-                                    if !is_early {
-                                        cx.vtable_map.insert(ex.id,
-                                                             @~[vtable]);
+                        ty::ty_box(mt) | ty::ty_rptr(_, mt) => {
+                            // Ensure that the trait vstore and the pointer
+                            // type match.
+                            match (ty::get(ty).sty, vstore) {
+                                (ty::ty_box(_), ty::vstore_box) |
+                                (ty::ty_rptr(*), ty::vstore_slice(*)) => {
+                                    let vtable_opt =
+                                        lookup_vtable_invariant(fcx,
+                                                                ex,
+                                                                mt.ty,
+                                                                target_ty,
+                                                                true,
+                                                                is_early);
+                                    match vtable_opt {
+                                        Some(vtable) => {
+                                            // Map this expression to that
+                                            // vtable (that is: "ex has vtable
+                                            // ")
+                                            if !is_early {
+                                                cx.vtable_map.insert(
+                                                    ex.id, @~[vtable]);
+                                            }
+                                        }
+                                        None => err = true
+                                    }
+
+                                    // Now, if this is &trait, we need to link
+                                    // the regions.
+                                    match (ty::get(ty).sty, vstore) {
+                                        (ty::ty_rptr(ra, _),
+                                         ty::vstore_slice(rb)) => {
+                                            infer::mk_subr(fcx.infcx(),
+                                                           false,
+                                                           ex.span,
+                                                           rb,
+                                                           ra);
+                                        }
+                                        _ => {}
                                     }
                                 }
-                                None => err = true
+                                (ty::ty_box(_), _) => {
+                                    fcx.ccx.tcx.sess.span_err(ex.span,
+                                                              ~"must cast \
+                                                                a boxed \
+                                                                pointer to \
+                                                                a boxed
+                                                                trait");
+                                    err = true;
+                                }
+                                (ty::ty_rptr(*), _) => {
+                                    fcx.ccx.tcx.sess.span_err(ex.span,
+                                                              ~"must cast \
+                                                                a borrowed \
+                                                                pointer to \
+                                                                a borrowed \
+                                                                trait");
+                                }
+                                _ => {
+                                    fcx.ccx.tcx.sess.impossible_case(
+                                        ex.span,
+                                        ~"impossible combination of type and \
+                                          trait vstore");
+                                }
                             }
                         }
                         _ => err = true
diff --git a/src/rustc/middle/typeck/coherence.rs b/src/rustc/middle/typeck/coherence.rs
index e9238e30c663..89cd696eb6fb 100644
--- a/src/rustc/middle/typeck/coherence.rs
+++ b/src/rustc/middle/typeck/coherence.rs
@@ -126,12 +126,16 @@ struct CoherenceInfo {
     // Contains implementations of methods associated with a trait. For these,
     // the associated trait must be imported at the call site.
     extension_methods: HashMap>,
+
+    // A mapping from a supertrait to its subtraits.
+    supertrait_to_subtraits: HashMap>
 }
 
 fn CoherenceInfo() -> CoherenceInfo {
     CoherenceInfo {
         inherent_methods: HashMap(),
-        extension_methods: HashMap()
+        extension_methods: HashMap(),
+        supertrait_to_subtraits: HashMap()
     }
 }
 
@@ -161,7 +165,6 @@ struct CoherenceChecker {
 }
 
 impl CoherenceChecker {
-
     // Create a mapping containing a MethodInfo for every provided
     // method in every trait.
     fn build_provided_methods_map(crate: @crate) {
@@ -225,9 +228,9 @@ impl CoherenceChecker {
     }
 
     fn check_coherence(crate: @crate) {
-
-        // Check implementations. This populates the tables containing the
-        // inherent methods and extension methods.
+        // Check implementations and traits. This populates the tables
+        // containing the inherent methods and extension methods. It also
+        // builds up the trait inheritance table.
         visit_crate(*crate, (), mk_simple_visitor(@{
             visit_item: |item| {
                 debug!("(checking coherence) item '%s'",
@@ -240,6 +243,9 @@ impl CoherenceChecker {
                     item_class(struct_def, _) => {
                         self.check_implementation(item, struct_def.traits);
                     }
+                    item_trait(_, supertraits, _) => {
+                        self.register_inherited_trait(item, supertraits);
+                    }
                     _ => {
                         // Nothing to do.
                     }
@@ -324,6 +330,27 @@ impl CoherenceChecker {
         }
     }
 
+    fn register_inherited_trait(item: @item, supertraits: ~[@trait_ref]) {
+        // XXX: This is wrong. We need to support substitutions; e.g.
+        // trait Foo : Bar.
+        let supertrait_to_subtraits =
+            self.crate_context.coherence_info.supertrait_to_subtraits;
+        let subtrait_id = local_def(item.id);
+        for supertraits.each |supertrait| {
+            let supertrait_id = self.trait_ref_to_trait_def_id(*supertrait);
+            match supertrait_to_subtraits.find(supertrait_id) {
+                None => {
+                    let new_vec = @dvec::DVec();
+                    new_vec.push(subtrait_id);
+                    supertrait_to_subtraits.insert(supertrait_id, new_vec);
+                }
+                Some(existing_vec) => {
+                    existing_vec.push(subtrait_id);
+                }
+            }
+        }
+    }
+
     fn add_inherent_method(base_def_id: def_id, implementation: @Impl) {
         let implementation_list;
         match self.crate_context.coherence_info.inherent_methods
diff --git a/src/rustdoc/astsrv.rs b/src/rustdoc/astsrv.rs
index ab6b348c04a2..2e6cbf579c8e 100644
--- a/src/rustdoc/astsrv.rs
+++ b/src/rustdoc/astsrv.rs
@@ -93,7 +93,7 @@ fn exec(
     +f: fn~(ctxt: Ctxt) -> T
 ) -> T {
     let po = comm::Port();
-    let ch = comm::Chan(po);
+    let ch = comm::Chan(&po);
     let msg = HandleRequest(fn~(move f, ctxt: Ctxt) {
         comm::send(ch, f(ctxt))
     });
diff --git a/src/rustdoc/markdown_writer.rs b/src/rustdoc/markdown_writer.rs
index d0fe7a3840b3..f505f9d0b993 100644
--- a/src/rustdoc/markdown_writer.rs
+++ b/src/rustdoc/markdown_writer.rs
@@ -109,14 +109,14 @@ fn pandoc_writer(
         os::close(pipe_in.out);
 
         let stdout_po = comm::Port();
-        let stdout_ch = comm::Chan(stdout_po);
+        let stdout_ch = comm::Chan(&stdout_po);
         do task::spawn_sched(task::SingleThreaded) {
             comm::send(stdout_ch, readclose(pipe_out.in));
         }
         let stdout = comm::recv(stdout_po);
 
         let stderr_po = comm::Port();
-        let stderr_ch = comm::Chan(stderr_po);
+        let stderr_ch = comm::Chan(&stderr_po);
         do task::spawn_sched(task::SingleThreaded) {
             comm::send(stderr_ch, readclose(pipe_err.in));
         }
@@ -268,10 +268,10 @@ fn write_file(path: &Path, s: ~str) {
 fn future_writer_factory(
 ) -> (WriterFactory, comm::Port<(doc::Page, ~str)>) {
     let markdown_po = comm::Port();
-    let markdown_ch = comm::Chan(markdown_po);
+    let markdown_ch = comm::Chan(&markdown_po);
     let writer_factory = fn~(page: doc::Page) -> Writer {
         let writer_po = comm::Port();
-        let writer_ch = comm::Chan(writer_po);
+        let writer_ch = comm::Chan(&writer_po);
         do task::spawn {
             let (writer, future) = future_writer();
             comm::send(writer_ch, writer);
diff --git a/src/rustdoc/rustdoc.rs b/src/rustdoc/rustdoc.rs
index 50ebef05afbe..b79b6ba21899 100755
--- a/src/rustdoc/rustdoc.rs
+++ b/src/rustdoc/rustdoc.rs
@@ -3,7 +3,8 @@ use doc::Item;
 use pass::Pass;
 use config::Config;
 
-fn main(args: ~[~str]) {
+fn main() {
+    let args = os::args();
 
     if args.contains(&~"-h") || args.contains(&~"--help") {
         config::usage();
diff --git a/src/snapshots.txt b/src/snapshots.txt
index 7464d18247d9..e1469d99d2b7 100644
--- a/src/snapshots.txt
+++ b/src/snapshots.txt
@@ -1,3 +1,19 @@
+S 2012-10-05 937f8f4
+  macos-i386 8b5ddc78b3004e539c6fbe224e492e4a6a1bc867
+  macos-x86_64 03793e0136512c644edfb5f13cc5bb7d67fb24e5
+  freebsd-x86_64 f7f4b402f06b9344fe327a9aa0282aa4ac18fcb0
+  linux-i386 789223cb3db37f6f81f48dff5fa202311fae6c2b
+  linux-x86_64 b5f1ada95528ac5b24d2b3dd3c817b8bcfc3302e
+  winnt-i386 e984437412dc4450931e0bb7ed140652bd66443c
+
+S 2012-10-03 5585514
+  macos-i386 c910d42405e66b444b7870ea66b93e1135776df3
+  macos-x86_64 e0dfa93e8d0d25b91c9684d4f6e92dec521e2d74
+  freebsd-x86_64 228e68ac17ca104554dd8a39a466d20f1b68de24
+  linux-i386 0a2760b24d5bc3cabcc9321b92a08796f95da377
+  linux-x86_64 eace8a5c46f7525355e85b3b570dbd7f4b3b6471
+  winnt-i386 25680d15a358cf4163e08f4e56e54fb497de5eb4
+
 S 2012-10-02 4d30b34
   macos-i386 2bcce3cde8a7e53df202972cda85b0b59ce4e50d 
   macos-x86_64 fc5592828392f9eabe8b51cc59639be6d709cc26
diff --git a/src/test/auxiliary/cci_capture_clause.rs b/src/test/auxiliary/cci_capture_clause.rs
index 2d7404aa1d2c..b25605852571 100644
--- a/src/test/auxiliary/cci_capture_clause.rs
+++ b/src/test/auxiliary/cci_capture_clause.rs
@@ -6,7 +6,7 @@ use comm::*;
 
 fn foo(x: T) -> Port {
     let p = Port();
-    let c = Chan(p);
+    let c = Chan(&p);
     do task::spawn() |copy c, copy x| {
         c.send(x);
     }
diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs
index afd9b2ccc9ca..09a5415823ce 100644
--- a/src/test/bench/core-map.rs
+++ b/src/test/bench/core-map.rs
@@ -142,7 +142,8 @@ fn empty_results() -> Results {
     }
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let num_keys = {
         if args.len() == 2 {
             uint::from_str(args[1]).get()
diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs
index cf44d4783562..6f90a2c99e81 100644
--- a/src/test/bench/core-std.rs
+++ b/src/test/bench/core-std.rs
@@ -8,7 +8,8 @@ use std::map::{Map, HashMap};
 
 use io::{Reader, ReaderUtil};
 
-fn main(++argv: ~[~str]) {
+fn main() {
+    let argv = os::args();
     #macro[
         [#bench[id],
          maybe_run_test(argv, #stringify(id), id)
diff --git a/src/test/bench/core-uint-to-str.rs b/src/test/bench/core-uint-to-str.rs
index 05643536dc0a..4b1e9519715e 100644
--- a/src/test/bench/core-uint-to-str.rs
+++ b/src/test/bench/core-uint-to-str.rs
@@ -1,4 +1,5 @@
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"10000000"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/core-vec-append.rs b/src/test/bench/core-vec-append.rs
index 2b9216876b42..1adbd20f4cde 100644
--- a/src/test/bench/core-vec-append.rs
+++ b/src/test/bench/core-vec-append.rs
@@ -20,7 +20,8 @@ fn collect_dvec(num: uint) -> ~[uint] {
     return dvec::unwrap(move result);
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"50000000"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs
index a34fcc89c048..5acde71c6fd6 100644
--- a/src/test/bench/graph500-bfs.rs
+++ b/src/test/bench/graph500-bfs.rs
@@ -384,7 +384,8 @@ fn validate(edges: ~[(node_id, node_id)],
     true
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"15", ~"48"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/msgsend-pipes-shared.rs b/src/test/bench/msgsend-pipes-shared.rs
index 0a55e7572db9..d60937af13c8 100644
--- a/src/test/bench/msgsend-pipes-shared.rs
+++ b/src/test/bench/msgsend-pipes-shared.rs
@@ -90,7 +90,8 @@ fn run(args: &[~str]) {
     assert result == num_bytes * size;
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"1000000", ~"10000"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/msgsend-pipes.rs b/src/test/bench/msgsend-pipes.rs
index ab67a8c7cb12..e2d115600eff 100644
--- a/src/test/bench/msgsend-pipes.rs
+++ b/src/test/bench/msgsend-pipes.rs
@@ -87,7 +87,8 @@ fn run(args: &[~str]) {
     assert result == num_bytes * size;
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"1000000", ~"8"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs
index ec144b78a10a..f657884eeef8 100644
--- a/src/test/bench/msgsend-ring-mutex-arcs.rs
+++ b/src/test/bench/msgsend-ring-mutex-arcs.rs
@@ -56,7 +56,8 @@ fn thread_ring(i: uint,
     };
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"100", ~"10000"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/msgsend-ring-pipes.rs b/src/test/bench/msgsend-ring-pipes.rs
index 119c2065d6bc..73942d4ddf8f 100644
--- a/src/test/bench/msgsend-ring-pipes.rs
+++ b/src/test/bench/msgsend-ring-pipes.rs
@@ -52,7 +52,8 @@ fn thread_ring(i: uint,
     };
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"100", ~"10000"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs
index 1b857b6caeb8..386496f459d8 100644
--- a/src/test/bench/msgsend-ring-rw-arcs.rs
+++ b/src/test/bench/msgsend-ring-rw-arcs.rs
@@ -56,7 +56,8 @@ fn thread_ring(i: uint,
     };
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"100", ~"10000"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/msgsend-ring.rs b/src/test/bench/msgsend-ring.rs
index 5533aeeeb41b..1dfcd241b83b 100644
--- a/src/test/bench/msgsend-ring.rs
+++ b/src/test/bench/msgsend-ring.rs
@@ -21,7 +21,8 @@ fn thread_ring(i: uint,
     };
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"100", ~"10000"]
     } else if args.len() <= 1u {
@@ -34,7 +35,7 @@ fn main(++args: ~[~str]) {
     let msg_per_task = uint::from_str(args[2]).get();
 
     let num_port = Port();
-    let mut num_chan = Chan(num_port);
+    let mut num_chan = Chan(&num_port);
 
     let start = time::precise_time_s();
 
@@ -43,12 +44,12 @@ fn main(++args: ~[~str]) {
 
     for uint::range(1u, num_tasks) |i| {
         let get_chan = Port();
-        let get_chan_chan = Chan(get_chan);
+        let get_chan_chan = Chan(&get_chan);
 
         let new_future = do future::spawn
             |copy num_chan, move get_chan_chan| {
             let p = Port();
-            get_chan_chan.send(Chan(p));
+            get_chan_chan.send(Chan(&p));
             thread_ring(i, msg_per_task, num_chan,  p)
         };
         futures.push(new_future);
diff --git a/src/test/bench/msgsend.rs b/src/test/bench/msgsend.rs
index fb1e3ae92262..8564adaab729 100644
--- a/src/test/bench/msgsend.rs
+++ b/src/test/bench/msgsend.rs
@@ -57,7 +57,8 @@ fn run(args: ~[~str]) {
     io::stdout().write_str(fmt!("Throughput=%f per sec\n", thruput));
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"1000000", ~"10000"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/shootout-ackermann.rs b/src/test/bench/shootout-ackermann.rs
index 03985a22d112..edccf15a4401 100644
--- a/src/test/bench/shootout-ackermann.rs
+++ b/src/test/bench/shootout-ackermann.rs
@@ -12,7 +12,8 @@ fn ack(m: int, n: int) -> int {
     }
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"12"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/shootout-binarytrees.rs b/src/test/bench/shootout-binarytrees.rs
index 2003c16fe6f7..be58bc0595e9 100644
--- a/src/test/bench/shootout-binarytrees.rs
+++ b/src/test/bench/shootout-binarytrees.rs
@@ -25,7 +25,8 @@ fn bottom_up_tree(arena: &r/arena::Arena,
     return arena.alloc(|| nil);
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"17"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs
index 5c7827f5106d..1e3c51d82548 100644
--- a/src/test/bench/shootout-chameneos-redux.rs
+++ b/src/test/bench/shootout-chameneos-redux.rs
@@ -126,8 +126,8 @@ fn rendezvous(nn: uint, set: ~[color]) {
     let from_creatures_log: comm::Port<~str> = comm::Port();
 
     // these channels will be passed to the creatures so they can talk to us
-    let to_rendezvous     = comm::Chan(from_creatures);
-    let to_rendezvous_log = comm::Chan(from_creatures_log);
+    let to_rendezvous     = comm::Chan(&from_creatures);
+    let to_rendezvous_log = comm::Chan(&from_creatures_log);
 
     // these channels will allow us to talk to each creature by 'name'/index
     let to_creature: ~[comm::Chan>] =
@@ -178,7 +178,8 @@ fn rendezvous(nn: uint, set: ~[color]) {
     io::println(show_number(creatures_met));
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"200000"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/shootout-fannkuchredux.rs b/src/test/bench/shootout-fannkuchredux.rs
index 19dced9aa183..1fbdaddaead8 100644
--- a/src/test/bench/shootout-fannkuchredux.rs
+++ b/src/test/bench/shootout-fannkuchredux.rs
@@ -56,7 +56,8 @@ fn fannkuch(n: int) -> int {
     return flips;
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"10"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/shootout-fasta.rs b/src/test/bench/shootout-fasta.rs
index 0c742e16bfa5..f230664495f1 100644
--- a/src/test/bench/shootout-fasta.rs
+++ b/src/test/bench/shootout-fasta.rs
@@ -70,7 +70,8 @@ fn make_repeat_fasta(wr: io::Writer, id: ~str, desc: ~str, s: ~str, n: int) unsa
 
 fn acid(ch: char, prob: u32) -> aminoacids { return {ch: ch, prob: prob}; }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         // alioth tests k-nucleotide with this data at 25,000,000
         ~[~"", ~"5000000"]
diff --git a/src/test/bench/shootout-fibo.rs b/src/test/bench/shootout-fibo.rs
index 9c39ed4aad1d..548dd1e7d79d 100644
--- a/src/test/bench/shootout-fibo.rs
+++ b/src/test/bench/shootout-fibo.rs
@@ -8,7 +8,8 @@ fn fib(n: int) -> int {
     }
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"40"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs
index 85dcdd32e13d..a68b345cbc55 100644
--- a/src/test/bench/shootout-k-nucleotide-pipes.rs
+++ b/src/test/bench/shootout-k-nucleotide-pipes.rs
@@ -128,7 +128,8 @@ fn make_sequence_processor(sz: uint, from_parent: pipes::Port<~[u8]>,
 }
 
 // given a FASTA file on stdin, process sequence THREE
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
    let rdr = if os::getenv(~"RUST_BENCH").is_some() {
        // FIXME: Using this compile-time env variable is a crummy way to
        // get to this massive data set, but #include_bin chokes on it (#2598)
diff --git a/src/test/bench/shootout-k-nucleotide.rs b/src/test/bench/shootout-k-nucleotide.rs
index 6ba6eb7feadd..e4373d55c179 100644
--- a/src/test/bench/shootout-k-nucleotide.rs
+++ b/src/test/bench/shootout-k-nucleotide.rs
@@ -125,7 +125,8 @@ fn make_sequence_processor(sz: uint, from_parent: comm::Port<~[u8]>,
 }
 
 // given a FASTA file on stdin, process sequence THREE
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
    let rdr = if os::getenv(~"RUST_BENCH").is_some() {
        // FIXME: Using this compile-time env variable is a crummy way to
        // get to this massive data set, but #include_bin chokes on it (#2598)
@@ -141,7 +142,7 @@ fn main(++args: ~[~str]) {
    // initialize each sequence sorter
    let sizes = ~[1u,2u,3u,4u,6u,12u,18u];
    let from_child = vec::map (sizes, |_sz| comm::Port() );
-   let to_parent  = vec::mapi(sizes, |ii, _sz| comm::Chan(from_child[ii]) );
+   let to_parent  = vec::mapi(sizes, |ii, _sz| comm::Chan(&from_child[ii]) );
    let to_child   = vec::mapi(sizes, |ii, sz| {
        let ii = ii;
        let sz = *sz;
diff --git a/src/test/bench/shootout-mandelbrot.rs b/src/test/bench/shootout-mandelbrot.rs
index ee38b957b0cb..b30e04a4ca7d 100644
--- a/src/test/bench/shootout-mandelbrot.rs
+++ b/src/test/bench/shootout-mandelbrot.rs
@@ -103,7 +103,7 @@ impl devnull: io::Writer {
 fn writer(path: ~str, writech: comm::Chan>, size: uint)
 {
     let p: comm::Port = comm::Port();
-    let ch = comm::Chan(p);
+    let ch = comm::Chan(&p);
     comm::send(writech, ch);
     let cout: io::Writer = match path {
         ~"" => {
@@ -151,7 +151,8 @@ fn writer(path: ~str, writech: comm::Chan>, size: uint)
     }
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"4000", ~"10"]
     } else {
@@ -168,7 +169,7 @@ fn main(++args: ~[~str]) {
     else { uint::from_str(args[1]).get() };
 
     let writep = comm::Port();
-    let writech = comm::Chan(writep);
+    let writech = comm::Chan(&writep);
     do task::spawn {
         writer(path, writech, size);
     };
diff --git a/src/test/bench/shootout-nbody.rs b/src/test/bench/shootout-nbody.rs
index e2d3d2a429eb..a1199511907c 100644
--- a/src/test/bench/shootout-nbody.rs
+++ b/src/test/bench/shootout-nbody.rs
@@ -14,7 +14,8 @@ extern mod libc {
     fn sqrt(n: float) -> float;
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"4000000"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/shootout-pfib.rs b/src/test/bench/shootout-pfib.rs
index 90224645f84c..fa97e796bd1c 100644
--- a/src/test/bench/shootout-pfib.rs
+++ b/src/test/bench/shootout-pfib.rs
@@ -81,7 +81,8 @@ fn stress(num_tasks: int) {
     for results.each |r| { future::get(r); }
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"20"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs
index 1f00c419de80..781ecce7ff72 100644
--- a/src/test/bench/shootout-spectralnorm.rs
+++ b/src/test/bench/shootout-spectralnorm.rs
@@ -40,7 +40,8 @@ fn eval_AtA_times_u(u: ~[const float], AtAu: ~[mut float]) {
     eval_At_times_u(v, AtAu);
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"2000"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/shootout-threadring.rs b/src/test/bench/shootout-threadring.rs
index 43229d1db133..7ac45863c5b4 100644
--- a/src/test/bench/shootout-threadring.rs
+++ b/src/test/bench/shootout-threadring.rs
@@ -7,7 +7,7 @@ fn start(+token: int) {
     use iter::*;
 
     let p = comm::Port();
-    let mut ch = comm::Chan(p);
+    let mut ch = comm::Chan(&p);
     for int::range(2, n_threads + 1) |i| {
         let id = n_threads + 2 - i;
         let to_child = do task::spawn_listener:: |p, copy ch| {
@@ -37,7 +37,8 @@ fn roundtrip(id: int, p: comm::Port, ch: comm::Chan) {
     }
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"2000000"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/std-smallintmap.rs b/src/test/bench/std-smallintmap.rs
index 3fdbe028b708..2ac651862213 100644
--- a/src/test/bench/std-smallintmap.rs
+++ b/src/test/bench/std-smallintmap.rs
@@ -17,7 +17,8 @@ fn check_sequential(min: uint, max: uint, map: SmallIntMap) {
     }
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"100000", ~"100"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/sudoku.rs b/src/test/bench/sudoku.rs
index 8f4e509e6294..2e8ef0bac582 100644
--- a/src/test/bench/sudoku.rs
+++ b/src/test/bench/sudoku.rs
@@ -126,7 +126,8 @@ fn write_grid(f: io::Writer, g: grid_t) {
      }
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let grid = if vec::len(args) == 1u {
         // FIXME create sudoku inline since nested vec consts dont work yet
         // (#571)
diff --git a/src/test/bench/task-perf-jargon-metal-smoke.rs b/src/test/bench/task-perf-jargon-metal-smoke.rs
index 53735cdbb16a..2055993d441e 100644
--- a/src/test/bench/task-perf-jargon-metal-smoke.rs
+++ b/src/test/bench/task-perf-jargon-metal-smoke.rs
@@ -23,7 +23,8 @@ fn child_generation(gens_left: uint, -c: pipes::Chan<()>) {
     }
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"100000"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/task-perf-linked-failure.rs b/src/test/bench/task-perf-linked-failure.rs
index 1ba92bfadee8..a692b2f3011e 100644
--- a/src/test/bench/task-perf-linked-failure.rs
+++ b/src/test/bench/task-perf-linked-failure.rs
@@ -11,7 +11,7 @@
 // Doesn't return until all such tasks are ready, but doesn't block forever itself.
 fn grandchild_group(num_tasks: uint) {
     let po = comm::Port();
-    let ch = comm::Chan(po);
+    let ch = comm::Chan(&po);
 
     for num_tasks.times {
         do task::spawn { // linked
@@ -37,7 +37,8 @@ fn spawn_supervised_blocking(myname: &str, +f: fn~()) {
     assert x == task::Success;
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"100000"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/task-perf-one-million.rs b/src/test/bench/task-perf-one-million.rs
index c9d4fb6b4d87..7a30c5e2325b 100644
--- a/src/test/bench/task-perf-one-million.rs
+++ b/src/test/bench/task-perf-one-million.rs
@@ -8,7 +8,7 @@ enum msg {
 
 fn calc(children: uint, parent_ch: comm::Chan) {
     let port = comm::Port();
-    let chan = comm::Chan(port);
+    let chan = comm::Chan(&port);
     let mut child_chs = ~[];
     let mut sum = 0;
 
@@ -48,7 +48,8 @@ fn calc(children: uint, parent_ch: comm::Chan) {
     comm::send(parent_ch, done(sum + 1));
 }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"100000"]
     } else if args.len() <= 1u {
@@ -59,7 +60,7 @@ fn main(++args: ~[~str]) {
 
     let children = uint::from_str(args[1]).get();
     let port = comm::Port();
-    let chan = comm::Chan(port);
+    let chan = comm::Chan(&port);
     do task::spawn {
         calc(children, chan);
     };
diff --git a/src/test/bench/task-perf-spawnalot.rs b/src/test/bench/task-perf-spawnalot.rs
index 48af1dcd5049..dfa53c3328b5 100644
--- a/src/test/bench/task-perf-spawnalot.rs
+++ b/src/test/bench/task-perf-spawnalot.rs
@@ -8,7 +8,8 @@ fn f(&&n: uint) {
 
 fn g() { }
 
-fn main(++args: ~[~str]) {
+fn main() {
+    let args = os::args();
     let args = if os::getenv(~"RUST_BENCH").is_some() {
         ~[~"", ~"400"]
     } else if args.len() <= 1u {
diff --git a/src/test/bench/task-perf-word-count-generic.rs b/src/test/bench/task-perf-word-count-generic.rs
index 626123665243..30add8c730c7 100644
--- a/src/test/bench/task-perf-word-count-generic.rs
+++ b/src/test/bench/task-perf-word-count-generic.rs
@@ -10,8 +10,6 @@
 
 // xfail-pretty
 
-#[legacy_modes];
-
 extern mod std;
 
 use option = option;
@@ -43,7 +41,7 @@ trait word_reader {
 type joinable_task = Port<()>;
 fn spawn_joinable(+f: fn~()) -> joinable_task {
     let p = Port();
-    let c = Chan(p);
+    let c = Chan(&p);
     do task::spawn() |move f| {
         f();
         c.send(());
@@ -70,18 +68,18 @@ fn map(f: fn~() -> word_reader, emit: map_reduce::putter<~str, int>) {
     let f = f();
     loop {
         match f.read_word() {
-          Some(w) => { emit(w, 1); }
+          Some(w) => { emit(&w, 1); }
           None => { break; }
         }
     }
 }
 
-fn reduce(&&word: ~str, get: map_reduce::getter) {
+fn reduce(word: &~str, get: map_reduce::getter) {
     let mut count = 0;
 
     loop { match get() { Some(_) => { count += 1; } None => { break; } } }
 
-    io::println(fmt!("%s\t%?", word, count));
+    io::println(fmt!("%s\t%?", *word, count));
 }
 
 struct box {
@@ -116,13 +114,13 @@ mod map_reduce {
     export reducer;
     export map_reduce;
 
-    type putter = fn(K, V);
+    type putter = fn(&K, V);
 
     type mapper = fn~(K1, putter);
 
     type getter = fn() -> Option;
 
-    type reducer = fn~(K, getter);
+    type reducer = fn~(&K, getter);
 
     enum ctrl_proto {
         find_reducer(K, Chan>>),
@@ -145,9 +143,9 @@ mod map_reduce {
 
     fn start_mappers(
-        map: mapper,
-        &ctrls: ~[ctrl_proto::server::open],
-        inputs: ~[K1])
+        map: &mapper,
+        ctrls: &mut ~[ctrl_proto::server::open],
+        inputs: &~[K1])
         -> ~[joinable_task]
     {
         let mut tasks = ~[];
@@ -155,7 +153,8 @@ mod map_reduce {
             let (ctrl, ctrl_server) = ctrl_proto::init();
             let ctrl = box(ctrl);
             let i = copy *i;
-            tasks.push(spawn_joinable(|move i| map_task(map, ctrl, i)));
+            let m = copy *map;
+            tasks.push(spawn_joinable(|move i| map_task(m, &ctrl, i)));
             ctrls.push(ctrl_server);
         }
         return tasks;
@@ -163,20 +162,22 @@ mod map_reduce {
 
     fn map_task(
         map: mapper,
-        ctrl: box>,
+        ctrl: &box>,
         input: K1)
     {
         // log(error, "map_task " + input);
-        let intermediates = map::HashMap();
+        let intermediates: HashMap>>
+            = map::HashMap();
 
-        do map(input) |key, val| {
+        do map(input) |key: &K2, val| {
             let mut c = None;
-            let found = intermediates.find(key);
+            let found: Option>>
+                = intermediates.find(*key);
             match found {
               Some(_c) => { c = Some(_c); }
               None => {
                 do ctrl.swap |ctrl| {
-                    let ctrl = ctrl_proto::client::find_reducer(ctrl, key);
+                    let ctrl = ctrl_proto::client::find_reducer(ctrl, *key);
                     match pipes::recv(ctrl) {
                       ctrl_proto::reducer(c_, ctrl) => {
                         c = Some(c_);
@@ -184,7 +185,7 @@ mod map_reduce {
                       }
                     }
                 }
-                intermediates.insert(key, c.get());
+                intermediates.insert(*key, c.get());
                 send(c.get(), addref);
               }
             }
@@ -200,21 +201,21 @@ mod map_reduce {
     }
 
     fn reduce_task(
-        reduce: reducer, 
+        reduce: ~reducer, 
         key: K,
         out: Chan>>)
     {
         let p = Port();
 
-        send(out, Chan(p));
+        send(out, Chan(&p));
 
         let mut ref_count = 0;
         let mut is_done = false;
 
         fn get(p: Port>,
-                             &ref_count: int, &is_done: bool)
+                             ref_count: &mut int, is_done: &mut bool)
            -> Option {
-            while !is_done || ref_count > 0 {
+            while !*is_done || *ref_count > 0 {
                 match recv(p) {
                   emit_val(v) => {
                     // error!("received %d", v);
@@ -222,16 +223,16 @@ mod map_reduce {
                   }
                   done => {
                     // error!("all done");
-                    is_done = true;
+                    *is_done = true;
                   }
-                  addref => { ref_count += 1; }
-                  release => { ref_count -= 1; }
+                  addref => { *ref_count += 1; }
+                  release => { *ref_count -= 1; }
                 }
             }
             return None;
         }
 
-        reduce(key, || get(p, ref_count, is_done) );
+        (*reduce)(&key, || get(p, &mut ref_count, &mut is_done) );
     }
 
     fn map_reduce(
@@ -245,7 +246,7 @@ mod map_reduce {
         // to do the rest.
 
         let reducers = map::HashMap();
-        let mut tasks = start_mappers(map, ctrl, inputs);
+        let mut tasks = start_mappers(&map, &mut ctrl, &inputs);
         let mut num_mappers = vec::len(inputs) as int;
 
         while num_mappers > 0 {
@@ -268,9 +269,9 @@ mod map_reduce {
                   None => {
                     // log(error, "creating new reducer for " + k);
                     let p = Port();
-                    let ch = Chan(p);
+                    let ch = Chan(&p);
                     let r = reduce, kk = k;
-                    tasks.push(spawn_joinable(|| reduce_task(r, kk, ch) ));
+                    tasks.push(spawn_joinable(|| reduce_task(~r, kk, ch) ));
                     c = recv(p);
                     reducers.insert(k, c);
                   }
@@ -288,7 +289,8 @@ mod map_reduce {
     }
 }
 
-fn main(++argv: ~[~str]) {
+fn main() {
+    let argv = os::args();
     if vec::len(argv) < 2u && !os::getenv(~"RUST_BENCH").is_some() {
         let out = io::stdout();
 
diff --git a/src/test/compile-fail/bad-main.rs b/src/test/compile-fail/bad-main.rs
index 79364a1bb520..3bd1f47307b7 100644
--- a/src/test/compile-fail/bad-main.rs
+++ b/src/test/compile-fail/bad-main.rs
@@ -1,3 +1,3 @@
-// error-pattern:expected `extern fn(++v: ~[~str])
+// error-pattern:expected `fn()
 
 fn main(x: int) { }
diff --git a/src/test/compile-fail/borrowck-lend-args.rs b/src/test/compile-fail/borrowck-lend-args.rs
index 3cb7009ee270..79f52b93612a 100644
--- a/src/test/compile-fail/borrowck-lend-args.rs
+++ b/src/test/compile-fail/borrowck-lend-args.rs
@@ -4,8 +4,8 @@ fn borrow_from_arg_imm_ref(&&v: ~int) {
     borrow(v);
 }
 
-fn borrow_from_arg_mut_ref(&v: ~int) {
-    borrow(v); //~ ERROR illegal borrow unless pure
+fn borrow_from_arg_mut_ref(v: &mut ~int) {
+    borrow(*v); //~ ERROR illegal borrow unless pure
     //~^ NOTE impure due to access to impure function
 }
 
diff --git a/src/test/compile-fail/deprecated-mode-fn-arg.rs b/src/test/compile-fail/deprecated-mode-fn-arg.rs
index 5afffb59dfc3..bb466e2c00b8 100644
--- a/src/test/compile-fail/deprecated-mode-fn-arg.rs
+++ b/src/test/compile-fail/deprecated-mode-fn-arg.rs
@@ -1,9 +1,9 @@
 #[forbid(deprecated_mode)];
 
-fn foo(_f: fn(&i: int)) { //~ ERROR explicit mode
+fn foo(_f: fn(&i: int)) { //~ ERROR by-mutable-reference mode
 }
 
-type Bar = fn(&i: int); //~ ERROR explicit mode
+type Bar = fn(&i: int); //~ ERROR by-mutable-reference mode
 
 fn main() {
 }
\ No newline at end of file
diff --git a/src/test/compile-fail/issue-3096-2.rs b/src/test/compile-fail/issue-3096-2.rs
index 03e13f67a9a9..dd8f341b9355 100644
--- a/src/test/compile-fail/issue-3096-2.rs
+++ b/src/test/compile-fail/issue-3096-2.rs
@@ -1,6 +1,6 @@
 enum bottom { } 
 
 fn main() {
-    let x = ptr::p2::addr_of(&()) as *bottom;
+    let x = ptr::addr_of(&()) as *bottom;
     match x { } //~ ERROR non-exhaustive patterns
 }
diff --git a/src/test/compile-fail/issue-511.rs b/src/test/compile-fail/issue-511.rs
index a3498dd19686..02a3082dc10d 100644
--- a/src/test/compile-fail/issue-511.rs
+++ b/src/test/compile-fail/issue-511.rs
@@ -1,11 +1,11 @@
 extern mod std;
 use cmp::Eq;
 
-fn f(&o: Option) {
-    assert o == option::None;
+fn f(o: &mut Option) {
+    assert *o == option::None;
 }
 
 fn main() {
-    f::(option::None);
+    f::(&mut option::None);
     //~^ ERROR illegal borrow: creating mutable alias to static item
 }
diff --git a/src/test/compile-fail/liveness-dead.rs b/src/test/compile-fail/liveness-dead.rs
index a115d7c4e340..834457940bec 100644
--- a/src/test/compile-fail/liveness-dead.rs
+++ b/src/test/compile-fail/liveness-dead.rs
@@ -1,5 +1,5 @@
-fn f1(&x: int) {
-    x = 1; // no error
+fn f1(x: &mut int) {
+    *x = 1; // no error
 }
 
 fn f2() {
diff --git a/src/test/compile-fail/liveness-move-from-args.rs b/src/test/compile-fail/liveness-move-from-args.rs
index 27e7e51b4054..27e9d3b60dc9 100644
--- a/src/test/compile-fail/liveness-move-from-args.rs
+++ b/src/test/compile-fail/liveness-move-from-args.rs
@@ -4,10 +4,6 @@ fn from_by_value_arg(++x: int) {
     take(x);  //~ ERROR illegal move from argument `x`, which is not copy or move mode
 }
 
-fn from_by_mut_ref_arg(&x: int) {
-    take(x);  //~ ERROR illegal move from argument `x`, which is not copy or move mode
-}
-
 fn from_by_ref_arg(&&x: int) {
     take(x);  //~ ERROR illegal move from argument `x`, which is not copy or move mode
 }
diff --git a/src/test/compile-fail/liveness-unused.rs b/src/test/compile-fail/liveness-unused.rs
index 7db02897112d..8b2fef7cd350 100644
--- a/src/test/compile-fail/liveness-unused.rs
+++ b/src/test/compile-fail/liveness-unused.rs
@@ -2,7 +2,7 @@ fn f1(x: int) {
     //~^ WARNING unused variable: `x`
 }
 
-fn f1b(&x: int) {
+fn f1b(x: &mut int) {
     //~^ WARNING unused variable: `x`
 }
 
diff --git a/src/test/compile-fail/mutable-arguments.rs b/src/test/compile-fail/mutable-arguments.rs
index 4fcb73e8516c..d84c9401e257 100644
--- a/src/test/compile-fail/mutable-arguments.rs
+++ b/src/test/compile-fail/mutable-arguments.rs
@@ -1,28 +1,28 @@
 // Note: it would be nice to give fewer warnings in these cases.
 
-fn mutate_by_mut_ref(&x: uint) {
-    x = 0u;
+fn mutate_by_mut_ref(x: &mut uint) {
+    *x = 0;
 }
 
 fn mutate_by_ref(&&x: uint) {
     //~^ WARNING unused variable: `x`
-    x = 0u; //~ ERROR assigning to argument
+    x = 0; //~ ERROR assigning to argument
 }
 
 fn mutate_by_val(++x: uint) {
     //~^ WARNING unused variable: `x`
-    x = 0u; //~ ERROR assigning to argument
+    x = 0; //~ ERROR assigning to argument
 }
 
 fn mutate_by_copy(+x: uint) {
     //~^ WARNING unused variable: `x`
-    x = 0u; //~ ERROR assigning to argument
+    x = 0; //~ ERROR assigning to argument
     //~^ WARNING value assigned to `x` is never read
 }
 
 fn mutate_by_move(-x: uint) {
     //~^ WARNING unused variable: `x`
-    x = 0u; //~ ERROR assigning to argument
+    x = 0; //~ ERROR assigning to argument
     //~^ WARNING value assigned to `x` is never read
 }
 
diff --git a/src/test/compile-fail/non-copyable-void.rs b/src/test/compile-fail/non-copyable-void.rs
index a00dd7afd6df..eaba1d861196 100644
--- a/src/test/compile-fail/non-copyable-void.rs
+++ b/src/test/compile-fail/non-copyable-void.rs
@@ -1,5 +1,5 @@
 fn main() {
-    let x : *~[int] = ptr::p2::addr_of(&~[1,2,3]);
+    let x : *~[int] = ptr::addr_of(&~[1,2,3]);
     let y : *libc::c_void = x as *libc::c_void;
     unsafe {
         let _z = *y;
diff --git a/src/test/compile-fail/unnamed_argument_mode.rs b/src/test/compile-fail/unnamed_argument_mode.rs
index 36e6edc96f99..77d40aae6a27 100644
--- a/src/test/compile-fail/unnamed_argument_mode.rs
+++ b/src/test/compile-fail/unnamed_argument_mode.rs
@@ -1,11 +1,8 @@
-//error-pattern: mismatched types
+//error-pattern: by-mutable-reference mode
 
 fn bad(&a: int) {
 }
 
-// unnamed argument &int is now parsed x: &int
-// it's not parsed &x: int anymore
-
 fn called(f: fn(&int)) {
 }
 
diff --git a/src/test/compile-fail/unsendable-class.rs b/src/test/compile-fail/unsendable-class.rs
index a954f6e6e3b2..a47a8b76e56a 100644
--- a/src/test/compile-fail/unsendable-class.rs
+++ b/src/test/compile-fail/unsendable-class.rs
@@ -16,6 +16,6 @@ fn foo(i:int, j: @~str) -> foo {
 fn main() {
   let cat = ~"kitty";
   let po = comm::Port();         //~ ERROR missing `send`
-  let ch = comm::Chan(po);       //~ ERROR missing `send`
+  let ch = comm::Chan(&po);       //~ ERROR missing `send`
   comm::send(ch, foo(42, @cat)); //~ ERROR missing `send`
 }
diff --git a/src/test/compile-fail/vtable-res-trait-param.rs b/src/test/compile-fail/vtable-res-trait-param.rs
index 550be31d1a4a..8032c199bf09 100644
--- a/src/test/compile-fail/vtable-res-trait-param.rs
+++ b/src/test/compile-fail/vtable-res-trait-param.rs
@@ -14,7 +14,7 @@ impl int: TraitB {
 
 fn call_it(b: B)  -> int {
     let y = 4u;
-    b.gimme_an_a(y) //~ ERROR failed to find an implementation of trait @TraitA for uint
+    b.gimme_an_a(y) //~ ERROR failed to find an implementation of trait @TraitA
 }
 
 fn main() {
diff --git a/src/test/run-fail/port-type.rs b/src/test/run-fail/port-type.rs
index 7ea778bd1907..30714413c537 100644
--- a/src/test/run-fail/port-type.rs
+++ b/src/test/run-fail/port-type.rs
@@ -9,7 +9,7 @@ fn echo(c: Chan, oc: Chan>) {
     // Tests that the type argument in port gets
     // visited
     let p = Port::();
-    send(oc, Chan(p));
+    send(oc, Chan(&p));
 
     let x = recv(p);
     send(c, x);
diff --git a/src/test/run-pass/argument-passing.rs b/src/test/run-pass/argument-passing.rs
index 2a8398634551..e8aaf88374f9 100644
--- a/src/test/run-pass/argument-passing.rs
+++ b/src/test/run-pass/argument-passing.rs
@@ -1,10 +1,10 @@
 // xfail-fast
 #[legacy_modes];
 
-fn f1(a: {mut x: int}, &b: int, -c: int) -> int {
-    let r = a.x + b + c;
+fn f1(a: {mut x: int}, b: &mut int, -c: int) -> int {
+    let r = a.x + *b + c;
     a.x = 0;
-    b = 10;
+    *b = 10;
     return r;
 }
 
@@ -12,7 +12,7 @@ fn f2(a: int, f: fn(int)) -> int { f(1); return a; }
 
 fn main() {
     let mut a = {mut x: 1}, b = 2, c = 3;
-    assert (f1(a, b, c) == 6);
+    assert (f1(a, &mut b, c) == 6);
     assert (a.x == 0);
     assert (b == 10);
     assert (f2(a.x, |x| a.x = 50 ) == 0);
diff --git a/src/test/run-pass/argv.rs b/src/test/run-pass/argv.rs
deleted file mode 100644
index a697e0f73dcb..000000000000
--- a/src/test/run-pass/argv.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-fn main(++args: ~[~str]) {
-    let vs: ~[~str] = ~[~"hi", ~"there", ~"this", ~"is", ~"a", ~"vec"];
-    let vvs: ~[~[~str]] = ~[args, vs];
-    for vvs.each |vs| { for vs.each |s| { log(debug, *s); } }
-}
diff --git a/src/test/run-pass/basic-1.rs b/src/test/run-pass/basic-1.rs
index 8f467e24e1b7..1f0bfe93ab28 100644
--- a/src/test/run-pass/basic-1.rs
+++ b/src/test/run-pass/basic-1.rs
@@ -10,7 +10,7 @@ fn a(c: Chan) { send(c, 10); }
 
 fn main() {
     let p = Port();
-    let ch = Chan(p);
+    let ch = Chan(&p);
     task::spawn(|| a(ch) );
     task::spawn(|| a(ch) );
     let mut n: int = 0;
diff --git a/src/test/run-pass/basic-2.rs b/src/test/run-pass/basic-2.rs
index b5130a100278..7a81bfc3fc52 100644
--- a/src/test/run-pass/basic-2.rs
+++ b/src/test/run-pass/basic-2.rs
@@ -10,7 +10,7 @@ fn a(c: Chan) { debug!("task a0"); debug!("task a1"); send(c, 10); }
 
 fn main() {
     let p = Port();
-    let ch = Chan(p);
+    let ch = Chan(&p);
     task::spawn(|| a(ch) );
     task::spawn(|| b(ch) );
     let mut n: int = 0;
diff --git a/src/test/run-pass/basic.rs b/src/test/run-pass/basic.rs
index a72c9058d106..6f8fa6e3e70f 100644
--- a/src/test/run-pass/basic.rs
+++ b/src/test/run-pass/basic.rs
@@ -29,7 +29,7 @@ fn main() {
     let mut n: int = 2 + 3 * 7;
     let s: ~str = ~"hello there";
     let p = comm::Port();
-    let ch = comm::Chan(p);
+    let ch = comm::Chan(&p);
     task::spawn(|| a(ch) );
     task::spawn(|| b(ch) );
     let mut x: int = 10;
diff --git a/src/test/run-pass/capture_nil.rs b/src/test/run-pass/capture_nil.rs
index 41359ceec185..60f243077096 100644
--- a/src/test/run-pass/capture_nil.rs
+++ b/src/test/run-pass/capture_nil.rs
@@ -17,7 +17,7 @@ use comm::*;
 
 fn foo(&&x: ()) -> Port<()> {
     let p = Port();
-    let c = Chan(p);
+    let c = Chan(&p);
     do task::spawn() |copy c, copy x| {
         c.send(x);
     }
diff --git a/src/test/run-pass/chan-leak.rs b/src/test/run-pass/chan-leak.rs
index b0a27a9a97e5..f834b1b35195 100644
--- a/src/test/run-pass/chan-leak.rs
+++ b/src/test/run-pass/chan-leak.rs
@@ -12,7 +12,7 @@ type ctx = Chan;
 
 fn request_task(c: Chan) {
     let p = Port();
-    send(c, Chan(p));
+    send(c, Chan(&p));
     let mut req: request;
     req = recv(p);
     // Need to drop req before receiving it again
@@ -21,7 +21,7 @@ fn request_task(c: Chan) {
 
 fn new_cx() -> ctx {
     let p = Port();
-    let ch = Chan(p);
+    let ch = Chan(&p);
     let t = task::spawn(|| request_task(ch) );
     let mut cx: ctx;
     cx = recv(p);
@@ -32,6 +32,6 @@ fn main() {
     let cx = new_cx();
 
     let p = Port::();
-    send(cx, close(Chan(p)));
+    send(cx, close(Chan(&p)));
     send(cx, quit);
 }
diff --git a/src/test/run-pass/comm.rs b/src/test/run-pass/comm.rs
index b41152f31588..003b7c830934 100644
--- a/src/test/run-pass/comm.rs
+++ b/src/test/run-pass/comm.rs
@@ -7,7 +7,7 @@ use comm::recv;
 
 fn main() {
     let p = comm::Port();
-    let ch = comm::Chan(p);
+    let ch = comm::Chan(&p);
     let t = task::spawn(|| child(ch) );
     let y = recv(p);
     error!("received");
diff --git a/src/test/run-pass/command-line-args.rs b/src/test/run-pass/command-line-args.rs
deleted file mode 100644
index 242392ccbe17..000000000000
--- a/src/test/run-pass/command-line-args.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-fn main(++args: ~[~str]) { log(debug, args[0]); }
diff --git a/src/test/run-pass/decl-with-recv.rs b/src/test/run-pass/decl-with-recv.rs
index 07ce5cb63ac6..b594e5334c46 100644
--- a/src/test/run-pass/decl-with-recv.rs
+++ b/src/test/run-pass/decl-with-recv.rs
@@ -8,7 +8,7 @@ use comm::recv;
 
 fn main() {
     let po = Port();
-    let ch = Chan(po);
+    let ch = Chan(&po);
     send(ch, 10);
     let i = recv(po);
     assert (i == 10);
diff --git a/src/test/run-pass/fn-bare-assign.rs b/src/test/run-pass/fn-bare-assign.rs
index ae6b1a1079ff..71996552d0cc 100644
--- a/src/test/run-pass/fn-bare-assign.rs
+++ b/src/test/run-pass/fn-bare-assign.rs
@@ -1,15 +1,15 @@
-fn f(i: int, &called: bool) {
+fn f(i: int, called: &mut bool) {
     assert i == 10;
-    called = true;
+    *called = true;
 }
 
-fn g(f: extern fn(int, &v: bool), &called: bool) {
+fn g(f: extern fn(int, v: &mut bool), called: &mut bool) {
     f(10, called);
 }
 
 fn main() {
     let mut called = false;
     let h = f;
-    g(h, called);
+    g(h, &mut called);
     assert called == true;
 }
\ No newline at end of file
diff --git a/src/test/run-pass/hashmap-memory.rs b/src/test/run-pass/hashmap-memory.rs
index 24163cfa5664..50b88693f39f 100644
--- a/src/test/run-pass/hashmap-memory.rs
+++ b/src/test/run-pass/hashmap-memory.rs
@@ -47,7 +47,7 @@ mod map_reduce {
               None => {
                 let p = Port();
                 error!("sending find_reducer");
-                send(ctrl, find_reducer(str::to_bytes(key), Chan(p)));
+                send(ctrl, find_reducer(str::to_bytes(key), Chan(&p)));
                 error!("receiving");
                 c = recv(p);
                 log(error, c);
@@ -70,7 +70,7 @@ mod map_reduce {
 
         reducers = map::HashMap();
 
-        start_mappers(Chan(ctrl), inputs);
+        start_mappers(Chan(&ctrl), inputs);
 
         let mut num_mappers = vec::len(inputs) as int;
 
diff --git a/src/test/run-pass/intrinsic-move-val.rs b/src/test/run-pass/intrinsic-move-val.rs
index b7f2115f45da..683321aac3d0 100644
--- a/src/test/run-pass/intrinsic-move-val.rs
+++ b/src/test/run-pass/intrinsic-move-val.rs
@@ -1,13 +1,13 @@
 #[abi = "rust-intrinsic"]
 extern mod rusti {
     #[legacy_exports];
-    fn move_val_init(&dst: T, -src: T);
-    fn move_val(&dst: T, -src: T);
+    fn move_val_init(dst: &mut T, -src: T);
+    fn move_val(dst: &mut T, -src: T);
 }
 
 fn main() {
     let mut x = @1;
     let mut y = @2;
-    rusti::move_val(y, x);
+    rusti::move_val(&mut y, x);
     assert *y == 1;
 }
\ No newline at end of file
diff --git a/src/test/run-pass/issue-507.rs b/src/test/run-pass/issue-507.rs
index 447a892f3390..0baa0aca7ade 100644
--- a/src/test/run-pass/issue-507.rs
+++ b/src/test/run-pass/issue-507.rs
@@ -20,7 +20,7 @@ fn child(c: Chan) {
 
 fn main() {
     let p = comm::Port();
-    let ch = Chan(p);
+    let ch = Chan(&p);
 
     task::spawn(|| child(ch) );
 
diff --git a/src/test/run-pass/issue-687.rs b/src/test/run-pass/issue-687.rs
index 6d9dc8216e1a..4ed94c577849 100644
--- a/src/test/run-pass/issue-687.rs
+++ b/src/test/run-pass/issue-687.rs
@@ -14,7 +14,7 @@ fn producer(c: Chan<~[u8]>) {
 
 fn packager(cb: Chan>, msg: Chan) {
     let p: Port<~[u8]> = Port();
-    send(cb, Chan(p));
+    send(cb, Chan(&p));
     loop {
         debug!("waiting for bytes");
         let data = recv(p);
@@ -35,9 +35,9 @@ fn packager(cb: Chan>, msg: Chan) {
 
 fn main() {
     let p: Port = Port();
-    let ch = Chan(p);
+    let ch = Chan(&p);
     let recv_reader: Port> = Port();
-    let recv_reader_chan = Chan(recv_reader);
+    let recv_reader_chan = Chan(&recv_reader);
     let pack = task::spawn(|| packager(recv_reader_chan, ch) );
 
     let source_chan: Chan<~[u8]> = recv(recv_reader);
diff --git a/src/test/run-pass/issue-783.rs b/src/test/run-pass/issue-783.rs
index a9c6fed8ecae..50fadefa4643 100644
--- a/src/test/run-pass/issue-783.rs
+++ b/src/test/run-pass/issue-783.rs
@@ -6,10 +6,10 @@ fn a() {
     fn doit() {
         fn b(c: Chan>) {
             let p = Port();
-            send(c, Chan(p));
+            send(c, Chan(&p));
         }
         let p = Port();
-        let ch = Chan(p);
+        let ch = Chan(&p);
         spawn(|| b(ch) );
         recv(p);
     }
diff --git a/src/test/run-pass/ivec-tag.rs b/src/test/run-pass/ivec-tag.rs
index bfcba52790b3..b92d20bbe40c 100644
--- a/src/test/run-pass/ivec-tag.rs
+++ b/src/test/run-pass/ivec-tag.rs
@@ -13,7 +13,7 @@ fn producer(c: Chan<~[u8]>) {
 
 fn main() {
     let p: Port<~[u8]> = Port();
-    let ch = Chan(p);
+    let ch = Chan(&p);
     let prod = task::spawn(|| producer(ch) );
 
     let data: ~[u8] = recv(p);
diff --git a/src/test/run-pass/lazy-and-or.rs b/src/test/run-pass/lazy-and-or.rs
index 7ad71854dc42..3e84c9f6f726 100644
--- a/src/test/run-pass/lazy-and-or.rs
+++ b/src/test/run-pass/lazy-and-or.rs
@@ -1,12 +1,12 @@
 
 
-fn incr(&x: int) -> bool { x += 1; assert (false); return false; }
+fn incr(x: &mut int) -> bool { *x += 1; assert (false); return false; }
 
 fn main() {
     let x = 1 == 2 || 3 == 3;
     assert (x);
     let mut y: int = 10;
-    log(debug, x || incr(y));
+    log(debug, x || incr(&mut y));
     assert (y == 10);
     if true && x { assert (true); } else { assert (false); }
 }
diff --git a/src/test/run-pass/lazychan.rs b/src/test/run-pass/lazychan.rs
index 1446ebc94935..06e89a298a97 100644
--- a/src/test/run-pass/lazychan.rs
+++ b/src/test/run-pass/lazychan.rs
@@ -5,7 +5,7 @@ use comm::*;
 
 fn main() {
     let p = Port();
-    let ch = Chan(p);
+    let ch = Chan(&p);
     let mut y: int;
 
     task::spawn(|| child(ch) );
diff --git a/src/test/run-pass/main-ivec.rs b/src/test/run-pass/main-ivec.rs
deleted file mode 100644
index 39bbd07c66b1..000000000000
--- a/src/test/run-pass/main-ivec.rs
+++ /dev/null
@@ -1 +0,0 @@
-fn main(++args: ~[~str]) { for args.each |s| { log(debug, *s); } }
diff --git a/src/test/run-pass/many.rs b/src/test/run-pass/many.rs
index 2362f683e5e8..83ebc0ef844b 100644
--- a/src/test/run-pass/many.rs
+++ b/src/test/run-pass/many.rs
@@ -7,7 +7,7 @@ fn sub(parent: comm::Chan, id: int) {
         comm::send(parent, 0);
     } else {
         let p = comm::Port();
-        let ch = comm::Chan(p);
+        let ch = comm::Chan(&p);
         let child = task::spawn(|| sub(ch, id - 1) );
         let y = comm::recv(p);
         comm::send(parent, y + 1);
@@ -16,7 +16,7 @@ fn sub(parent: comm::Chan, id: int) {
 
 fn main() {
     let p = comm::Port();
-    let ch = comm::Chan(p);
+    let ch = comm::Chan(&p);
     let child = task::spawn(|| sub(ch, 200) );
     let y = comm::recv(p);
     debug!("transmission complete");
diff --git a/src/test/run-pass/mutable-alias-vec.rs b/src/test/run-pass/mutable-alias-vec.rs
index e54197ccc6b5..d5b1eef993e1 100644
--- a/src/test/run-pass/mutable-alias-vec.rs
+++ b/src/test/run-pass/mutable-alias-vec.rs
@@ -3,13 +3,13 @@
 // -*- rust -*-
 extern mod std;
 
-fn grow(&v: ~[int]) { v += ~[1]; }
+fn grow(v: &mut ~[int]) { *v += ~[1]; }
 
 fn main() {
     let mut v: ~[int] = ~[];
-    grow(v);
-    grow(v);
-    grow(v);
+    grow(&mut v);
+    grow(&mut v);
+    grow(&mut v);
     let len = vec::len::(v);
     log(debug, len);
     assert (len == 3 as uint);
diff --git a/src/test/run-pass/reexport-star.rs b/src/test/run-pass/reexport-star.rs
index 1709ddc70f2d..daa8d9d67964 100644
--- a/src/test/run-pass/reexport-star.rs
+++ b/src/test/run-pass/reexport-star.rs
@@ -1,3 +1,6 @@
+// xfail-pretty
+// FIXME #3654
+
 mod a {
     pub fn f() {}
     pub fn g() {}
diff --git a/src/test/run-pass/rt-circular-buffer.rs b/src/test/run-pass/rt-circular-buffer.rs
index 2f5245f7bc4c..2af5535ad280 100644
--- a/src/test/run-pass/rt-circular-buffer.rs
+++ b/src/test/run-pass/rt-circular-buffer.rs
@@ -18,7 +18,7 @@ type record = {val1: u32, val2: u32, val3: u32};
 // assertions.
 fn test_init() {
     let myport = Port();
-    let mychan = Chan(myport);
+    let mychan = Chan(&myport);
     let val: record = {val1: 0u32, val2: 0u32, val3: 0u32};
     send(mychan, val);
 }
@@ -28,7 +28,7 @@ fn test_init() {
 // Don't trigger any assertions.
 fn test_grow() {
     let myport = Port();
-    let mychan = Chan(myport);
+    let mychan = Chan(&myport);
     for uint::range(0u, 100u) |i| {
         let val: record = {val1: 0u32, val2: 0u32, val3: 0u32};
         comm::send(mychan, val);
@@ -39,14 +39,14 @@ fn test_grow() {
 // Don't allow the buffer to shrink below it's original size
 fn test_shrink1() {
     let myport = Port();
-    let mychan = Chan(myport);
+    let mychan = Chan(&myport);
     send(mychan, 0i8);
     let x = recv(myport);
 }
 
 fn test_shrink2() {
     let myport = Port();
-    let mychan = Chan(myport);
+    let mychan = Chan(&myport);
     for uint::range(0u, 100u) |_i| {
         let val: record = {val1: 0u32, val2: 0u32, val3: 0u32};
         send(mychan, val);
@@ -58,7 +58,7 @@ fn test_shrink2() {
 // Test rotating the buffer when the unit size is not a power of two
 fn test_rotate() {
     let myport = Port();
-    let mychan = Chan(myport);
+    let mychan = Chan(&myport);
     for uint::range(0u, 100u) |i| {
         let val = {val1: i as u32, val2: i as u32, val3: i as u32};
         send(mychan, val);
@@ -74,7 +74,7 @@ fn test_rotate() {
 // the unit size is not a power of two
 fn test_rotate_grow() {
     let myport = Port::();
-    let mychan = Chan(myport);
+    let mychan = Chan(&myport);
     for uint::range(0u, 10u) |j| {
         for uint::range(0u, 10u) |i| {
             let val: record =
diff --git a/src/test/run-pass/rt-sched-1.rs b/src/test/run-pass/rt-sched-1.rs
index 15207b668fef..690d93172ebc 100644
--- a/src/test/run-pass/rt-sched-1.rs
+++ b/src/test/run-pass/rt-sched-1.rs
@@ -18,7 +18,7 @@ extern mod rustrt {
 
 fn main() unsafe {
     let po = comm::Port();
-    let ch = comm::Chan(po);
+    let ch = comm::Chan(&po);
     let parent_sched_id = rustrt::rust_get_sched_id();
     error!("parent %?", parent_sched_id);
     let num_threads = 1u;
diff --git a/src/test/run-pass/send-iloop.rs b/src/test/run-pass/send-iloop.rs
index 9e369d819d41..b0003e8b5b18 100644
--- a/src/test/run-pass/send-iloop.rs
+++ b/src/test/run-pass/send-iloop.rs
@@ -8,7 +8,7 @@ fn die() {
 fn iloop() {
     task::spawn(|| die() );
     let p = comm::Port::<()>();
-    let c = comm::Chan(p);
+    let c = comm::Chan(&p);
     loop {
         // Sending and receiving here because these actions yield,
         // at which point our child can kill us
diff --git a/src/test/run-pass/send-resource.rs b/src/test/run-pass/send-resource.rs
index 3fc3afb12dab..a2ef71b14124 100644
--- a/src/test/run-pass/send-resource.rs
+++ b/src/test/run-pass/send-resource.rs
@@ -14,11 +14,11 @@ fn test(f: int) -> test {
 
 fn main() {
     let p = Port();
-    let c = Chan(p);
+    let c = Chan(&p);
 
     do spawn() {
         let p = Port();
-        c.send(Chan(p));
+        c.send(Chan(&p));
 
         let _r = p.recv();
     }
diff --git a/src/test/run-pass/send-type-inference.rs b/src/test/run-pass/send-type-inference.rs
index 4f0b9667524f..8bca78807871 100644
--- a/src/test/run-pass/send-type-inference.rs
+++ b/src/test/run-pass/send-type-inference.rs
@@ -8,6 +8,6 @@ type command = {key: K, val: V};
 
 fn cache_server(c: Chan>>) {
     let ctrl = Port();
-    send(c, Chan(ctrl));
+    send(c, Chan(&ctrl));
 }
 fn main() { }
diff --git a/src/test/run-pass/sendable-class.rs b/src/test/run-pass/sendable-class.rs
index ecaa9238b277..d9b0ec336432 100644
--- a/src/test/run-pass/sendable-class.rs
+++ b/src/test/run-pass/sendable-class.rs
@@ -14,6 +14,6 @@ fn foo(i:int, j: char) -> foo {
 
 fn main() {
   let po = comm::Port::();
-  let ch = comm::Chan(po);
+  let ch = comm::Chan(&po);
   comm::send(ch, foo(42, 'c'));
 }
\ No newline at end of file
diff --git a/src/test/run-pass/spawn-types.rs b/src/test/run-pass/spawn-types.rs
index 22c20ed7e5e6..043bf125532e 100644
--- a/src/test/run-pass/spawn-types.rs
+++ b/src/test/run-pass/spawn-types.rs
@@ -15,6 +15,6 @@ fn iotask(cx: ctx, ip: ~str) {
 
 fn main() {
     let p = comm::Port::();
-    let ch = comm::Chan(p);
+    let ch = comm::Chan(&p);
     task::spawn(|| iotask(ch, ~"localhost") );
 }
diff --git a/src/test/run-pass/task-comm-chan-cleanup.rs b/src/test/run-pass/task-comm-chan-cleanup.rs
index 7149f3079630..b81f001c00d5 100644
--- a/src/test/run-pass/task-comm-chan-cleanup.rs
+++ b/src/test/run-pass/task-comm-chan-cleanup.rs
@@ -2,6 +2,6 @@ extern mod std;
 
 fn main() {
     let p = comm::Port();
-    let c = comm::Chan(p);
+    let c = comm::Chan(&p);
     comm::send(c, ~"coffee");
 }
\ No newline at end of file
diff --git a/src/test/run-pass/task-comm-chan-cleanup2.rs b/src/test/run-pass/task-comm-chan-cleanup2.rs
index 7149f3079630..b81f001c00d5 100644
--- a/src/test/run-pass/task-comm-chan-cleanup2.rs
+++ b/src/test/run-pass/task-comm-chan-cleanup2.rs
@@ -2,6 +2,6 @@ extern mod std;
 
 fn main() {
     let p = comm::Port();
-    let c = comm::Chan(p);
+    let c = comm::Chan(&p);
     comm::send(c, ~"coffee");
 }
\ No newline at end of file
diff --git a/src/test/run-pass/task-comm-chan-cleanup3.rs b/src/test/run-pass/task-comm-chan-cleanup3.rs
index 4dc10f867169..14cb272b62f3 100644
--- a/src/test/run-pass/task-comm-chan-cleanup3.rs
+++ b/src/test/run-pass/task-comm-chan-cleanup3.rs
@@ -3,7 +3,7 @@ extern mod std;
 fn main() {
     let c = {
         let p = comm::Port();
-        comm::Chan(p)
+        comm::Chan(&p)
     };
     comm::send(c, ~"coffee");
 }
\ No newline at end of file
diff --git a/src/test/run-pass/task-comm-chan-cleanup4.rs b/src/test/run-pass/task-comm-chan-cleanup4.rs
index 215843fbac71..852f0e5607d8 100644
--- a/src/test/run-pass/task-comm-chan-cleanup4.rs
+++ b/src/test/run-pass/task-comm-chan-cleanup4.rs
@@ -12,7 +12,7 @@ fn starship(&&ch: comm::Chan<~str>) {
 fn starbase() {
     for int::range(0, 10) |_i| {
         let p = comm::Port();
-        let c = comm::Chan(p);
+        let c = comm::Chan(&p);
         task::spawn(|| starship(c) );
         task::yield();
     }
diff --git a/src/test/run-pass/task-comm-chan-nil.rs b/src/test/run-pass/task-comm-chan-nil.rs
index 87b91889356d..7cbd24844fe5 100644
--- a/src/test/run-pass/task-comm-chan-nil.rs
+++ b/src/test/run-pass/task-comm-chan-nil.rs
@@ -7,7 +7,7 @@ extern mod std;
 // or not this is desirable I don't know, but here's a regression test.
 fn main() {
     let po = comm::Port();
-    let ch = comm::Chan(po);
+    let ch = comm::Chan(&po);
     comm::send(ch, ());
     let n: () = comm::recv(po);
     assert (n == ());
diff --git a/src/test/run-pass/task-comm.rs b/src/test/run-pass/task-comm.rs
index 8d144b1a3995..c88b556fd53f 100644
--- a/src/test/run-pass/task-comm.rs
+++ b/src/test/run-pass/task-comm.rs
@@ -32,7 +32,7 @@ fn test00() {
     debug!("Creating tasks");
 
     let po = Port();
-    let ch = Chan(po);
+    let ch = Chan(&po);
 
     let mut i: int = 0;
 
@@ -69,7 +69,7 @@ fn test01() {
 
 fn test02() {
     let p = Port();
-    let c = Chan(p);
+    let c = Chan(&p);
     debug!("Writing to a local task channel.");
     send(c, 42);
     debug!("Reading from a local task port.");
@@ -101,7 +101,7 @@ fn test05_start(ch: Chan) {
 
 fn test05() {
     let po = comm::Port();
-    let ch = Chan(po);
+    let ch = Chan(&po);
     task::spawn(|| test05_start(ch) );
     let mut value: int;
     value = recv(po);
diff --git a/src/test/run-pass/task-killjoin-rsrc.rs b/src/test/run-pass/task-killjoin-rsrc.rs
index 405ba82b7903..1cea7d61f8c4 100644
--- a/src/test/run-pass/task-killjoin-rsrc.rs
+++ b/src/test/run-pass/task-killjoin-rsrc.rs
@@ -36,7 +36,7 @@ fn joinable(+f: fn~()) -> comm::Port {
         *b = true;
     }
     let p = comm::Port();
-    let c = comm::Chan(p);
+    let c = comm::Chan(&p);
     do task::spawn_unlinked { wrapper(c, copy f) };
     p
 }
diff --git a/src/test/run-pass/task-spawn-move-and-copy.rs b/src/test/run-pass/task-spawn-move-and-copy.rs
index 7316a927751b..09c880d489c2 100644
--- a/src/test/run-pass/task-spawn-move-and-copy.rs
+++ b/src/test/run-pass/task-spawn-move-and-copy.rs
@@ -1,6 +1,6 @@
 fn main() {
     let p = comm::Port::();
-    let ch = comm::Chan(p);
+    let ch = comm::Chan(&p);
 
     let x = ~1;
     let x_in_parent = ptr::addr_of(&(*x)) as uint;
diff --git a/src/test/run-pass/trait-inheritance-simple.rs b/src/test/run-pass/trait-inheritance-simple.rs
new file mode 100644
index 000000000000..37dd11aadc48
--- /dev/null
+++ b/src/test/run-pass/trait-inheritance-simple.rs
@@ -0,0 +1,31 @@
+// xfail-fast
+// xfail-test
+
+// Broken on 32 bit, I guess?
+
+trait Foo {
+    fn f();
+}
+
+trait Bar : Foo {
+    fn g();
+}
+
+struct A {
+    x: int
+}
+
+impl A : Bar {
+    fn g() { io::println("in g"); }
+    fn f() { io::println("in f"); }
+}
+
+fn h(a: &T) {
+    a.f();
+}
+
+fn main() {
+    let a = A { x: 3 };
+    h(&a);
+}
+
diff --git a/src/test/run-pass/trait-region-pointer-simple.rs b/src/test/run-pass/trait-region-pointer-simple.rs
new file mode 100644
index 000000000000..dfcbfc3993f1
--- /dev/null
+++ b/src/test/run-pass/trait-region-pointer-simple.rs
@@ -0,0 +1,21 @@
+trait Foo {
+    fn f() -> int;
+}
+
+struct A {
+    x: int
+}
+
+impl A : Foo {
+    fn f() -> int {
+        io::println(~"Today's number is " + self.x.to_str());
+        return self.x;
+    }
+}
+
+fn main() {
+    let a = A { x: 3 };
+    let b = (&a) as &Foo;
+    assert b.f() == 3;
+}
+
diff --git a/src/test/run-pass/unique-fn-arg-mut.rs b/src/test/run-pass/unique-fn-arg-mut.rs
index 8d9386d70fff..36d1d689f5fb 100644
--- a/src/test/run-pass/unique-fn-arg-mut.rs
+++ b/src/test/run-pass/unique-fn-arg-mut.rs
@@ -1,9 +1,9 @@
-fn f(&i: ~int) {
-    i = ~200;
+fn f(i: &mut ~int) {
+    *i = ~200;
 }
 
 fn main() {
     let mut i = ~100;
-    f(i);
+    f(&mut i);
     assert *i == 200;
 }
\ No newline at end of file
diff --git a/src/test/run-pass/unique-send-2.rs b/src/test/run-pass/unique-send-2.rs
index 73cd7adc034e..70d58ea6cc3b 100644
--- a/src/test/run-pass/unique-send-2.rs
+++ b/src/test/run-pass/unique-send-2.rs
@@ -6,7 +6,7 @@ fn child(c: comm::Chan<~uint>, i: uint) {
 
 fn main() {
     let p = comm::Port();
-    let ch = comm::Chan(p);
+    let ch = comm::Chan(&p);
     let n = 100u;
     let mut expected = 0u;
     for uint::range(0u, n) |i| {
diff --git a/src/test/run-pass/unique-send.rs b/src/test/run-pass/unique-send.rs
index 3acaa1b59f6e..cf06a55ae7a5 100644
--- a/src/test/run-pass/unique-send.rs
+++ b/src/test/run-pass/unique-send.rs
@@ -2,7 +2,7 @@ extern mod std;
 
 fn main() {
     let p = comm::Port();
-    let c = comm::Chan(p);
+    let c = comm::Chan(&p);
     comm::send(c, ~100);
     let v = comm::recv(p);
     assert v == ~100;
diff --git a/src/test/run-pass/unwind-resource.rs b/src/test/run-pass/unwind-resource.rs
index 08d6af273d21..a602a2716026 100644
--- a/src/test/run-pass/unwind-resource.rs
+++ b/src/test/run-pass/unwind-resource.rs
@@ -22,7 +22,7 @@ fn f(c: comm::Chan) {
 
 fn main() {
     let p = comm::Port();
-    let c = comm::Chan(p);
+    let c = comm::Chan(&p);
     task::spawn_unlinked(|| f(c) );
     error!("hiiiiiiiii");
     assert comm::recv(p);
diff --git a/src/test/run-pass/writealias.rs b/src/test/run-pass/writealias.rs
index 9dba2e2adfdc..eb3fa602f12a 100644
--- a/src/test/run-pass/writealias.rs
+++ b/src/test/run-pass/writealias.rs
@@ -4,10 +4,10 @@
 // -*- rust -*-
 type point = {x: int, y: int, mut z: int};
 
-fn f(&p: point) { p.z = 13; }
+fn f(p: &mut point) { p.z = 13; }
 
 fn main() {
     let mut x: point = {x: 10, y: 11, mut z: 12};
-    f(x);
+    f(&mut x);
     assert (x.z == 13);
 }