diff --git a/.travis.yml b/.travis.yml
index 29d287bfb4849..dc955bc2f2be2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,9 @@
-# Use something that's not 'ruby' so we don't set up things like
-# RVM/bundler/ruby and whatnot. Right now 'rust' as a language actually
-# downloads a rust/cargo snapshot, which we don't really want for building rust.
+# ccache support is disabled unless your language is a C-derivative. However
+# `language: C` unconditionally sets `CC=compiler`. If we just set it in our
+# `env` it will be overwritten by the default (gcc 4.6).
 language: c
+compiler: /usr/bin/gcc-4.7
+cache: ccache
 sudo: false
 
 # The test suite is in general way too stressful for travis, especially in
@@ -9,12 +11,28 @@ sudo: false
 # back to only build the stage1 compiler and run a subset of tests, but this
 # didn't end up panning out very well.
 #
-# As a result, we're just using travis to run `make tidy` now. It'll help
-# everyone find out about their trailing spaces early on!
+# As a result, we're just using travis to run `make tidy` and *only* build
+# stage1 but *not* test it for now (a strict subset of the bootstrap). This will
+# catch "obvious" errors like style or not even compiling.
+#
+# We need gcc4.7 or higher to build LLVM, and travis (well, Ubuntu 12.04)
+# currently ships with 4.6. Gotta download our own.
 before_script:
-  - ./configure --llvm-root=path/to/nowhere
+  - ./configure --enable-ccache
 script:
   - make tidy
+  - make rustc-stage1 -j4
+
+env:
+  - CXX=/usr/bin/g++-4.7
+
+addons:
+  apt:
+    sources:
+    - ubuntu-toolchain-r-test
+    packages:
+    - gcc-4.7
+    - g++-4.7
 
 # Real testing happens on http://buildbot.rust-lang.org/
 #
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 16113a32d2448..22a23de070780 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -133,8 +133,8 @@ Documentation improvements are very welcome. The source of `doc.rust-lang.org`
 is located in `src/doc` in the tree, and standard API documentation is generated
 from the source code itself.
 
-Documentation pull requests function in the same as other pull requests, though
-you may see a slightly different form of `r+`:
+Documentation pull requests function in the same way as other pull requests,
+though you may see a slightly different form of `r+`:
 
     @bors: r+ 38fe8d2 rollup
 
diff --git a/RELEASES.md b/RELEASES.md
index 636bcc4312eb8..db1c7380a788b 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -28,6 +28,9 @@ Breaking Changes
   in, and the same value reported by clang's
   `alignof`. [`mem::min_align_of`] is deprecated. This is not known to
   break real code.
+* [The `#[packed]` attribute is no longer silently accepted by the
+  compiler][packed]. This attribute did nothing and code that
+  mentioned it likely did not work as intended.
 
 Language
 --------
@@ -140,7 +143,7 @@ Misc
 [fat]: https://github.com/rust-lang/rust/pull/26411
 [dst]: https://github.com/rust-lang/rfcs/blob/master/text/0982-dst-coercion.md
 [parcodegen]: https://github.com/rust-lang/rust/pull/26018
-
+[packed]: https://github.com/rust-lang/rust/pull/25541
 
 Version 1.1.0 (June 2015)
 =========================
diff --git a/configure b/configure
index 9be2f9b91f0a3..3d04cf7519ed4 100755
--- a/configure
+++ b/configure
@@ -1031,15 +1031,12 @@ fi
 
 if [ ! -z "$CFG_ENABLE_CCACHE" ]
 then
-    if [ -z "$CC" ]
+    if [ -z "$CFG_CCACHE" ]
     then
-        if [ -z "$CFG_CCACHE" ]
-        then
-            err "ccache requested but not found"
-        fi
-
-        CFG_CC="ccache $CFG_CC"
+        err "ccache requested but not found"
     fi
+
+    CFG_CC="ccache $CFG_CC"
 fi
 
 if [ -z "$CC" -a -z "$CFG_ENABLE_CLANG" -a -z "$CFG_GCC" ]
@@ -1528,11 +1525,26 @@ do
 
             (*)
             msg "inferring LLVM_CXX/CC from CXX/CC = $CXX/$CC"
-            LLVM_CXX_32="$CXX"
-            LLVM_CC_32="$CC"
+            if [ ! -z "$CFG_ENABLE_CCACHE" ]
+            then
+                if [ -z "$CFG_CCACHE" ]
+                then
+                    err "ccache requested but not found"
+                fi
+
+                LLVM_CXX_32="ccache $CXX"
+                LLVM_CC_32="ccache $CC"
+
+                LLVM_CXX_64="ccache $CXX"
+                LLVM_CC_64="ccache $CC"
+            else
+                LLVM_CXX_32="$CXX"
+                LLVM_CC_32="$CC"
+
+                LLVM_CXX_64="$CXX"
+                LLVM_CC_64="$CC"
+            fi
 
-            LLVM_CXX_64="$CXX"
-            LLVM_CC_64="$CC"
             ;;
         esac
 
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 060f954274a9d..a37e1c146681e 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -343,10 +343,10 @@ The type of an _unsuffixed_ integer literal is determined by type inference:
 * If an integer type can be _uniquely_ determined from the surrounding
   program context, the unsuffixed integer literal has that type.
 
-* If the program context underconstrains the type, it defaults to the
+* If the program context under-constrains the type, it defaults to the
   signed 32-bit integer `i32`.
 
-* If the program context overconstrains the type, it is considered a
+* If the program context over-constrains the type, it is considered a
   static type error.
 
 Examples of integer literals of various forms:
@@ -382,9 +382,9 @@ type inference:
   surrounding program context, the unsuffixed floating-point literal
   has that type.
 
-* If the program context underconstrains the type, it defaults to `f64`.
+* If the program context under-constrains the type, it defaults to `f64`.
 
-* If the program context overconstrains the type, it is considered a
+* If the program context over-constrains the type, it is considered a
   static type error.
 
 Examples of floating-point literals of various forms:
@@ -1292,7 +1292,7 @@ All access to a static is safe, but there are a number of restrictions on
 statics:
 
 * Statics may not contain any destructors.
-* The types of static values must ascribe to `Sync` to allow threadsafe access.
+* The types of static values must ascribe to `Sync` to allow thread-safe access.
 * Statics may not refer to other statics by value, only by reference.
 * Constants cannot refer to statics.
 
@@ -1694,7 +1694,7 @@ explain, here's a few use cases and what they would entail:
 * A crate needs a global available "helper module" to itself, but it doesn't
   want to expose the helper module as a public API. To accomplish this, the
   root of the crate's hierarchy would have a private module which then
-  internally has a "public api". Because the entire crate is a descendant of
+  internally has a "public API". Because the entire crate is a descendant of
   the root, then the entire local crate can access this private module through
   the second case.
 
@@ -1957,8 +1957,6 @@ macro scope.
   object file that this item's contents will be placed into.
 - `no_mangle` - on any item, do not apply the standard name mangling. Set the
   symbol for this item to its identifier.
-- `packed` - on structs or enums, eliminate any padding that would be used to
-  align fields.
 - `simd` - on certain tuple structs, derive the arithmetic operators, which
   lower to the target's SIMD instructions, if any; the `simd` feature gate
   is necessary to use this attribute.
@@ -3663,47 +3661,71 @@ sites are:
 
 * `let` statements where an explicit type is given.
 
-    In `let _: U = e;`, `e` is coerced to have type `U`.
+   For example, `128` is coerced to have type `i8` in the following:
+
+   ```rust
+   let _: i8 = 128;
+   ```
 
 * `static` and `const` statements (similar to `let` statements).
 
-* arguments for function calls.
+* Arguments for function calls
+
+  The value being coerced is the actual parameter, and it is coerced to
+  the type of the formal parameter.
+
+  For example, `128` is coerced to have type `i8` in the following:
+
+  ```rust
+  fn bar(_: i8) { }
 
-    The value being coerced is the
-    actual parameter and it is coerced to the type of the formal parameter. For
-    example, let `foo` be defined as `fn foo(x: U) { ... }` and call it as
-    `foo(e);`. Then `e` is coerced to have type `U`;
+  fn main() {
+     bar(128);
+  }
+  ```
 
-* instantiations of struct or variant fields.
+* Instantiations of struct or variant fields
 
-    Assume we have a `struct
-    Foo { x: U }` and instantiate it as `Foo { x: e }`. Then `e` is coerced to
-    have type `U`.
+  For example, `128` is coerced to have type `i8` in the following:
 
-* function results (either the final line of a block if it is not semicolon
-terminated or any expression in a `return` statement).
+  ```rust
+  struct Foo { x: i8 }
 
-    In `fn foo() -> U { e }`, `e` is coerced to to have type `U`.
+  fn main() {
+      Foo { x: 128 };
+  }
+  ```
+
+* Function results, either the final line of a block if it is not
+  semicolon-terminated or any expression in a `return` statement
+
+  For example, `128` is coerced to have type `i8` in the following:
+
+  ```rust
+  fn foo() -> i8 {
+      128
+  }
+  ```
 
 If the expression in one of these coercion sites is a coercion-propagating
 expression, then the relevant sub-expressions in that expression are also
 coercion sites. Propagation recurses from these new coercion sites.
 Propagating expressions and their relevant sub-expressions are:
 
-* array literals, where the array has type `[U; n]`. Each sub-expression in
+* Array literals, where the array has type `[U; n]`. Each sub-expression in
 the array literal is a coercion site for coercion to type `U`.
 
-* array literals with repeating syntax, where the array has type `[U; n]`. The
+* Array literals with repeating syntax, where the array has type `[U; n]`. The
 repeated sub-expression is a coercion site for coercion to type `U`.
 
-* tuples, where a tuple is a coercion site to type `(U_0, U_1, ..., U_n)`.
+* Tuples, where a tuple is a coercion site to type `(U_0, U_1, ..., U_n)`.
 Each sub-expression is a coercion site to the respective type, e.g. the
 zeroth sub-expression is a coercion site to type `U_0`.
 
-* parenthesised sub-expressions (`(e)`). If the expression has type `U`, then
+* Parenthesised sub-expressions (`(e)`): if the expression has type `U`, then
 the sub-expression is a coercion site to `U`.
 
-* blocks. If a block has type `U`, then the last expression in the block (if
+* Blocks: if a block has type `U`, then the last expression in the block (if
 it is not semicolon-terminated) is a coercion site to `U`. This includes
 blocks which are part of control flow statements, such as `if`/`else`, if
 the block has a known type.
@@ -3712,45 +3734,46 @@ the block has a known type.
 
 Coercion is allowed between the following types:
 
-* `T` to `U` if `T` is a subtype of `U` (*reflexive case*).
+* `T` to `U` if `T` is a subtype of `U` (*reflexive case*)
 
 * `T_1` to `T_3` where `T_1` coerces to `T_2` and `T_2` coerces to `T_3`
-(*transitive case*).
+(*transitive case*)
 
     Note that this is not fully supported yet
 
-* `&mut T` to `&T`.
+* `&mut T` to `&T`
 
-* `*mut T` to `*const T`.
+* `*mut T` to `*const T`
 
-* `&T` to `*const T`.
+* `&T` to `*const T`
 
-* `&mut T` to `*mut T`.
+* `&mut T` to `*mut T`
 
 * `&T` to `&U` if `T` implements `Deref<Target = U>`. For example:
 
-```rust
-use std::ops::Deref;
+  ```rust
+  use std::ops::Deref;
 
-struct CharContainer {
-    value: char
-}
+  struct CharContainer {
+      value: char
+  }
 
-impl Deref for CharContainer {
-    type Target = char;
+  impl Deref for CharContainer {
+      type Target = char;
 
-    fn deref<'a>(&'a self) -> &'a char {
-        &self.value
-    }
-}
+      fn deref<'a>(&'a self) -> &'a char {
+          &self.value
+      }
+  }
 
-fn foo(arg: &char) {}
+  fn foo(arg: &char) {}
+
+  fn main() {
+      let x = &mut CharContainer { value: 'y' };
+      foo(x); //&mut CharContainer is coerced to &char.
+  }
+  ```
 
-fn main() {
-    let x = &mut CharContainer { value: 'y' };
-    foo(x); //&mut CharContainer is coerced to &char.
-}
-```
 * `&mut T` to `&mut U` if `T` implements `DerefMut<Target = U>`.
 
 * TyCtor(`T`) to TyCtor(coerce_inner(`T`)), where TyCtor(`T`) is one of
@@ -3964,7 +3987,7 @@ In general, `--crate-type=bin` or `--crate-type=lib` should be sufficient for
 all compilation needs, and the other options are just available if more
 fine-grained control is desired over the output format of a Rust crate.
 
-# Appendix: Rationales and design tradeoffs
+# Appendix: Rationales and design trade-offs
 
 *TODO*.
 
@@ -3974,7 +3997,7 @@ Rust is not a particularly original language, with design elements coming from
 a wide range of sources. Some of these are listed below (including elements
 that have since been removed):
 
-* SML, OCaml: algebraic datatypes, pattern matching, type inference,
+* SML, OCaml: algebraic data types, pattern matching, type inference,
   semicolon statement separation
 * C++: references, RAII, smart pointers, move semantics, monomorphisation,
   memory model
diff --git a/src/doc/trpl/error-handling.md b/src/doc/trpl/error-handling.md
index 580eaa6ca5571..8dd5a3650ef52 100644
--- a/src/doc/trpl/error-handling.md
+++ b/src/doc/trpl/error-handling.md
@@ -50,6 +50,8 @@ is very wrong. Wrong enough that we can't continue with things in the current
 state. Another example is using the `unreachable!()` macro:
 
 ```rust,ignore
+use Event::NewRelease;
+
 enum Event {
     NewRelease,
 }
@@ -71,7 +73,7 @@ fn descriptive_probability(event: Event) -> &'static str {
 }
 
 fn main() {
-    std::io::println(descriptive_probability(NewRelease));
+    println!("{}", descriptive_probability(NewRelease));
 }
 ```
 
diff --git a/src/doc/trpl/the-stack-and-the-heap.md b/src/doc/trpl/the-stack-and-the-heap.md
index 2c5f5927fd15a..ff81590cc03b9 100644
--- a/src/doc/trpl/the-stack-and-the-heap.md
+++ b/src/doc/trpl/the-stack-and-the-heap.md
@@ -176,7 +176,7 @@ After `bar()` is over, its frame is deallocated, leaving just `foo()` and
 | 1       | a    | 5     |
 | 0       | x    | 42    |
 
-And then `foo()` ends, leaving just `main()`
+And then `foo()` ends, leaving just `main()`:
 
 | Address | Name | Value |
 |---------|------|-------|
@@ -537,7 +537,7 @@ Generally, you should prefer stack allocation, and so, Rust stack-allocates by
 default. The LIFO model of the stack is simpler, at a fundamental level. This
 has two big impacts: runtime efficiency and semantic impact.
 
-## Runtime Efficiency.
+## Runtime Efficiency
 
 Managing the memory for the stack is trivial: The machine just
 increments or decrements a single value, the so-called “stack pointer”.
diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs
index a92b72e0f00fa..d26e9ab707205 100644
--- a/src/libcore/hash/sip.rs
+++ b/src/libcore/hash/sip.rs
@@ -10,8 +10,6 @@
 
 //! An implementation of SipHash 2-4.
 
-#![allow(deprecated)] // until the next snapshot for inherent wrapping ops
-
 use prelude::*;
 use super::Hasher;
 
diff --git a/src/libcoretest/hash/mod.rs b/src/libcoretest/hash/mod.rs
index 5c11f0196aeb8..697c3ee254b98 100644
--- a/src/libcoretest/hash/mod.rs
+++ b/src/libcoretest/hash/mod.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+mod sip;
+
 use std::mem;
 use std::hash::{Hash, Hasher};
 use std::default::Default;
diff --git a/src/libcoretest/hash/sip.rs b/src/libcoretest/hash/sip.rs
index 8289d06d04c61..7832985d3f1c1 100644
--- a/src/libcoretest/hash/sip.rs
+++ b/src/libcoretest/hash/sip.rs
@@ -8,28 +8,55 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 use test::Bencher;
-use std::prelude::*;
-use std::fmt;
 
-use str::Str;
-use string::String;
-use slice::{AsSlice, SlicePrelude};
-use vec::Vec;
-
-use core::hash::{Hash, Writer};
-use core::hash::sip::{SipState, hash, hash_with_keys};
+use core::hash::{Hash, Hasher};
+use core::hash::SipHasher;
 
 // Hash just the bytes of the slice, without length prefix
 struct Bytes<'a>(&'a [u8]);
 
-impl<'a, S: Writer> Hash<S> for Bytes<'a> {
+impl<'a> Hash for Bytes<'a> {
     #[allow(unused_must_use)]
-    fn hash(&self, state: &mut S) {
+    fn hash<H: Hasher>(&self, state: &mut H) {
         let Bytes(v) = *self;
         state.write(v);
     }
 }
 
+macro_rules! u8to64_le {
+    ($buf:expr, $i:expr) =>
+    ($buf[0+$i] as u64 |
+     ($buf[1+$i] as u64) << 8 |
+     ($buf[2+$i] as u64) << 16 |
+     ($buf[3+$i] as u64) << 24 |
+     ($buf[4+$i] as u64) << 32 |
+     ($buf[5+$i] as u64) << 40 |
+     ($buf[6+$i] as u64) << 48 |
+     ($buf[7+$i] as u64) << 56);
+    ($buf:expr, $i:expr, $len:expr) =>
+    ({
+        let mut t = 0;
+        let mut out = 0;
+        while t < $len {
+            out |= ($buf[t+$i] as u64) << t*8;
+            t += 1;
+        }
+        out
+    });
+}
+
+fn hash<T: Hash>(x: &T) -> u64 {
+    let mut st = SipHasher::new();
+    x.hash(&mut st);
+    st.finish()
+}
+
+fn hash_with_keys<T: Hash>(k1: u64, k2: u64, x: &T) -> u64 {
+    let mut st = SipHasher::new_with_keys(k1, k2);
+    x.hash(&mut st);
+    st.finish()
+}
+
 #[test]
 #[allow(unused_must_use)]
 fn test_siphash() {
@@ -104,79 +131,43 @@ fn test_siphash() {
     let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08;
     let mut buf = Vec::new();
     let mut t = 0;
-    let mut state_inc = SipState::new_with_keys(k0, k1);
-    let mut state_full = SipState::new_with_keys(k0, k1);
-
-    fn to_hex_str(r: &[u8; 8]) -> String {
-        let mut s = String::new();
-        for b in r {
-            s.push_str(format!("{}", fmt::radix(*b, 16)));
-        }
-        s
-    }
-
-    fn result_bytes(h: u64) -> Vec<u8> {
-        vec![(h >> 0) as u8,
-          (h >> 8) as u8,
-          (h >> 16) as u8,
-          (h >> 24) as u8,
-          (h >> 32) as u8,
-          (h >> 40) as u8,
-          (h >> 48) as u8,
-          (h >> 56) as u8,
-        ]
-    }
-
-    fn result_str(h: u64) -> String {
-        let r = result_bytes(h);
-        let mut s = String::new();
-        for b in &r {
-            s.push_str(format!("{}", fmt::radix(*b, 16)));
-        }
-        s
-    }
+    let mut state_inc = SipHasher::new_with_keys(k0, k1);
 
     while t < 64 {
-        debug!("siphash test {}: {}", t, buf);
         let vec = u8to64_le!(vecs[t], 0);
-        let out = hash_with_keys(k0, k1, &Bytes(buf));
-        debug!("got {}, expected {}", out, vec);
+        let out = hash_with_keys(k0, k1, &Bytes(&buf));
         assert_eq!(vec, out);
 
-        state_full.reset();
-        state_full.write(buf);
-        let f = result_str(state_full.result());
-        let i = result_str(state_inc.result());
-        let v = to_hex_str(&vecs[t]);
-        debug!("{}: ({}) => inc={} full={}", t, v, i, f);
+        let full = hash_with_keys(k0, k1, &Bytes(&buf));
+        let i = state_inc.finish();
 
-        assert_eq!(f, i);
-        assert_eq!(f, v);
+        assert_eq!(full, i);
+        assert_eq!(full, vec);
 
         buf.push(t as u8);
-        state_inc.write(&[t as u8]);
+        Hasher::write(&mut state_inc, &[t as u8]);
 
         t += 1;
     }
 }
 
 #[test] #[cfg(target_arch = "arm")]
-fn test_hash_uint() {
+fn test_hash_usize() {
     let val = 0xdeadbeef_deadbeef_u64;
-    assert!(hash(&(val as u64)) != hash(&(val as uint)));
-    assert_eq!(hash(&(val as u32)), hash(&(val as uint)));
+    assert!(hash(&(val as u64)) != hash(&(val as usize)));
+    assert_eq!(hash(&(val as u32)), hash(&(val as usize)));
 }
 #[test] #[cfg(target_arch = "x86_64")]
-fn test_hash_uint() {
+fn test_hash_usize() {
     let val = 0xdeadbeef_deadbeef_u64;
-    assert_eq!(hash(&(val as u64)), hash(&(val as uint)));
-    assert!(hash(&(val as u32)) != hash(&(val as uint)));
+    assert_eq!(hash(&(val as u64)), hash(&(val as usize)));
+    assert!(hash(&(val as u32)) != hash(&(val as usize)));
 }
 #[test] #[cfg(target_arch = "x86")]
-fn test_hash_uint() {
+fn test_hash_usize() {
     let val = 0xdeadbeef_deadbeef_u64;
-    assert!(hash(&(val as u64)) != hash(&(val as uint)));
-    assert_eq!(hash(&(val as u32)), hash(&(val as uint)));
+    assert!(hash(&(val as u64)) != hash(&(val as usize)));
+    assert_eq!(hash(&(val as u32)), hash(&(val as usize)));
 }
 
 #[test]
@@ -200,7 +191,7 @@ fn test_hash_no_bytes_dropped_64() {
     assert!(hash(&val) != hash(&zero_byte(val, 6)));
     assert!(hash(&val) != hash(&zero_byte(val, 7)));
 
-    fn zero_byte(val: u64, byte: uint) -> u64 {
+    fn zero_byte(val: u64, byte: usize) -> u64 {
         assert!(byte < 8);
         val & !(0xff << (byte * 8))
     }
@@ -215,7 +206,7 @@ fn test_hash_no_bytes_dropped_32() {
     assert!(hash(&val) != hash(&zero_byte(val, 2)));
     assert!(hash(&val) != hash(&zero_byte(val, 3)));
 
-    fn zero_byte(val: u32, byte: uint) -> u32 {
+    fn zero_byte(val: u32, byte: usize) -> u32 {
         assert!(byte < 4);
         val & !(0xff << (byte * 8))
     }
@@ -230,8 +221,9 @@ fn test_hash_no_concat_alias() {
     assert!(s != t && t != u);
     assert!(hash(&s) != hash(&t) && hash(&s) != hash(&u));
 
-    let v: (&[u8], &[u8], &[u8]) = (&[1], &[0, 0], &[0]);
-    let w: (&[u8], &[u8], &[u8]) = (&[1, 0, 0, 0], &[], &[]);
+    let u = [1, 0, 0, 0];
+    let v = (&u[..1], &u[1..3], &u[3..]);
+    let w = (&u[..], &u[4..4], &u[4..4]);
 
     assert!(v != w);
     assert!(hash(&v) != hash(&w));
diff --git a/src/librustc/ast_map/mod.rs b/src/librustc/ast_map/mod.rs
index 3205141e604c2..5c10cc6aaa8db 100644
--- a/src/librustc/ast_map/mod.rs
+++ b/src/librustc/ast_map/mod.rs
@@ -411,6 +411,13 @@ impl<'ast> Map<'ast> {
         }
     }
 
+    pub fn expect_trait_item(&self, id: NodeId) -> &'ast TraitItem {
+        match self.find(id) {
+            Some(NodeTraitItem(item)) => item,
+            _ => panic!("expected trait item, found {}", self.node_to_string(id))
+        }
+    }
+
     pub fn expect_struct(&self, id: NodeId) -> &'ast StructDef {
         match self.find(id) {
             Some(NodeItem(i)) => {
diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs
index 9aa5daa3a0a27..4b77c211df983 100644
--- a/src/librustc/diagnostics.rs
+++ b/src/librustc/diagnostics.rs
@@ -972,16 +972,16 @@ Updates to the borrow checker in a future version of Rust may remove this
 restriction, but for now patterns must be rewritten without sub-bindings.
 
 ```
-// Code like this...
-match Some(5) {
-    ref op_num @ Some(num) => ...
+// Before.
+match Some("hi".to_string()) {
+    ref op_string_ref @ Some(ref s) => ...
     None => ...
 }
 
 // After.
 match Some("hi".to_string()) {
     Some(ref s) => {
-        let op_string_ref = &Some(&s);
+        let op_string_ref = &Some(s);
         ...
     }
     None => ...
diff --git a/src/librustc/middle/infer/higher_ranked/README.md b/src/librustc/middle/infer/higher_ranked/README.md
index 3414c7515a374..57665b6d93923 100644
--- a/src/librustc/middle/infer/higher_ranked/README.md
+++ b/src/librustc/middle/infer/higher_ranked/README.md
@@ -17,7 +17,7 @@ The problem we are addressing is that there is a kind of subtyping
 between functions with bound region parameters. Consider, for
 example, whether the following relation holds:
 
-    for<'a> fn(&'a int) <: for<'b> fn(&'b int)? (Yes, a => b)
+    for<'a> fn(&'a isize) <: for<'b> fn(&'b isize)? (Yes, a => b)
 
 The answer is that of course it does. These two types are basically
 the same, except that in one we used the name `a` and one we used
@@ -27,14 +27,14 @@ In the examples that follow, it becomes very important to know whether
 a lifetime is bound in a function type (that is, is a lifetime
 parameter) or appears free (is defined in some outer scope).
 Therefore, from now on I will always write the bindings explicitly,
-using the Rust syntax `for<'a> fn(&'a int)` to indicate that `a` is a
+using the Rust syntax `for<'a> fn(&'a isize)` to indicate that `a` is a
 lifetime parameter.
 
 Now let's consider two more function types. Here, we assume that the
 `'b` lifetime is defined somewhere outside and hence is not a lifetime
 parameter bound by the function type (it "appears free"):
 
-    for<'a> fn(&'a int) <: fn(&'b int)? (Yes, a => b)
+    for<'a> fn(&'a isize) <: fn(&'b isize)? (Yes, a => b)
 
 This subtyping relation does in fact hold. To see why, you have to
 consider what subtyping means. One way to look at `T1 <: T2` is to
@@ -51,7 +51,7 @@ to the same thing: a function that accepts pointers with any lifetime
 
 So, what if we reverse the order of the two function types, like this:
 
-    fn(&'b int) <: for<'a> fn(&'a int)? (No)
+    fn(&'b isize) <: for<'a> fn(&'a isize)? (No)
 
 Does the subtyping relationship still hold?  The answer of course is
 no. In this case, the function accepts *only the lifetime `'b`*,
@@ -60,8 +60,8 @@ accepted any lifetime.
 
 What about these two examples:
 
-    for<'a,'b> fn(&'a int, &'b int) <: for<'a>    fn(&'a int, &'a int)? (Yes)
-    for<'a>    fn(&'a int, &'a int) <: for<'a,'b> fn(&'a int, &'b int)? (No)
+    for<'a,'b> fn(&'a isize, &'b isize) <: for<'a>    fn(&'a isize, &'a isize)? (Yes)
+    for<'a>    fn(&'a isize, &'a isize) <: for<'a,'b> fn(&'a isize, &'b isize)? (No)
 
 Here, it is true that functions which take two pointers with any two
 lifetimes can be treated as if they only accepted two pointers with
diff --git a/src/librustc/middle/infer/region_inference/README.md b/src/librustc/middle/infer/region_inference/README.md
index e44211da4a7bb..2dc16d4fa1dd4 100644
--- a/src/librustc/middle/infer/region_inference/README.md
+++ b/src/librustc/middle/infer/region_inference/README.md
@@ -121,7 +121,7 @@ every expression, block, and pattern (patterns are considered to
 "execute" by testing the value they are applied to and creating any
 relevant bindings).  So, for example:
 
-    fn foo(x: int, y: int) { // -+
+    fn foo(x: isize, y: isize) { // -+
     //  +------------+       //  |
     //  |      +-----+       //  |
     //  |  +-+ +-+ +-+       //  |
@@ -168,13 +168,13 @@ an error.
 Here is a more involved example (which is safe) so we can see what's
 going on:
 
-    struct Foo { f: uint, g: uint }
+    struct Foo { f: usize, g: usize }
     ...
-    fn add(p: &mut uint, v: uint) {
+    fn add(p: &mut usize, v: usize) {
         *p += v;
     }
     ...
-    fn inc(p: &mut uint) -> uint {
+    fn inc(p: &mut usize) -> usize {
         *p += 1; *p
     }
     fn weird() {
@@ -199,8 +199,8 @@ in a call expression:
 
     'a: {
         'a_arg1: let a_temp1: ... = add;
-        'a_arg2: let a_temp2: &'a mut uint = &'a mut (*x).f;
-        'a_arg3: let a_temp3: uint = {
+        'a_arg2: let a_temp2: &'a mut usize = &'a mut (*x).f;
+        'a_arg3: let a_temp3: usize = {
             let b_temp1: ... = inc;
             let b_temp2: &'b = &'b mut (*x).f;
             'b_call: b_temp1(b_temp2)
@@ -225,13 +225,13 @@ it will not be *dereferenced* during the evaluation of the second
 argument, it can still be *invalidated* by that evaluation. Consider
 this similar but unsound example:
 
-    struct Foo { f: uint, g: uint }
+    struct Foo { f: usize, g: usize }
     ...
-    fn add(p: &mut uint, v: uint) {
+    fn add(p: &mut usize, v: usize) {
         *p += v;
     }
     ...
-    fn consume(x: Box<Foo>) -> uint {
+    fn consume(x: Box<Foo>) -> usize {
         x.f + x.g
     }
     fn weird() {
diff --git a/src/librustc/middle/traits/README.md b/src/librustc/middle/traits/README.md
index 853d12172af5e..92982af92dcfe 100644
--- a/src/librustc/middle/traits/README.md
+++ b/src/librustc/middle/traits/README.md
@@ -12,10 +12,10 @@ reference to a trait. So, for example, if there is a generic function like:
 
 and then a call to that function:
 
-    let v: Vec<int> = clone_slice([1, 2, 3])
+    let v: Vec<isize> = clone_slice([1, 2, 3])
 
 it is the job of trait resolution to figure out (in which case)
-whether there exists an impl of `int : Clone`
+whether there exists an impl of `isize : Clone`
 
 Note that in some cases, like generic functions, we may not be able to
 find a specific impl, but we can figure out that the caller must
@@ -115,27 +115,27 @@ trait Convert<Target> {
 
 This trait just has one method. It's about as simple as it gets. It
 converts from the (implicit) `Self` type to the `Target` type. If we
-wanted to permit conversion between `int` and `uint`, we might
+wanted to permit conversion between `isize` and `usize`, we might
 implement `Convert` like so:
 
 ```rust
-impl Convert<uint> for int { ... } // int -> uint
-impl Convert<int> for uint { ... } // uint -> int
+impl Convert<usize> for isize { ... } // isize -> usize
+impl Convert<isize> for usize { ... } // usize -> isize
 ```
 
 Now imagine there is some code like the following:
 
 ```rust
-let x: int = ...;
+let x: isize = ...;
 let y = x.convert();
 ```
 
 The call to convert will generate a trait reference `Convert<$Y> for
-int`, where `$Y` is the type variable representing the type of
+isize`, where `$Y` is the type variable representing the type of
 `y`. When we match this against the two impls we can see, we will find
-that only one remains: `Convert<uint> for int`. Therefore, we can
+that only one remains: `Convert<usize> for isize`. Therefore, we can
 select this impl, which will cause the type of `$Y` to be unified to
-`uint`. (Note that while assembling candidates, we do the initial
+`usize`. (Note that while assembling candidates, we do the initial
 unifications in a transaction, so that they don't affect one another.)
 
 There are tests to this effect in src/test/run-pass:
@@ -225,7 +225,7 @@ Confirmation unifies the output type parameters of the trait with the
 values found in the obligation, possibly yielding a type error.  If we
 return to our example of the `Convert` trait from the previous
 section, confirmation is where an error would be reported, because the
-impl specified that `T` would be `uint`, but the obligation reported
+impl specified that `T` would be `usize`, but the obligation reported
 `char`. Hence the result of selection would be an error.
 
 ### Selection during translation
@@ -250,12 +250,12 @@ Here is an example:
     trait Foo { ... }
     impl<U,T:Bar<U>> Foo for Vec<T> { ... }
 
-    impl Bar<uint> for int { ... }
+    impl Bar<usize> for isize { ... }
 
-After one shallow round of selection for an obligation like `Vec<int>
+After one shallow round of selection for an obligation like `Vec<isize>
 : Foo`, we would know which impl we want, and we would know that
-`T=int`, but we do not know the type of `U`.  We must select the
-nested obligation `int : Bar<U>` to find out that `U=uint`.
+`T=isize`, but we do not know the type of `U`.  We must select the
+nested obligation `isize : Bar<U>` to find out that `U=usize`.
 
 It would be good to only do *just as much* nested resolution as
 necessary. Currently, though, we just do a full resolution.
@@ -263,7 +263,7 @@ necessary. Currently, though, we just do a full resolution.
 # Higher-ranked trait bounds
 
 One of the more subtle concepts at work are *higher-ranked trait
-bounds*. An example of such a bound is `for<'a> MyTrait<&'a int>`.
+bounds*. An example of such a bound is `for<'a> MyTrait<&'a isize>`.
 Let's walk through how selection on higher-ranked trait references
 works.
 
@@ -279,21 +279,21 @@ trait Foo<X> {
 ```
 
 Let's say we have a function `want_hrtb` that wants a type which
-implements `Foo<&'a int>` for any `'a`:
+implements `Foo<&'a isize>` for any `'a`:
 
 ```rust
-fn want_hrtb<T>() where T : for<'a> Foo<&'a int> { ... }
+fn want_hrtb<T>() where T : for<'a> Foo<&'a isize> { ... }
 ```
 
-Now we have a struct `AnyInt` that implements `Foo<&'a int>` for any
+Now we have a struct `AnyInt` that implements `Foo<&'a isize>` for any
 `'a`:
 
 ```rust
 struct AnyInt;
-impl<'a> Foo<&'a int> for AnyInt { }
+impl<'a> Foo<&'a isize> for AnyInt { }
 ```
 
-And the question is, does `AnyInt : for<'a> Foo<&'a int>`? We want the
+And the question is, does `AnyInt : for<'a> Foo<&'a isize>`? We want the
 answer to be yes. The algorithm for figuring it out is closely related
 to the subtyping for higher-ranked types (which is described in
 `middle::infer::higher_ranked::doc`, but also in a [paper by SPJ] that
@@ -306,12 +306,12 @@ I recommend you read).
 [paper by SPJ]: http://research.microsoft.com/en-us/um/people/simonpj/papers/higher-rank/
 
 So let's work through our example. The first thing we would do is to
-skolemize the obligation, yielding `AnyInt : Foo<&'0 int>` (here `'0`
+skolemize the obligation, yielding `AnyInt : Foo<&'0 isize>` (here `'0`
 represents skolemized region #0). Note that now have no quantifiers;
 in terms of the compiler type, this changes from a `ty::PolyTraitRef`
 to a `TraitRef`. We would then create the `TraitRef` from the impl,
 using fresh variables for it's bound regions (and thus getting
-`Foo<&'$a int>`, where `'$a` is the inference variable for `'a`). Next
+`Foo<&'$a isize>`, where `'$a` is the inference variable for `'a`). Next
 we relate the two trait refs, yielding a graph with the constraint
 that `'0 == '$a`. Finally, we check for skolemization "leaks" -- a
 leak is basically any attempt to relate a skolemized region to another
@@ -327,13 +327,13 @@ Let's consider a failure case. Imagine we also have a struct
 
 ```rust
 struct StaticInt;
-impl Foo<&'static int> for StaticInt;
+impl Foo<&'static isize> for StaticInt;
 ```
 
-We want the obligation `StaticInt : for<'a> Foo<&'a int>` to be
+We want the obligation `StaticInt : for<'a> Foo<&'a isize>` to be
 considered unsatisfied. The check begins just as before. `'a` is
 skolemized to `'0` and the impl trait reference is instantiated to
-`Foo<&'static int>`. When we relate those two, we get a constraint
+`Foo<&'static isize>`. When we relate those two, we get a constraint
 like `'static == '0`. This means that the taint set for `'0` is `{'0,
 'static}`, which fails the leak check.
 
@@ -358,13 +358,13 @@ impl<X,F> Foo<X> for F
 }
 ```
 
-Now let's say we have a obligation `for<'a> Foo<&'a int>` and we match
+Now let's say we have a obligation `for<'a> Foo<&'a isize>` and we match
 this impl. What obligation is generated as a result? We want to get
-`for<'a> Bar<&'a int>`, but how does that happen?
+`for<'a> Bar<&'a isize>`, but how does that happen?
 
 After the matching, we are in a position where we have a skolemized
-substitution like `X => &'0 int`. If we apply this substitution to the
-impl obligations, we get `F : Bar<&'0 int>`. Obviously this is not
+substitution like `X => &'0 isize`. If we apply this substitution to the
+impl obligations, we get `F : Bar<&'0 isize>`. Obviously this is not
 directly usable because the skolemized region `'0` cannot leak out of
 our computation.
 
@@ -375,7 +375,7 @@ leak check passed, so this taint set consists solely of the skolemized
 region itself plus various intermediate region variables. We then walk
 the trait-reference and convert every region in that taint set back to
 a late-bound region, so in this case we'd wind up with `for<'a> F :
-Bar<&'a int>`.
+Bar<&'a isize>`.
 
 # Caching and subtle considerations therewith
 
@@ -391,8 +391,8 @@ but *replay* its effects on the type variables.
 
 The high-level idea of how the cache works is that we first replace
 all unbound inference variables with skolemized versions. Therefore,
-if we had a trait reference `uint : Foo<$1>`, where `$n` is an unbound
-inference variable, we might replace it with `uint : Foo<%0>`, where
+if we had a trait reference `usize : Foo<$1>`, where `$n` is an unbound
+inference variable, we might replace it with `usize : Foo<%0>`, where
 `%n` is a skolemized type. We would then look this up in the cache.
 If we found a hit, the hit would tell us the immediate next step to
 take in the selection process: i.e., apply impl #22, or apply where
@@ -401,17 +401,17 @@ Therefore, we search through impls and where clauses and so forth, and
 we come to the conclusion that the only possible impl is this one,
 with def-id 22:
 
-    impl Foo<int> for uint { ... } // Impl #22
+    impl Foo<isize> for usize { ... } // Impl #22
 
-We would then record in the cache `uint : Foo<%0> ==>
+We would then record in the cache `usize : Foo<%0> ==>
 ImplCandidate(22)`. Next we would confirm `ImplCandidate(22)`, which
-would (as a side-effect) unify `$1` with `int`.
+would (as a side-effect) unify `$1` with `isize`.
 
-Now, at some later time, we might come along and see a `uint :
-Foo<$3>`.  When skolemized, this would yield `uint : Foo<%0>`, just as
+Now, at some later time, we might come along and see a `usize :
+Foo<$3>`.  When skolemized, this would yield `usize : Foo<%0>`, just as
 before, and hence the cache lookup would succeed, yielding
 `ImplCandidate(22)`. We would confirm `ImplCandidate(22)` which would
-(as a side-effect) unify `$3` with `int`.
+(as a side-effect) unify `$3` with `isize`.
 
 ## Where clauses and the local vs global cache
 
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 0d475e1257141..8f2e5deb92c7d 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -705,8 +705,19 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                             ol,
                             moved_lp_msg,
                             pat_ty));
-                self.tcx.sess.fileline_help(span,
-                    "use `ref` to override");
+                match self.tcx.sess.codemap().span_to_snippet(span) {
+                    Ok(string) => {
+                        self.tcx.sess.span_suggestion(
+                            span,
+                            &format!("if you would like to borrow the value instead, \
+                                      use a `ref` binding as shown:"),
+                            format!("ref {}", string));
+                    },
+                    Err(_) => {
+                        self.tcx.sess.fileline_help(span,
+                            "use `ref` to override");
+                    },
+                }
             }
 
             move_data::Captured => {
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 2906fd35a0a18..873950b0be893 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -202,20 +202,24 @@ pub trait CompilerCalls<'a> {
     // be called straight after options have been parsed but before anything
     // else (e.g., selecting input and output).
     fn early_callback(&mut self,
-                      &getopts::Matches,
-                      &diagnostics::registry::Registry)
-                      -> Compilation;
+                      _: &getopts::Matches,
+                      _: &diagnostics::registry::Registry)
+                      -> Compilation {
+        Compilation::Continue
+    }
 
     // Hook for a callback late in the process of handling arguments. This will
     // be called just before actual compilation starts (and before build_controller
     // is called), after all arguments etc. have been completely handled.
     fn late_callback(&mut self,
-                     &getopts::Matches,
-                     &Session,
-                     &Input,
-                     &Option<PathBuf>,
-                     &Option<PathBuf>)
-                     -> Compilation;
+                     _: &getopts::Matches,
+                     _: &Session,
+                     _: &Input,
+                     _: &Option<PathBuf>,
+                     _: &Option<PathBuf>)
+                     -> Compilation {
+        Compilation::Continue
+    }
 
     // Called after we extract the input from the arguments. Gives the implementer
     // an opportunity to change the inputs or to add some custom input handling.
@@ -231,12 +235,14 @@ pub trait CompilerCalls<'a> {
     // emitting error messages. Returning None will cause compilation to stop
     // at this point.
     fn no_input(&mut self,
-                &getopts::Matches,
-                &config::Options,
-                &Option<PathBuf>,
-                &Option<PathBuf>,
-                &diagnostics::registry::Registry)
-                -> Option<(Input, Option<PathBuf>)>;
+                _: &getopts::Matches,
+                _: &config::Options,
+                _: &Option<PathBuf>,
+                _: &Option<PathBuf>,
+                _: &diagnostics::registry::Registry)
+                -> Option<(Input, Option<PathBuf>)> {
+        None
+    }
 
     // Parse pretty printing information from the arguments. The implementer can
     // choose to ignore this (the default will return None) which will skip pretty
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index dd26fd25215a3..aa7f93776da22 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -26,6 +26,7 @@ use ParentLink::{self, ModuleParentLink, BlockParentLink};
 use Resolver;
 use resolve_imports::Shadowable;
 use TypeNsDef;
+use {resolve_error, ResolutionError};
 
 use self::DuplicateCheckingMode::*;
 use self::NamespaceError::*;
@@ -208,10 +209,13 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                     // Return an error here by looking up the namespace that
                     // had the duplicate.
                     let ns = ns.unwrap();
-                    self.resolve_error(sp,
-                        &format!("duplicate definition of {} `{}`",
-                             namespace_error_to_string(duplicate_type),
-                             token::get_name(name)));
+                    resolve_error(
+                        self,
+                        sp,
+                        ResolutionError::DuplicateDefinition(
+                            namespace_error_to_string(duplicate_type),
+                            name)
+                    );
                     {
                         let r = child.span_for_namespace(ns);
                         if let Some(sp) = r {
@@ -304,8 +308,10 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                             full_path.segments.last().unwrap().identifier.name;
                         if &token::get_name(source_name)[..] == "mod" ||
                            &token::get_name(source_name)[..] == "self" {
-                            self.resolve_error(view_path.span,
-                                "`self` imports are only allowed within a { } list");
+                            resolve_error(self,
+                                            view_path.span,
+                                            ResolutionError::SelfImportsOnlyAllowedWithin
+                            );
                         }
 
                         let subclass = SingleImport(binding.name,
@@ -325,8 +331,11 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                             _ => None
                         }).collect::<Vec<Span>>();
                         if mod_spans.len() > 1 {
-                            self.resolve_error(mod_spans[0],
-                                "`self` import can only appear once in the list");
+                            resolve_error(
+                                self,
+                                mod_spans[0],
+                                ResolutionError::SelfImportCanOnlyAppearOnceInTheList
+                            );
                             for other_span in mod_spans.iter().skip(1) {
                                 self.session.span_note(*other_span,
                                     "another `self` import appears here");
@@ -341,9 +350,12 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                                     let name = match module_path.last() {
                                         Some(name) => *name,
                                         None => {
-                                            self.resolve_error(source_item.span,
-                                                "`self` import can only appear in an import list \
-                                                 with a non-empty prefix");
+                                            resolve_error(
+                                                self,
+                                                source_item.span,
+                                                ResolutionError::
+                                                SelfImportOnlyInImportListWithNonEmptyPrefix
+                                            );
                                             continue;
                                         }
                                     };
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 15ddcbc80749c..939991da20307 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -202,12 +202,52 @@ http://doc.rust-lang.org/reference.html#types
 }
 
 register_diagnostics! {
-    E0157,
-    E0153,
+    E0153, // called no where
+    E0157, // called from no where
     E0253, // not directly importable
     E0254, // import conflicts with imported crate in this module
     E0257,
     E0258,
     E0364, // item is private
-    E0365  // item is private
+    E0365, // item is private
+    E0401, // can't use type parameters from outer function
+    E0402, // cannot use an outer type parameter in this context
+    E0403, // the name `{}` is already used
+    E0404, // is not a trait
+    E0405, // use of undeclared trait name
+    E0406, // undeclared associated type
+    E0407, // method is not a member of trait
+    E0408, // variable from pattern #1 is not bound in pattern #
+    E0409, // variable is bound with different mode in pattern # than in
+           // pattern #1
+    E0410, // variable from pattern is not bound in pattern 1
+    E0411, // use of `Self` outside of an impl or trait
+    E0412, // use of undeclared
+    E0413, // declaration of shadows an enum variant or unit-like struct in
+           // scope
+    E0414, // only irrefutable patterns allowed here
+    E0415, // identifier is bound more than once in this parameter list
+    E0416, // identifier is bound more than once in the same pattern
+    E0417, // static variables cannot be referenced in a pattern, use a
+           // `const` instead
+    E0418, // is not an enum variant, struct or const
+    E0419, // unresolved enum variant, struct or const
+    E0420, // is not an associated const
+    E0421, // unresolved associated const
+    E0422, // does not name a structure
+    E0423, // is a struct variant name, but this expression uses it like a
+           // function name
+    E0424, // `self` is not available in a static method.
+    E0425, // unresolved name
+    E0426, // use of undeclared label
+    E0427, // cannot use `ref` binding mode with ...
+    E0428, // duplicate definition of ...
+    E0429, // `self` imports are only allowed within a { } list
+    E0430, // `self` import can only appear once in the list
+    E0431, // `self` import can only appear in an import list with a non-empty
+           // prefix
+    E0432, // unresolved import
+    E0433, // failed to resolve
+    E0434, // can't capture dynamic environment in a fn item
+    E0435  // attempt to use a non-constant value in a constant
 }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 1093d2ef31815..e1afc33684ce6 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -99,7 +99,6 @@ use std::usize;
 use resolve_imports::{Target, ImportDirective, ImportResolution};
 use resolve_imports::Shadowable;
 
-
 // NB: This module needs to be declared first so diagnostics are
 // registered before they are used.
 pub mod diagnostics;
@@ -109,6 +108,262 @@ mod record_exports;
 mod build_reduced_graph;
 mod resolve_imports;
 
+pub enum ResolutionError<'a> {
+    /// error E0401: can't use type parameters from outer function
+    TypeParametersFromOuterFunction,
+    /// error E0402: cannot use an outer type parameter in this context
+    OuterTypeParameterContext,
+    /// error E0403: the name is already used for a type parameter in this type parameter list
+    NameAlreadyUsedInTypeParameterList(Name),
+    /// error E0404: is not a trait
+    IsNotATrait(&'a str),
+    /// error E0405: use of undeclared trait name
+    UndeclaredTraitName(&'a str),
+    /// error E0406: undeclared associated type
+    UndeclaredAssociatedType,
+    /// error E0407: method is not a member of trait
+    MethodNotMemberOfTrait(Name, &'a str),
+    /// error E0408: variable `{}` from pattern #1 is not bound in pattern
+    VariableNotBoundInPattern(Name, usize),
+    /// error E0409: variable is bound with different mode in pattern #{} than in pattern #1
+    VariableBoundWithDifferentMode(Name, usize),
+    /// error E0410: variable from pattern is not bound in pattern #1
+    VariableNotBoundInParentPattern(Name, usize),
+    /// error E0411: use of `Self` outside of an impl or trait
+    SelfUsedOutsideImplOrTrait,
+    /// error E0412: use of undeclared
+    UseOfUndeclared(&'a str, &'a str),
+    /// error E0413: declaration shadows an enum variant or unit-like struct in scope
+    DeclarationShadowsEnumVariantOrUnitLikeStruct(Name),
+    /// error E0414: only irrefutable patterns allowed here
+    OnlyIrrefutablePatternsAllowedHere,
+    /// error E0415: identifier is bound more than once in this parameter list
+    IdentifierBoundMoreThanOnceInParameterList(&'a str),
+    /// error E0416: identifier is bound more than once in the same pattern
+    IdentifierBoundMoreThanOnceInSamePattern(&'a str),
+    /// error E0417: static variables cannot be referenced in a pattern
+    StaticVariableReference,
+    /// error E0418: is not an enum variant, struct or const
+    NotAnEnumVariantStructOrConst(&'a str),
+    /// error E0419: unresolved enum variant, struct or const
+    UnresolvedEnumVariantStructOrConst(&'a str),
+    /// error E0420: is not an associated const
+    NotAnAssociatedConst(&'a str),
+    /// error E0421: unresolved associated const
+    UnresolvedAssociatedConst(&'a str),
+    /// error E0422: does not name a struct
+    DoesNotNameAStruct(&'a str),
+    /// error E0423: is a struct variant name, but this expression uses it like a function name
+    StructVariantUsedAsFunction(&'a str),
+    /// error E0424: `self` is not available in a static method
+    SelfNotAvailableInStaticMethod,
+    /// error E0425: unresolved name
+    UnresolvedName(&'a str, &'a str),
+    /// error E0426: use of undeclared label
+    UndeclaredLabel(&'a str),
+    /// error E0427: cannot use `ref` binding mode with ...
+    CannotUseRefBindingModeWith(&'a str),
+    /// error E0428: duplicate definition
+    DuplicateDefinition(&'a str, Name),
+    /// error E0429: `self` imports are only allowed within a { } list
+    SelfImportsOnlyAllowedWithin,
+    /// error E0430: `self` import can only appear once in the list
+    SelfImportCanOnlyAppearOnceInTheList,
+    /// error E0431: `self` import can only appear in an import list with a non-empty prefix
+    SelfImportOnlyInImportListWithNonEmptyPrefix,
+    /// error E0432: unresolved import
+    UnresolvedImport(Option<(&'a str, Option<&'a str>)>),
+    /// error E0433: failed to resolve
+    FailedToResolve(&'a str),
+    /// error E0434: can't capture dynamic environment in a fn item
+    CannotCaptureDynamicEnvironmentInFnItem,
+    /// error E0435: attempt to use a non-constant value in a constant
+    AttemptToUseNonConstantValueInConstant,
+}
+
+fn resolve_error<'b, 'a:'b, 'tcx:'a>(resolver: &'b Resolver<'a, 'tcx>, span: syntax::codemap::Span,
+                                     resolution_error: ResolutionError<'b>) {
+    if !resolver.emit_errors {
+        return;
+    }
+    match resolution_error {
+        ResolutionError::TypeParametersFromOuterFunction => {
+            span_err!(resolver.session, span, E0401, "can't use type parameters from \
+                                                      outer function; try using a local \
+                                                      type parameter instead");
+        },
+        ResolutionError::OuterTypeParameterContext => {
+            span_err!(resolver.session, span, E0402,
+                         "cannot use an outer type parameter in this context");
+        },
+        ResolutionError::NameAlreadyUsedInTypeParameterList(name) => {
+            span_err!(resolver.session, span, E0403,
+                         "the name `{}` is already used for a type \
+                          parameter in this type parameter list", name);
+        },
+        ResolutionError::IsNotATrait(name) => {
+            span_err!(resolver.session, span, E0404,
+                         "`{}` is not a trait",
+                         name);
+        },
+        ResolutionError::UndeclaredTraitName(name) => {
+            span_err!(resolver.session, span, E0405,
+                         "use of undeclared trait name `{}`",
+                         name);
+        },
+        ResolutionError::UndeclaredAssociatedType => {
+            span_err!(resolver.session, span, E0406, "undeclared associated type");
+        },
+        ResolutionError::MethodNotMemberOfTrait(method, trait_) => {
+            span_err!(resolver.session, span, E0407,
+                         "method `{}` is not a member of trait `{}`",
+                         method,
+                         trait_);
+        },
+        ResolutionError::VariableNotBoundInPattern(variable_name, pattern_number) => {
+            span_err!(resolver.session, span, E0408,
+                         "variable `{}` from pattern #1 is not bound in pattern #{}",
+                         variable_name,
+                         pattern_number);
+        },
+        ResolutionError::VariableBoundWithDifferentMode(variable_name, pattern_number) => {
+            span_err!(resolver.session, span, E0409,
+                         "variable `{}` is bound with different \
+                         mode in pattern #{} than in pattern #1",
+                         variable_name,
+                         pattern_number);
+        },
+        ResolutionError::VariableNotBoundInParentPattern(variable_name, pattern_number) => {
+            span_err!(resolver.session, span, E0410,
+                         "variable `{}` from pattern #{} is not bound in pattern #1",
+                         variable_name,
+                         pattern_number);
+        },
+        ResolutionError::SelfUsedOutsideImplOrTrait => {
+            span_err!(resolver.session, span, E0411, "use of `Self` outside of an impl or trait");
+        },
+        ResolutionError::UseOfUndeclared(kind, name) => {
+            span_err!(resolver.session, span, E0412,
+                         "use of undeclared {} `{}`",
+                         kind,
+                         name);
+        },
+        ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(name) => {
+            span_err!(resolver.session, span, E0413,
+                         "declaration of `{}` shadows an enum variant or unit-like struct in \
+                          scope",
+                         name);
+        },
+        ResolutionError::OnlyIrrefutablePatternsAllowedHere => {
+            span_err!(resolver.session, span, E0414, "only irrefutable patterns allowed here");
+        },
+        ResolutionError::IdentifierBoundMoreThanOnceInParameterList(identifier) => {
+            span_err!(resolver.session, span, E0415,
+                         "identifier `{}` is bound more than once in this parameter list",
+                         identifier);
+        },
+        ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(identifier) => {
+            span_err!(resolver.session, span, E0416,
+                         "identifier `{}` is bound more than once in the same pattern",
+                         identifier);
+        },
+        ResolutionError::StaticVariableReference => {
+            span_err!(resolver.session, span, E0417, "static variables cannot be \
+                                                      referenced in a pattern, \
+                                                      use a `const` instead");
+        },
+        ResolutionError::NotAnEnumVariantStructOrConst(name) => {
+            span_err!(resolver.session, span, E0418,
+                         "`{}` is not an enum variant, struct or const",
+                         name);
+        },
+        ResolutionError::UnresolvedEnumVariantStructOrConst(name) => {
+            span_err!(resolver.session, span, E0419,
+                         "unresolved enum variant, struct or const `{}`",
+                         name);
+        },
+        ResolutionError::NotAnAssociatedConst(name) => {
+            span_err!(resolver.session, span, E0420,
+                         "`{}` is not an associated const",
+                         name);
+        },
+        ResolutionError::UnresolvedAssociatedConst(name) => {
+            span_err!(resolver.session, span, E0421,
+                         "unresolved associated const `{}`",
+                         name);
+        },
+        ResolutionError::DoesNotNameAStruct(name) => {
+            span_err!(resolver.session, span, E0422, "`{}` does not name a structure", name);
+        },
+        ResolutionError::StructVariantUsedAsFunction(path_name) => {
+            span_err!(resolver.session, span, E0423,
+                         "`{}` is a struct variant name, but \
+                          this expression \
+                          uses it like a function name",
+                          path_name);
+        },
+        ResolutionError::SelfNotAvailableInStaticMethod => {
+            span_err!(resolver.session, span, E0424, "`self` is not available in a static method. \
+                                                      Maybe a `self` argument is missing?");
+        },
+        ResolutionError::UnresolvedName(path, name) => {
+            span_err!(resolver.session, span, E0425,
+                         "unresolved name `{}`{}",
+                         path,
+                         name);
+        },
+        ResolutionError::UndeclaredLabel(name) => {
+            span_err!(resolver.session, span, E0426,
+                         "use of undeclared label `{}`",
+                         name);
+        },
+        ResolutionError::CannotUseRefBindingModeWith(descr) => {
+            span_err!(resolver.session, span, E0427,
+                         "cannot use `ref` binding mode with {}",
+                         descr);
+        },
+        ResolutionError::DuplicateDefinition(namespace, name) => {
+            span_err!(resolver.session, span, E0428,
+                         "duplicate definition of {} `{}`",
+                         namespace,
+                         name);
+        },
+        ResolutionError::SelfImportsOnlyAllowedWithin => {
+            span_err!(resolver.session, span, E0429, "{}",
+                         "`self` imports are only allowed within a { } list");
+        },
+        ResolutionError::SelfImportCanOnlyAppearOnceInTheList => {
+            span_err!(resolver.session, span, E0430,
+                         "`self` import can only appear once in the list");
+        },
+        ResolutionError::SelfImportOnlyInImportListWithNonEmptyPrefix => {
+            span_err!(resolver.session, span, E0431,
+                         "`self` import can only appear in an import list with a \
+                          non-empty prefix");
+        }
+        ResolutionError::UnresolvedImport(name) => {
+            let msg = match name {
+                Some((n, Some(p))) => format!("unresolved import `{}`{}", n, p),
+                Some((n, None)) => format!("unresolved import (maybe you meant `{}::*`?)", n),
+                None => "unresolved import".to_owned()
+            };
+            span_err!(resolver.session, span, E0432, "{}", msg);
+        },
+        ResolutionError::FailedToResolve(msg) => {
+            span_err!(resolver.session, span, E0433, "failed to resolve. {}", msg);
+        },
+        ResolutionError::CannotCaptureDynamicEnvironmentInFnItem => {
+            span_err!(resolver.session, span, E0434, "{}",
+                         "can't capture dynamic environment in a fn item; \
+                          use the || { ... } closure form instead");
+        },
+        ResolutionError::AttemptToUseNonConstantValueInConstant =>{
+            span_err!(resolver.session, span, E0435,
+                         "attempt to use a non-constant value in a constant");
+        },
+    }
+}
+
 #[derive(Copy, Clone)]
 struct BindingInfo {
     span: Span,
@@ -947,8 +1202,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         if module.external_module_children.borrow().contains_key(&name) {
                 span_err!(self.session, span, E0259,
                           "an external crate named `{}` has already \
-                                   been imported into this module",
-                                  &token::get_name(name));
+                           been imported into this module",
+                          name);
         }
     }
 
@@ -960,9 +1215,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         if module.external_module_children.borrow().contains_key(&name) {
                 span_err!(self.session, span, E0260,
                           "the name `{}` conflicts with an external \
-                                   crate that has been imported into this \
-                                   module",
-                                  &token::get_name(name));
+                           crate that has been imported into this \
+                           module",
+                           name);
         }
     }
 
@@ -1041,7 +1296,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 Indeterminate => {
                     debug!("(resolving module path for import) module \
                             resolution is indeterminate: {}",
-                            token::get_name(name));
+                            name);
                     return Indeterminate;
                 }
                 Success((target, used_proxy)) => {
@@ -1052,7 +1307,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             match type_def.module_def {
                                 None => {
                                     let msg = format!("Not a module `{}`",
-                                                        token::get_name(name));
+                                                        name);
 
                                     return Failed(Some((span, msg)));
                                 }
@@ -1078,7 +1333,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         None => {
                             // There are no type bindings at all.
                             let msg = format!("Not a module `{}`",
-                                              token::get_name(name));
+                                              name);
                             return Failed(Some((span, msg)));
                         }
                     }
@@ -1200,7 +1455,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     -> ResolveResult<(Target, bool)> {
         debug!("(resolving item in lexical scope) resolving `{}` in \
                 namespace {:?} in `{}`",
-               token::get_name(name),
+               name,
                namespace,
                module_to_string(&*module_));
 
@@ -1302,9 +1557,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                               namespace,
                                               PathSearch,
                                               true) {
-                Failed(Some((span, msg))) =>
-                    self.resolve_error(span, &format!("failed to resolve. {}",
-                                                     msg)),
+                Failed(Some((span, msg))) => {
+                    resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
+                },
                 Failed(None) => (), // Continue up the search chain.
                 Indeterminate => {
                     // We couldn't see through the higher scope because of an
@@ -1469,7 +1724,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                               allow_private_imports: bool)
                               -> ResolveResult<(Target, bool)> {
         debug!("(resolving name in module) resolving `{}` in `{}`",
-               &token::get_name(name),
+               name,
                module_to_string(&*module_));
 
         // First, check the direct children of the module.
@@ -1547,7 +1802,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         // We're out of luck.
         debug!("(resolving name in module) failed to resolve `{}`",
-               &token::get_name(name));
+               name);
         return Failed(None);
     }
 
@@ -1561,12 +1816,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                          .span_to_snippet((*imports)[index].span)
                          .unwrap();
             if sn.contains("::") {
-                self.resolve_error((*imports)[index].span,
-                                   "unresolved import");
+                resolve_error(self,
+                              (*imports)[index].span,
+                              ResolutionError::UnresolvedImport(None));
             } else {
-                let err = format!("unresolved import (maybe you meant `{}::*`?)",
-                                  sn);
-                self.resolve_error((*imports)[index].span, &err[..]);
+                resolve_error(self,
+                              (*imports)[index].span,
+                              ResolutionError::UnresolvedImport(Some((&*sn, None))));
             }
         }
 
@@ -1623,7 +1879,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 match orig_module.children.borrow().get(&name) {
                     None => {
                         debug!("!!! (with scope) didn't find `{}` in `{}`",
-                               token::get_name(name),
+                               name,
                                module_to_string(&*orig_module));
                     }
                     Some(name_bindings) => {
@@ -1631,7 +1887,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             None => {
                                 debug!("!!! (with scope) didn't find module \
                                         for `{}` in `{}`",
-                                       token::get_name(name),
+                                       name,
                                        module_to_string(&*orig_module));
                             }
                             Some(module_) => {
@@ -1692,17 +1948,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             // This was an attempt to access an upvar inside a
                             // named function item. This is not allowed, so we
                             // report an error.
-
-                            self.resolve_error(span,
-                                "can't capture dynamic environment in a fn item; \
-                                 use the || { ... } closure form instead");
+                            resolve_error(
+                                self,
+                                span,
+                                ResolutionError::CannotCaptureDynamicEnvironmentInFnItem
+                            );
                             return None;
                         }
                         ConstantItemRibKind => {
                             // Still doesn't deal with upvars
-                            self.resolve_error(span,
-                                               "attempt to use a non-constant \
-                                                value in a constant");
+                            resolve_error(
+                                self,
+                                span,
+                                ResolutionError::AttemptToUseNonConstantValueInConstant
+                            );
                             return None;
                         }
                     }
@@ -1718,17 +1977,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             // This was an attempt to use a type parameter outside
                             // its scope.
 
-                            self.resolve_error(span,
-                                               "can't use type parameters from \
-                                                outer function; try using a local \
-                                                type parameter instead");
+                            resolve_error(self,
+                                          span,
+                                          ResolutionError::TypeParametersFromOuterFunction);
                             return None;
                         }
                         ConstantItemRibKind => {
                             // see #9186
-                            self.resolve_error(span,
-                                               "cannot use an outer type \
-                                                parameter in this context");
+                            resolve_error(self, span, ResolutionError::OuterTypeParameterContext);
                             return None;
                         }
                     }
@@ -1795,7 +2051,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let name = item.ident.name;
 
         debug!("(resolving item) resolving {}",
-               token::get_name(name));
+               name);
 
         match item.node {
             ItemEnum(_, ref generics) |
@@ -1921,12 +2177,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     debug!("with_type_parameter_rib: {}", type_parameter.id);
 
                     if seen_bindings.contains(&name) {
-                        self.resolve_error(type_parameter.span,
-                                           &format!("the name `{}` is already \
-                                                     used for a type \
-                                                     parameter in this type \
-                                                     parameter list",
-                                                    token::get_name(name)))
+                        resolve_error(self,
+                                      type_parameter.span,
+                                      ResolutionError::NameAlreadyUsedInTypeParameterList(
+                                        name)
+                        );
                     }
                     seen_bindings.insert(name);
 
@@ -2013,9 +2268,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 debug!("(resolving trait) found trait def: {:?}", path_res);
                 Ok(path_res)
             } else {
-                self.resolve_error(trait_path.span,
-                    &format!("`{}` is not a trait",
-                             path_names_to_string(trait_path, path_depth)));
+                resolve_error(self,
+                              trait_path.span,
+                              ResolutionError::IsNotATrait(&*path_names_to_string(trait_path,
+                                                                                   path_depth))
+                             );
 
                 // If it's a typedef, give a note
                 if let DefTy(..) = path_res.base_def {
@@ -2025,9 +2282,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 Err(())
             }
         } else {
-            let msg = format!("use of undeclared trait name `{}`",
-                              path_names_to_string(trait_path, path_depth));
-            self.resolve_error(trait_path.span, &msg);
+            resolve_error(self,
+                          trait_path.span,
+                          ResolutionError::UndeclaredTraitName(
+                            &*path_names_to_string(trait_path, path_depth))
+                         );
             Err(())
         }
     }
@@ -2045,7 +2304,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     if let Some(PathResolution { base_def: DefTyParam(..), .. }) = path_res {
                         self.record_def(eq_pred.id, path_res.unwrap());
                     } else {
-                        self.resolve_error(eq_pred.path.span, "undeclared associated type");
+                        resolve_error(self,
+                                      eq_pred.span,
+                                      ResolutionError::UndeclaredAssociatedType);
                     }
                 }
             }
@@ -2170,10 +2431,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         if let Some((did, ref trait_ref)) = self.current_trait_ref {
             if !self.trait_item_map.contains_key(&(name, did)) {
                 let path_str = path_names_to_string(&trait_ref.path, 0);
-                self.resolve_error(span,
-                                    &format!("method `{}` is not a member of trait `{}`",
-                                            token::get_name(name),
-                                            path_str));
+                resolve_error(self,
+                              span,
+                              ResolutionError::MethodNotMemberOfTrait(name,
+                                                                       &*path_str));
             }
         }
     }
@@ -2220,21 +2481,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             for (&key, &binding_0) in &map_0 {
                 match map_i.get(&key) {
                   None => {
-                    self.resolve_error(
-                        p.span,
-                        &format!("variable `{}` from pattern #1 is \
-                                  not bound in pattern #{}",
-                                token::get_name(key),
-                                i + 1));
+                    resolve_error(self,
+                                  p.span,
+                                  ResolutionError::VariableNotBoundInPattern(key,
+                                                                              i + 1));
                   }
                   Some(binding_i) => {
                     if binding_0.binding_mode != binding_i.binding_mode {
-                        self.resolve_error(
-                            binding_i.span,
-                            &format!("variable `{}` is bound with different \
-                                      mode in pattern #{} than in pattern #1",
-                                    token::get_name(key),
-                                    i + 1));
+                        resolve_error(self,
+                                      binding_i.span,
+                                      ResolutionError::VariableBoundWithDifferentMode(key,
+                                                                                       i + 1)
+                                     );
                     }
                   }
                 }
@@ -2242,12 +2500,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
             for (&key, &binding) in &map_i {
                 if !map_0.contains_key(&key) {
-                    self.resolve_error(
-                        binding.span,
-                        &format!("variable `{}` from pattern {}{} is \
-                                  not bound in pattern {}1",
-                                token::get_name(key),
-                                "#", i + 1, "#"));
+                    resolve_error(self,
+                                  binding.span,
+                                  ResolutionError::VariableNotBoundInParentPattern(key,
+                                                                                    i + 1));
                 }
             }
         }
@@ -2360,14 +2616,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             path.segments.len() > 0 &&
                             maybe_qself.is_none() &&
                             path.segments[0].identifier.name == self_type_name;
-                        let msg = if is_invalid_self_type_name {
-                            "use of `Self` outside of an impl or trait".to_string()
+                        if is_invalid_self_type_name {
+                            resolve_error(self,
+                                          ty.span,
+                                          ResolutionError::SelfUsedOutsideImplOrTrait);
                         } else {
-                            format!("use of undeclared {} `{}`",
-                                kind, path_names_to_string(path, 0))
-                        };
-
-                        self.resolve_error(ty.span, &msg[..]);
+                            resolve_error(self,
+                                          ty.span,
+                                          ResolutionError::UseOfUndeclared(
+                                                                    kind,
+                                                                    &*path_names_to_string(path,
+                                                                                           0))
+                                         );
+                        }
                     }
                 }
             }
@@ -2405,7 +2666,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 if mode == RefutableMode => {
                             debug!("(resolving pattern) resolving `{}` to \
                                     struct or enum variant",
-                                   token::get_name(renamed));
+                                   renamed);
 
                             self.enforce_default_binding_mode(
                                 pattern,
@@ -2418,17 +2679,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             });
                         }
                         FoundStructOrEnumVariant(..) => {
-                            self.resolve_error(
+                            resolve_error(
+                                self,
                                 pattern.span,
-                                &format!("declaration of `{}` shadows an enum \
-                                         variant or unit-like struct in \
-                                         scope",
-                                        token::get_name(renamed)));
+                                ResolutionError::DeclarationShadowsEnumVariantOrUnitLikeStruct(
+                                    renamed)
+                            );
                         }
                         FoundConst(def, lp) if mode == RefutableMode => {
                             debug!("(resolving pattern) resolving `{}` to \
                                     constant",
-                                   token::get_name(renamed));
+                                   renamed);
 
                             self.enforce_default_binding_mode(
                                 pattern,
@@ -2441,13 +2702,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             });
                         }
                         FoundConst(..) => {
-                            self.resolve_error(pattern.span,
-                                                  "only irrefutable patterns \
-                                                   allowed here");
+                            resolve_error(
+                                self,
+                                pattern.span,
+                                ResolutionError::OnlyIrrefutablePatternsAllowedHere
+                            );
                         }
                         BareIdentifierPatternUnresolved => {
                             debug!("(resolving pattern) binding `{}`",
-                                   token::get_name(renamed));
+                                   renamed);
 
                             let def = DefLocal(pattern.id);
 
@@ -2475,24 +2738,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     bindings_list.contains_key(&renamed) {
                                 // Forbid duplicate bindings in the same
                                 // parameter list.
-                                self.resolve_error(pattern.span,
-                                                   &format!("identifier `{}` \
-                                                            is bound more \
-                                                            than once in \
-                                                            this parameter \
-                                                            list",
-                                                           token::get_ident(
-                                                               ident))
-                                                   )
+                                resolve_error(
+                                    self,
+                                    pattern.span,
+                                    ResolutionError::IdentifierBoundMoreThanOnceInParameterList(
+                                        &*token::get_ident(ident))
+                                );
                             } else if bindings_list.get(&renamed) ==
                                     Some(&pat_id) {
                                 // Then this is a duplicate variable in the
                                 // same disjunction, which is an error.
-                                self.resolve_error(pattern.span,
-                                    &format!("identifier `{}` is bound \
-                                             more than once in the same \
-                                             pattern",
-                                            token::get_ident(ident)));
+                                resolve_error(
+                                    self,
+                                    pattern.span,
+                                    ResolutionError::IdentifierBoundMoreThanOnceInSamePattern(
+                                        &*token::get_ident(ident))
+                                );
                             }
                             // Else, not bound in the same pattern: do
                             // nothing.
@@ -2523,10 +2784,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 self.record_def(pattern.id, path_res);
                             }
                             DefStatic(..) => {
-                                self.resolve_error(path.span,
-                                                   "static variables cannot be \
-                                                    referenced in a pattern, \
-                                                    use a `const` instead");
+                                resolve_error(&self,
+                                              path.span,
+                                              ResolutionError::StaticVariableReference);
                             }
                             _ => {
                                 // If anything ends up here entirely resolved,
@@ -2534,11 +2794,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 // partially resolved, that's OK, because it may
                                 // be a `T::CONST` that typeck will resolve.
                                 if path_res.depth == 0 {
-                                    self.resolve_error(
+                                    resolve_error(
+                                        self,
                                         path.span,
-                                        &format!("`{}` is not an enum variant, struct or const",
-                                                 token::get_ident(
-                                                     path.segments.last().unwrap().identifier)));
+                                        ResolutionError::NotAnEnumVariantStructOrConst(
+                                            &*token::get_ident(
+                                                path.segments.last().unwrap().identifier)
+                                            )
+                                    );
                                 } else {
                                     let const_name = path.segments.last().unwrap()
                                                          .identifier.name;
@@ -2549,9 +2812,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             }
                         }
                     } else {
-                        self.resolve_error(path.span,
-                            &format!("unresolved enum variant, struct or const `{}`",
-                                token::get_ident(path.segments.last().unwrap().identifier)));
+                        resolve_error(
+                            self,
+                            path.span,
+                            ResolutionError::UnresolvedEnumVariantStructOrConst(
+                                &*token::get_ident(path.segments.last().unwrap().identifier))
+                        );
                     }
                     visit::walk_path(self, path);
                 }
@@ -2583,16 +2849,24 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 self.record_def(pattern.id, path_res);
                             }
                             _ => {
-                                self.resolve_error(path.span,
-                                    &format!("`{}` is not an associated const",
-                                        token::get_ident(
-                                            path.segments.last().unwrap().identifier)));
+                                resolve_error(
+                                    self,
+                                    path.span,
+                                    ResolutionError::NotAnAssociatedConst(
+                                        &*token::get_ident(
+                                            path.segments.last().unwrap().identifier)
+                                    )
+                                );
                             }
                         }
                     } else {
-                        self.resolve_error(path.span,
-                            &format!("unresolved associated const `{}`",
-                                token::get_ident(path.segments.last().unwrap().identifier)));
+                        resolve_error(
+                            self,
+                            path.span,
+                            ResolutionError::UnresolvedAssociatedConst(
+                                &*token::get_ident(path.segments.last().unwrap().identifier)
+                            )
+                        );
                     }
                     visit::walk_pat(self, pattern);
                 }
@@ -2605,9 +2879,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         result => {
                             debug!("(resolving pattern) didn't find struct \
                                     def: {:?}", result);
-                            let msg = format!("`{}` does not name a structure",
-                                              path_names_to_string(path, 0));
-                            self.resolve_error(path.span, &msg[..]);
+                            resolve_error(
+                                self,
+                                path.span,
+                                ResolutionError::DoesNotNameAStruct(
+                                    &*path_names_to_string(path, 0))
+                            );
                         }
                     }
                     visit::walk_path(self, path);
@@ -2634,7 +2911,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             Success((target, _)) => {
                 debug!("(resolve bare identifier pattern) succeeded in \
                          finding {} at {:?}",
-                        token::get_name(name),
+                        name,
                         target.bindings.value_def.borrow());
                 match *target.bindings.value_def.borrow() {
                     None => {
@@ -2653,10 +2930,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 return FoundConst(def, LastMod(AllPublic));
                             }
                             DefStatic(..) => {
-                                self.resolve_error(span,
-                                                   "static variables cannot be \
-                                                    referenced in a pattern, \
-                                                    use a `const` instead");
+                                resolve_error(self,
+                                              span,
+                                              ResolutionError::StaticVariableReference);
                                 return BareIdentifierPatternUnresolved;
                             }
                             _ => {
@@ -2673,14 +2949,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             Failed(err) => {
                 match err {
                     Some((span, msg)) => {
-                        self.resolve_error(span, &format!("failed to resolve: {}",
-                                                         msg));
+                        resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
                     }
                     None => ()
                 }
 
                 debug!("(resolve bare identifier pattern) failed to find {}",
-                        token::get_name(name));
+                        name);
                 return BareIdentifierPatternUnresolved;
             }
         }
@@ -2903,8 +3178,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     }
                 };
 
-                self.resolve_error(span, &format!("failed to resolve. {}",
-                                                 msg));
+                resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
                 return None;
             }
             Indeterminate => panic!("indeterminate unexpected"),
@@ -2963,8 +3237,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     }
                 };
 
-                self.resolve_error(span, &format!("failed to resolve. {}",
-                                                 msg));
+                resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
                 return None;
             }
 
@@ -3038,13 +3311,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         // found a module instead. Modules don't have defs.
                         debug!("(resolving item path by identifier in lexical \
                                  scope) failed to resolve {} after success...",
-                                 token::get_name(name));
+                                 name);
                         return None;
                     }
                     Some(def) => {
                         debug!("(resolving item path in lexical scope) \
                                 resolved `{}` to item",
-                               token::get_name(name));
+                               name);
                         // This lookup is "all public" because it only searched
                         // for one identifier in the current module (couldn't
                         // have passed through reexports or anything like that.
@@ -3057,10 +3330,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             }
             Failed(err) => {
                 debug!("(resolving item path by identifier in lexical scope) \
-                         failed to resolve {}", token::get_name(name));
+                         failed to resolve {}", name);
 
                 if let Some((span, msg)) = err {
-                    self.resolve_error(span, &format!("failed to resolve. {}", msg))
+                    resolve_error(self, span, ResolutionError::FailedToResolve(&*msg))
                 }
 
                 return None;
@@ -3077,12 +3350,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         rs
     }
 
-    fn resolve_error(&self, span: Span, s: &str) {
-        if self.emit_errors {
-            self.session.span_err(span, s);
-        }
-    }
-
     fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion {
         fn extract_path_and_node_id(t: &Ty, allow: FallbackChecks)
                                                     -> Option<(Path, NodeId, FallbackChecks)> {
@@ -3268,11 +3535,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     // Check if struct variant
                     if let DefVariant(_, _, true) = path_res.base_def {
                         let path_name = path_names_to_string(path, 0);
-                        self.resolve_error(expr.span,
-                                &format!("`{}` is a struct variant name, but \
-                                          this expression \
-                                          uses it like a function name",
-                                         path_name));
+
+                        resolve_error(self,
+                                      expr.span,
+                                      ResolutionError::StructVariantUsedAsFunction(&*path_name));
 
                         let msg = format!("did you mean to write: \
                                            `{} {{ /* fields */ }}`?",
@@ -3309,11 +3575,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     match type_res.map(|r| r.base_def) {
                         Some(DefTy(struct_id, _))
                             if self.structs.contains_key(&struct_id) => {
-                                self.resolve_error(expr.span,
-                                    &format!("`{}` is a structure name, but \
-                                                this expression \
-                                                uses it like a function name",
-                                                path_name));
+                                resolve_error(
+                                    self,
+                                    expr.span,
+                                    ResolutionError::StructVariantUsedAsFunction(
+                                        &*path_name)
+                                );
 
                                 let msg = format!("did you mean to write: \
                                                      `{} {{ /* fields */ }}`?",
@@ -3340,11 +3607,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
                             if method_scope &&
                                &token::get_name(special_names::self_)[..] == path_name {
-                                    self.resolve_error(
-                                        expr.span,
-                                        "`self` is not available \
-                                         in a static method. Maybe a \
-                                         `self` argument is missing?");
+                                resolve_error(
+                                    self,
+                                    expr.span,
+                                    ResolutionError::SelfNotAvailableInStaticMethod
+                                );
                             } else {
                                 let last_name = path.segments.last().unwrap().identifier.name;
                                 let mut msg = match self.find_fallback_in_self_type(last_name) {
@@ -3368,10 +3635,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     msg = format!(". Did you mean {}?", msg)
                                 }
 
-                                self.resolve_error(
-                                    expr.span,
-                                    &format!("unresolved name `{}`{}",
-                                             path_name, msg));
+                                resolve_error(self,
+                                              expr.span,
+                                              ResolutionError::UnresolvedName(&*path_name,
+                                                                               &*msg));
                             }
                         }
                     }
@@ -3388,9 +3655,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     Some(definition) => self.record_def(expr.id, definition),
                     None => {
                         debug!("(resolving expression) didn't find struct def",);
-                        let msg = format!("`{}` does not name a structure",
-                                          path_names_to_string(path, 0));
-                        self.resolve_error(path.span, &msg[..]);
+
+                        resolve_error(self,
+                                      path.span,
+                                      ResolutionError::DoesNotNameAStruct(
+                                                                &*path_names_to_string(path, 0))
+                                     );
                     }
                 }
 
@@ -3415,10 +3685,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 let renamed = mtwt::resolve(label);
                 match self.search_label(renamed) {
                     None => {
-                        self.resolve_error(
-                            expr.span,
-                            &format!("use of undeclared label `{}`",
-                                    token::get_ident(label)))
+                        resolve_error(self,
+                                      expr.span,
+                                      ResolutionError::UndeclaredLabel(&*token::get_ident(label)))
                     }
                     Some(DlDef(def @ DefLabel(_))) => {
                         // Since this def is a label, it is never read.
@@ -3467,7 +3736,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     fn get_traits_containing_item(&mut self, name: Name) -> Vec<DefId> {
         debug!("(getting traits containing item) looking for '{}'",
-               token::get_name(name));
+               name);
 
         fn add_trait_info(found_traits: &mut Vec<DefId>,
                           trait_def_id: DefId,
@@ -3475,7 +3744,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             debug!("(adding trait info) found trait {}:{} for method '{}'",
                 trait_def_id.krate,
                 trait_def_id.node,
-                token::get_name(name));
+                name);
             found_traits.push(trait_def_id);
         }
 
@@ -3564,10 +3833,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         match pat_binding_mode {
             BindByValue(_) => {}
             BindByRef(..) => {
-                self.resolve_error(pat.span,
-                                   &format!("cannot use `ref` binding mode \
-                                            with {}",
-                                           descr));
+                resolve_error(self,
+                              pat.span,
+                              ResolutionError::CannotUseRefBindingModeWith(descr));
             }
         }
     }
@@ -3586,7 +3854,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         debug!("Children:");
         build_reduced_graph::populate_module_if_necessary(self, &module_);
         for (&name, _) in module_.children.borrow().iter() {
-            debug!("* {}", token::get_name(name));
+            debug!("* {}", name);
         }
 
         debug!("Import resolutions:");
@@ -3610,7 +3878,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                 }
             }
 
-            debug!("* {}:{}{}", token::get_name(name), value_repr, type_repr);
+            debug!("* {}:{}{}", name, value_repr, type_repr);
         }
     }
 }
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index e77e7116b9fea..e797da7b8f64b 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -22,6 +22,7 @@ use ResolveResult;
 use Resolver;
 use UseLexicalScopeFlag;
 use {names_to_string, module_to_string};
+use {resolve_error, ResolutionError};
 
 use build_reduced_graph;
 
@@ -272,12 +273,14 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                         Some((span, msg)) => (span, format!(". {}", msg)),
                         None => (import_directive.span, String::new())
                     };
-                    let msg = format!("unresolved import `{}`{}",
-                                      import_path_to_string(
-                                          &import_directive.module_path,
-                                          import_directive.subclass),
-                                      help);
-                    self.resolver.resolve_error(span, &msg[..]);
+                    resolve_error(self.resolver,
+                                    span,
+                                    ResolutionError::UnresolvedImport(
+                                                Some((&*import_path_to_string(
+                                                        &import_directive.module_path,
+                                                        import_directive.subclass),
+                                                      Some(&*help))))
+                                   );
                 }
                 ResolveResult::Indeterminate => break, // Bail out. We'll come around next time.
                 ResolveResult::Success(()) => () // Good. Continue.
@@ -394,9 +397,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                              -> ResolveResult<()> {
         debug!("(resolving single import) resolving `{}` = `{}::{}` from \
                 `{}` id {}, last private {:?}",
-               token::get_name(target),
+               target,
                module_to_string(&*target_module),
-               token::get_name(source),
+               source,
                module_to_string(module_),
                directive.id,
                lp);
@@ -431,7 +434,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                     value_result = BoundResult(target_module.clone(),
                                                (*child_name_bindings).clone());
                     if directive.is_public && !child_name_bindings.is_public(ValueNS) {
-                        let msg = format!("`{}` is private", token::get_name(source));
+                        let msg = format!("`{}` is private", source);
                         span_err!(self.resolver.session, directive.span, E0364, "{}", &msg);
                         pub_err = true;
                     }
@@ -441,7 +444,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                     type_result = BoundResult(target_module.clone(),
                                               (*child_name_bindings).clone());
                     if !pub_err && directive.is_public && !child_name_bindings.is_public(TypeNS) {
-                        let msg = format!("`{}` is private", token::get_name(source));
+                        let msg = format!("`{}` is private", source);
                         span_err!(self.resolver.session, directive.span, E0365, "{}", &msg);
                     }
                 }
@@ -655,7 +658,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
 
         if value_result.is_unbound() && type_result.is_unbound() {
             let msg = format!("There is no `{}` in `{}`",
-                              token::get_name(source),
+                              source,
                               module_to_string(&target_module));
             return ResolveResult::Failed(Some((directive.span, msg)));
         }
@@ -736,7 +739,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
         for (ident, target_import_resolution) in import_resolutions.iter() {
             debug!("(resolving glob import) writing module resolution \
                     {} into `{}`",
-                   token::get_name(*ident),
+                   *ident,
                    module_to_string(module_));
 
             if !target_import_resolution.is_public {
@@ -842,7 +845,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
 
         debug!("(resolving glob import) writing resolution `{}` in `{}` \
                to `{}`",
-               &token::get_name(name),
+               name,
                module_to_string(&*containing_module),
                module_to_string(module_));
 
@@ -861,7 +864,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                         let msg = format!("a {} named `{}` has already been imported \
                                            in this module",
                                           namespace_name,
-                                          &token::get_name(name));
+                                          name);
                         span_err!(self.resolver.session, import_directive.span, E0251, "{}", msg);
                     } else {
                         let target = Target::new(containing_module.clone(),
@@ -894,7 +897,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                                     namespace: Namespace) {
         let target = import_resolution.target_for_namespace(namespace);
         debug!("check_for_conflicting_import: {}; target exists: {}",
-               &token::get_name(name),
+               name,
                target.is_some());
 
         match target {
@@ -918,13 +921,13 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                 span_err!(self.resolver.session, import_span, E0252,
                           "a {} named `{}` has already been imported \
                            in this module", ns_word,
-                                  &token::get_name(name));
+                                  name);
                 let use_id = import_resolution.id(namespace);
                 let item = self.resolver.ast_map.expect_item(use_id);
                 // item is syntax::ast::Item;
                 span_note!(self.resolver.session, item.span,
                             "previous import of `{}` here",
-                            token::get_name(name));
+                            name);
             }
             Some(_) | None => {}
         }
@@ -938,7 +941,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                                        namespace: Namespace) {
         if !name_bindings.defined_in_namespace_with(namespace, DefModifiers::IMPORTABLE) {
             let msg = format!("`{}` is not directly importable",
-                              token::get_name(name));
+                              name);
             span_err!(self.resolver.session, import_span, E0253, "{}", &msg[..]);
         }
     }
@@ -959,7 +962,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                     let msg = format!("import `{0}` conflicts with imported \
                                        crate in this module \
                                        (maybe you meant `use {0}::*`?)",
-                                      &token::get_name(name));
+                                      name);
                     span_err!(self.resolver.session, import_span, E0254, "{}", &msg[..]);
                 }
                 Some(_) | None => {}
@@ -981,7 +984,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                 if let Some(ref value) = *name_bindings.value_def.borrow() {
                     span_err!(self.resolver.session, import_span, E0255,
                               "import `{}` conflicts with value in this module",
-                              &token::get_name(name));
+                              name);
                     if let Some(span) = value.value_span {
                         self.resolver.session.span_note(span, "conflicting value here");
                     }
@@ -1004,7 +1007,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                     };
                     span_err!(self.resolver.session, import_span, E0256,
                               "import `{}` conflicts with {}",
-                              &token::get_name(name), what);
+                              name, what);
                     if let Some(span) = ty.type_span {
                         self.resolver.session.span_note(span, note);
                     }
diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs
index c5196d09e00a1..680999717eae5 100644
--- a/src/librustc_trans/save/dump_csv.rs
+++ b/src/librustc_trans/save/dump_csv.rs
@@ -35,7 +35,6 @@ use session::Session;
 use middle::def;
 use middle::ty::{self, Ty};
 
-use std::cell::Cell;
 use std::fs::File;
 use std::path::Path;
 
@@ -76,14 +75,11 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
     pub fn new(tcx: &'l ty::ctxt<'tcx>,
                analysis: &'l ty::CrateAnalysis,
                output_file: Box<File>) -> DumpCsvVisitor<'l, 'tcx> {
-        let span_utils = SpanUtils {
-            sess: &tcx.sess,
-            err_count: Cell::new(0)
-        };
+        let span_utils = SpanUtils::new(&tcx.sess);
         DumpCsvVisitor {
             sess: &tcx.sess,
             tcx: tcx,
-            save_ctxt: SaveContext::new(tcx, span_utils.clone()),
+            save_ctxt: SaveContext::from_span_utils(tcx, span_utils.clone()),
             analysis: analysis,
             span: span_utils.clone(),
             fmt: FmtStrs::new(box Recorder {
diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs
index 4e0b34b7ef8ac..26da803de6557 100644
--- a/src/librustc_trans/save/mod.rs
+++ b/src/librustc_trans/save/mod.rs
@@ -163,9 +163,14 @@ pub struct MethodCallData {
 
 
 impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
-    pub fn new(tcx: &'l ty::ctxt<'tcx>,
-               span_utils: SpanUtils<'l>)
-               -> SaveContext<'l, 'tcx> {
+    pub fn new(tcx: &'l ty::ctxt<'tcx>) -> SaveContext <'l, 'tcx> {
+        let span_utils = SpanUtils::new(&tcx.sess);
+        SaveContext::from_span_utils(tcx, span_utils)
+    }
+
+    pub fn from_span_utils(tcx: &'l ty::ctxt<'tcx>,
+                           span_utils: SpanUtils<'l>)
+                           -> SaveContext<'l, 'tcx> {
         SaveContext {
             tcx: tcx,
             span_utils: span_utils,
@@ -527,7 +532,10 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     ref_id: def.def_id(),
                 })
             }
-            def::DefStruct(def_id) | def::DefTy(def_id, _) => {
+            def::DefStruct(def_id) |
+            def::DefTy(def_id, _) |
+            def::DefTrait(def_id) |
+            def::DefTyParam(_, _, def_id, _) => {
                 Data::TypeRefData(TypeRefData {
                     span: sub_span.unwrap(),
                     ref_id: def_id,
@@ -540,13 +548,12 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
                     let ti = self.tcx.impl_or_trait_item(decl_id);
                     match provenence {
                         def::FromTrait(def_id) => {
-                            Some(self.tcx.trait_items(def_id)
-                                    .iter()
-                                    .find(|mr| {
-                                        mr.name() == ti.name()
-                                    })
-                                    .unwrap()
-                                    .def_id())
+                            self.tcx.trait_items(def_id)
+                                .iter()
+                                .find(|mr| {
+                                    mr.name() == ti.name() && self.trait_method_has_body(mr)
+                                })
+                                .map(|mr| mr.def_id())
                         }
                         def::FromImpl(def_id) => {
                             let impl_items = self.tcx.impl_items.borrow();
@@ -586,6 +593,20 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
         }
     }
 
+    fn trait_method_has_body(&self, mr: &ty::ImplOrTraitItem) -> bool {
+        let def_id = mr.def_id();
+        if def_id.krate != ast::LOCAL_CRATE {
+            return false;
+        }
+
+        let trait_item = self.tcx.map.expect_trait_item(def_id.node);
+        if let ast::TraitItem_::MethodTraitItem(_, Some(_)) = trait_item.node {
+            true
+        } else {
+            false
+        }
+    }
+
     pub fn get_field_ref_data(&self,
                               field_ref: &ast::Field,
                               struct_id: DefId,
@@ -753,6 +774,6 @@ fn escape(s: String) -> String {
 
 // If the expression is a macro expansion or other generated code, run screaming
 // and don't index.
-fn generated_code(span: Span) -> bool {
+pub fn generated_code(span: Span) -> bool {
     span.expn_id != NO_EXPANSION || span  == DUMMY_SP
 }
diff --git a/src/librustc_trans/save/span_utils.rs b/src/librustc_trans/save/span_utils.rs
index 08cbd777c095c..ee7b1c4ff6e29 100644
--- a/src/librustc_trans/save/span_utils.rs
+++ b/src/librustc_trans/save/span_utils.rs
@@ -28,6 +28,13 @@ pub struct SpanUtils<'a> {
 }
 
 impl<'a> SpanUtils<'a> {
+    pub fn new(sess: &'a Session) -> SpanUtils<'a> {
+        SpanUtils {
+            sess: sess,
+            err_count: Cell::new(0)
+        }
+    }
+
     // Standard string for extents/location.
     pub fn extent_str(&self, span: Span) -> String {
         let lo_loc = self.sess.codemap().lookup_char_pos(span.lo);
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 5a71d1ed0b5bd..9042cedccc857 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3426,6 +3426,11 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
         let def = lookup_full_def(tcx, path.span, id);
         let struct_id = match def {
             def::DefVariant(enum_id, variant_id, true) => {
+                if let &Some(ref base_expr) = base_expr {
+                    span_err!(tcx.sess, base_expr.span, E0436,
+                              "functional record update syntax requires a struct");
+                    fcx.write_error(base_expr.id);
+                }
                 check_struct_enum_variant(fcx, id, expr.span, enum_id,
                                           variant_id, &fields[..]);
                 enum_id
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 5027be5fb62a3..2069e3098e638 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -2209,6 +2209,7 @@ register_diagnostics! {
     E0392, // parameter `{}` is never used
     E0393, // the type parameter `{}` must be explicitly specified in an object
            // type because its default value `{}` references the type `Self`"
-    E0399  // trait items need to be implemented because the associated
+    E0399, // trait items need to be implemented because the associated
            // type `{}` was overridden
+    E0436  // functional record update requires a struct
 }
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index c77cdd4d02183..1eb1556a25d26 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -701,6 +701,9 @@
             // Push and pop states are used to add search results to the browser
             // history.
             if (browserSupportsHistoryApi()) {
+                // Store the previous <title> so we can revert back to it later.
+                var previousTitle = $(document).prop("title");
+
                 $(window).on('popstate', function(e) {
                     var params = getQueryStringParams();
                     // When browsing back from search results the main page
@@ -709,6 +712,9 @@
                         $('#main.content').removeClass('hidden');
                         $('#search.content').addClass('hidden');
                     }
+                    // Revert to the previous title manually since the History
+                    // API ignores the title parameter.
+                    $(document).prop("title", previousTitle);
                     // When browsing forward to search results the previous
                     // search will be repeated, so the currentResults are
                     // cleared to ensure the search is successful.
@@ -951,3 +957,8 @@
     }());
 
 }());
+
+// Sets the focus on the search bar at the top of the page
+function focusSearchBar() {
+    document.getElementsByName('search')[0].focus();
+}
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index 7598a1c7a48f0..2c78b2894311d 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -25,6 +25,7 @@ use io::{self, SeekFrom, Seek, Read, Write};
 use path::{Path, PathBuf};
 use sys::fs as fs_imp;
 use sys_common::{AsInnerMut, FromInner, AsInner};
+use sys_common::io::read_to_end_uninitialized;
 use vec::Vec;
 
 /// A reference to an open file on the filesystem.
@@ -328,6 +329,9 @@ impl Read for File {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.inner.read(buf)
     }
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
+        unsafe { read_to_end_uninitialized(self, buf) }
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Write for File {
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 2551ffb2c056b..2447473103101 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -1449,6 +1449,8 @@ mod tests {
     use io::prelude::*;
     use io;
     use super::Cursor;
+    use test;
+    use super::repeat;
 
     #[test]
     fn read_until() {
@@ -1567,4 +1569,13 @@ mod tests {
         let mut buf = [0; 1];
         assert_eq!(0, R.take(0).read(&mut buf).unwrap());
     }
+
+    #[bench]
+    fn bench_read_to_end(b: &mut test::Bencher) {
+        b.iter(|| {
+            let mut lr = repeat(1).take(10000000);
+            let mut vec = Vec::with_capacity(1024);
+            super::read_to_end(&mut lr, &mut vec);
+        });
+    }
 }
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index 62bbb939a71f5..d8b7c8a282ca2 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -18,6 +18,7 @@ use io::lazy::Lazy;
 use io::{self, BufReader, LineWriter};
 use sync::{Arc, Mutex, MutexGuard};
 use sys::stdio;
+use sys_common::io::{read_to_end_uninitialized};
 use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
 use libc;
 
@@ -277,6 +278,9 @@ impl<'a> Read for StdinLock<'a> {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
         self.inner.read(buf)
     }
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
+        unsafe { read_to_end_uninitialized(self, buf) }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 53423cd5148c8..fa90670acfbef 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -10,29 +10,116 @@
 
 //! # The Rust Standard Library
 //!
-//! The Rust Standard Library provides the essential runtime
-//! functionality for building portable Rust software.
+//! The Rust Standard Library is the foundation of portable Rust
+//! software, a set of minimal and battle-tested shared abstractions
+//! for the [broader Rust ecosystem](https://crates.io). It offers
+//! core types (e.g. [`Vec`](vec/index.html)
+//! and [`Option`](option/index.html)), library-defined [operations on
+//! language primitives](#primitive) (e.g. [`u32`](u32/index.html) and
+//! [`str`](str/index.html)), [standard macros](#macros),
+//! [I/O](io/index.html) and [multithreading](thread/index.html), among
+//! [many other lovely
+//! things](#what-is-in-the-standard-library-documentation?).
 //!
-//! The Rust Standard Library is available to all Rust crates by
-//! default, just as if contained an `extern crate std` import at the
-//! crate root. Therefore the standard library can be accessed in
-//! `use` statements through the path `std`, as in `use std::thread`,
-//! or in expressions through the absolute path `::std`, as in
-//! `::std::thread::sleep_ms(100)`.
+//! `std` is available to all Rust crates by default, just as if each
+//! one contained an `extern crate std` import at the [crate
+//! root][book-crate-root]. Therefore the standard library can be
+//! accessed in [`use`][book-use] statements through the path `std`,
+//! as in [`use std::env`](env/index.html), or in expressions
+//! through the absolute path `::std`, as in
+//! [`::std::env::args()`](env/fn.args.html).
 //!
-//! Furthermore, the standard library defines [The Rust
-//! Prelude](prelude/index.html), a small collection of items, mostly
-//! traits, that are imported into and available in every module.
+//! [book-crate-root]: ../book/crates-and-modules.html#basic-terminology:-crates-and-modules
+//! [book-use]: ../book/crates-and-modules.html#importing-modules-with-use
 //!
-//! ## What is in the standard library
+//! # How to read this documentation
 //!
-//! The standard library is a set of minimal, battle-tested
-//! core types and shared abstractions for the [broader Rust
-//! ecosystem](https://crates.io) to build on.
+//! If you already know the name of what you are looking for the
+//! fastest way to find it is to use the <a href="#"
+//! onclick="focusSearchBar();">search bar</a> at the top of the page.
 //!
-//! The [primitive types](#primitives), though not defined in the
-//! standard library, are documented here, as are the predefined
-//! [macros](#macros).
+//! Otherwise, you may want to jump to one of these useful sections:
+//!
+//! * [`std::*` modules](#modules)
+//! * [Primitive types](#primitives)
+//! * [Standard macros](#macros)
+//! * [The Rust Prelude](prelude/index.html)
+//!
+//! If this is your first time, the documentation for the standard
+//! library is written to be casually perused. Clicking on interesting
+//! things should generally lead you to interesting places. Still,
+//! there are important bits you don't want to miss, so read on for a
+//! tour of the standard library and its documentation!
+//!
+//! Once you are familiar with the contents of the standard library
+//! you may begin to find the verbosity of the prose distracting. At
+//! this stage in your development you may want to press the **[-]**
+//! button near the top of the page to collapse it into a more
+//! skimmable view.
+//!
+//! While you are looking at that **[-]** button also notice the
+//! **[src]** button. Rust's API documentation comes with the source
+//! code and you are encouraged to read it. The standard library
+//! source is generally high quality and a peek behind the curtains is
+//! often enlightening.
+//!
+//! # What is in the standard library documentation?
+//!
+//! Lots of stuff. Well, broadly four things actually.
+//!
+//! First of all, The Rust Standard Library is divided into a number
+//! of focused modules, [all listed further down this page](#modules).
+//! These modules are the bedrock upon which all of Rust is forged,
+//! and they have mighty names like [`std::slice`](slice/index.html)
+//! and [`std::cmp`](cmp/index.html). Modules' documentation typically
+//! includes an overview of the module along with examples, and are
+//! a smart place to start familiarizing yourself with the library.
+//!
+//! Second, implicit methods on [primitive
+//! types](../book/primitive-types.html) are documented here. This can
+//! be a source of confusion for two reasons:
+//!
+//! 1. While primitives are implemented by the compiler, the standard
+//!    library implements methods directly on the primitive types (and
+//!    it is the only library that does so), which are [documented in
+//!    the section on primitives](#primitives).
+//! 2. The standard library exports many modules *with the same name
+//!    as primitive types*. These define additional items related
+//!    to the primitive type, but not the all-important methods.
+//!
+//! So for example there is a [page for the primitive type
+//! `i32`](primitive.i32.html) that lists all the methods that can be
+//! called on 32-bit integers (mega useful), and there is a [page for
+//! the module `std::i32`](i32/index.html) that documents the constant
+//! values `MIN` and `MAX` (rarely useful).
+//!
+//! Note the documentation for the primitives
+//! [`str`](primitive.str.html) and [`[T]`](primitive.slice.html)
+//! (also called 'slice'). Many method calls on
+//! [`String`](string/struct.String.html) and
+//! [`Vec`](vec/struct.Vec.html) are actually calls to methods on
+//! `str` and `[T]` respectively, via [deref
+//! coercions](../book/deref-coercions.html). *Accepting that
+//! primitive types are documented on their own pages will bring you a
+//! deep inner wisdom. Embrace it now before proceeding.*
+//!
+//! Third, the standard library defines [The Rust
+//! Prelude](prelude/index.html), a small collection of items - mostly
+//! traits - that are imported into every module of every crate. The
+//! traits in the prelude are pervasive, making the prelude
+//! documentation a good entry point to learning about the library.
+//!
+//! And finally, the standard library exports a number of standard
+//! macros, and [lists them on this page](#macros) (technically, not
+//! all of the standard macros are defined by the standard library -
+//! some are defined by the compiler - but they are documented here
+//! the same). Like the prelude, the standard macros are imported by
+//! default into all crates.
+//!
+//! # A Tour of The Rust Standard Library
+//!
+//! The rest of this crate documentation is dedicated to pointing
+//! out notable features of The Rust Standard Library.
 //!
 //! ## Containers and collections
 //!
@@ -43,17 +130,29 @@
 //! [`Iterator`](iter/trait.Iterator.html), which works with the `for`
 //! loop to access collections.
 //!
-//! The common container type, `Vec`, a growable vector backed by an array,
-//! lives in the [`vec`](vec/index.html) module. Contiguous, unsized regions
-//! of memory, `[T]`, commonly called "slices", and their borrowed versions,
-//! `&[T]`, commonly called "borrowed slices", are built-in types for which the
-//! [`slice`](slice/index.html) module defines many methods.
+//! The standard library exposes 3 common ways to deal with contiguous
+//! regions of memory:
 //!
-//! `&str`, a UTF-8 string, is a built-in type, and the standard library
-//! defines methods for it on a variety of traits in the
-//! [`str`](str/index.html) module. Rust strings are immutable;
-//! use the `String` type defined in [`string`](string/index.html)
-//! for a mutable string builder.
+//! * [`Vec<T>`](vec/index.html) - A heap-allocated *vector* that is
+//! resizable at runtime.
+//! * [`[T; n]`](primitive.array.html) - An inline *array* with a
+//! fixed size at compile time.
+//! * [`[T]`](primitive.slice.html) - A dynamically sized *slice* into
+//! any other kind of contiguous storage, whether heap-allocated or
+//! not.
+//!
+//! Slices can only be handled through some kind of *pointer*, and as
+//! such come in many flavours such as:
+//!
+//! * `&[T]` - *shared slice*
+//! * `&mut [T]` - *mutable slice*
+//! * [`Box<[T]>`](boxed/index.html) - *owned slice*
+//!
+//! `str`, a UTF-8 string slice, is a primitive type, and the standard
+//! library defines [many methods for it](primitive.str.html). Rust
+//! `str`s are typically accessed as immutable references: `&str`. Use
+//! the owned `String` type defined in [`string`](string/index.html)
+//! for building and mutating strings.
 //!
 //! For converting to strings use the [`format!`](fmt/index.html)
 //! macro, and for converting from strings use the
@@ -88,6 +187,7 @@
 //! [`atomic`](sync/atomic/index.html) and
 //! [`mpsc`](sync/mpsc/index.html), which contains the channel types
 //! for message passing.
+//!
 
 // Do not remove on snapshot creation. Needed for bootstrap. (Issue #22364)
 #![cfg_attr(stage0, feature(custom_attribute))]
diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs
index 085ba286dc3d9..66c8403b2685e 100644
--- a/src/libstd/net/tcp.rs
+++ b/src/libstd/net/tcp.rs
@@ -19,6 +19,7 @@ use io;
 use net::{ToSocketAddrs, SocketAddr, Shutdown};
 use sys_common::net as net_imp;
 use sys_common::{AsInner, FromInner};
+use sys_common::io::read_to_end_uninitialized;
 use time::Duration;
 
 /// A structure which represents a TCP stream between a local socket and a
@@ -189,6 +190,9 @@ impl TcpStream {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Read for TcpStream {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
+        unsafe { read_to_end_uninitialized(self, buf) }
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Write for TcpStream {
@@ -198,6 +202,9 @@ impl Write for TcpStream {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Read for &'a TcpStream {
     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
+    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
+        unsafe { read_to_end_uninitialized(self, buf) }
+    }
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Write for &'a TcpStream {
diff --git a/src/libstd/prelude/mod.rs b/src/libstd/prelude/mod.rs
index 156a3d428debd..275f415c6fc80 100644
--- a/src/libstd/prelude/mod.rs
+++ b/src/libstd/prelude/mod.rs
@@ -22,18 +22,107 @@
 //! with the `std::` path prefix, as in `use std::vec`, `use std::thread::spawn`,
 //! etc.
 //!
-//! Additionally, `std` contains a `prelude` module that reexports many of the
-//! most common traits, types and functions. The contents of the prelude are
-//! imported into every *module* by default.  Implicitly, all modules behave as if
-//! they contained the following prologue:
+//! Additionally, `std` contains a versioned *prelude* that reexports many of the
+//! most common traits, types and functions. *The contents of the prelude are
+//! imported into every module by default*.  Implicitly, all modules behave as if
+//! they contained the following [`use` statement][book-use]:
+//!
+//! [book-use]: ../../book/crates-and-modules.html#importing-modules-with-use
 //!
 //! ```ignore
 //! use std::prelude::v1::*;
 //! ```
 //!
-//! The prelude is primarily concerned with exporting *traits* that are so
-//! pervasive that it would be obnoxious to import for every use, particularly
-//! those that define methods on primitive types.
+//! The prelude is primarily concerned with exporting *traits* that
+//! are so pervasive that they would be onerous to import for every use,
+//! particularly those that are commonly mentioned in [generic type
+//! bounds][book-traits].
+//!
+//! The current version of the prelude (version 1) lives in
+//! [`std::prelude::v1`](v1/index.html), and reexports the following.
+//!
+//! * `std::marker::`{
+//!     [`Copy`](../marker/trait.Copy.html),
+//!     [`Send`](../marker/trait.Send.html),
+//!     [`Sized`](../marker/trait.Sized.html),
+//!     [`Sync`](../marker/trait.Sync.html)
+//!   }.
+//!   The marker traits indicate fundamental properties of types.
+//! * `std::ops::`{
+//!     [`Drop`](../ops/trait.Drop.html),
+//!     [`Fn`](../ops/trait.Fn.html),
+//!     [`FnMut`](../ops/trait.FnMut.html),
+//!     [`FnOnce`](../ops/trait.FnOnce.html)
+//!   }.
+//!   The [destructor][book-dtor] trait and the
+//!   [closure][book-closures] traits, reexported from the same
+//!   [module that also defines overloaded
+//!   operators](../ops/index.html).
+//! * `std::mem::`[`drop`](../mem/fn.drop.html).
+//!   A convenience function for explicitly dropping a value.
+//! * `std::boxed::`[`Box`](../boxed/struct.Box.html).
+//!   The owned heap pointer.
+//! * `std::borrow::`[`ToOwned`](../borrow/trait.ToOwned.html).
+//!   The conversion trait that defines `to_owned`, the generic method
+//!   for creating an owned type from a borrowed type.
+//! * `std::clone::`[`Clone`](../clone/trait.Clone.html).
+//!   The ubiquitous trait that defines `clone`, the method for
+//!   producing copies of values that are consider expensive to copy.
+//! * `std::cmp::`{
+//!     [`PartialEq`](../cmp/trait.PartialEq.html),
+//!     [`PartialOrd`](../cmp/trait.PartialOrd.html),
+//!     [`Eq`](../cmp/trait.Eq.html),
+//!     [`Ord`](../cmp/trait.Ord.html)
+//!   }.
+//!   The comparision traits, which implement the comparison operators
+//!   and are often seen in trait bounds.
+//! * `std::convert::`{
+//!     [`AsRef`](../convert/trait.AsRef.html),
+//!     [`AsMut`](../convert/trait.AsMut.html),
+//!     [`Into`](../convert/trait.Into.html),
+//!     [`From`](../convert/trait.From.html)
+//!   }.
+//!   Generic conversions, used by savvy API authors to create
+//!   overloaded methods.
+//! * `std::default::`[`Default`](../default/trait.Default).
+//!   Types that have default values.
+//! * `std::iter::`{
+//!     [`Iterator`](../iter/trait.Iterator.html),
+//!     [`Extend`](../iter/trait.Extend.html),
+//!     [`IntoIterator`](../iter/trait.IntoIterator.html),
+//!     [`DoubleEndedIterator`](../iter/trait.DoubleEndedIterator.html),
+//!     [`ExactSizeIterator`](../iter/trait.ExactSizeIterator.html)
+//!   }.
+//!   [Iterators][book-iter].
+//! * `std::option::Option::`{
+//!     [`self`](../option/enum.Option.html),
+//!     [`Some`](../option/enum.Option.html),
+//!     [`None`](../option/enum.Option.html)
+//!   }.
+//!   The ubiquitous `Option` type and its two [variants][book-enums],
+//!   `Some` and `None`.
+//! * `std::result::Result::`{
+//!     [`self`](../result/enum.Result.html),
+//!     [`Some`](../result/enum.Result.html),
+//!     [`None`](../result/enum.Result.html)
+//!   }.
+//!   The ubiquitous `Result` type and its two [variants][book-enums],
+//!   `Ok` and `Err`.
+//! * `std::slice::`[`SliceConcatExt`](../slice/trait.SliceConcatExt.html).
+//!   An unstable extension to slices that shouldn't have to exist.
+//! * `std::string::`{
+//!     [`String`](../string/struct.String.html),
+//!     [`ToString`](../string/trait.ToString.html)
+//!   }.
+//!   Heap allocated strings.
+//! * `std::vec::`[`Vec`](../vec/struct.Vec.html).
+//!   Heap allocated vectors.
+//!
+//! [book-traits]: ../../book/traits.html
+//! [book-closures]: ../../book/closures.html
+//! [book-dtor]: ../../book/drop.html
+//! [book-iter]: ../../book/iterators.html
+//! [book-enums]: ../../book/enums.html
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/src/libstd/sys/common/io.rs b/src/libstd/sys/common/io.rs
new file mode 100644
index 0000000000000..151d853fc9f7e
--- /dev/null
+++ b/src/libstd/sys/common/io.rs
@@ -0,0 +1,139 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+use prelude::v1::*;
+use io;
+use io::ErrorKind;
+use io::Read;
+use slice::from_raw_parts_mut;
+
+// Provides read_to_end functionality over an uninitialized buffer.
+// This function is unsafe because it calls the underlying
+// read function with a slice into uninitialized memory. The default
+// implementation of read_to_end for readers will zero out new memory in
+// the buf before passing it to read, but avoiding this zero can often
+// lead to a fairly significant performance win.
+//
+// Implementations using this method have to adhere to two guarantees:
+//  *  The implementation of read never reads the buffer provided.
+//  *  The implementation of read correctly reports how many bytes were written.
+pub unsafe fn read_to_end_uninitialized(r: &mut Read, buf: &mut Vec<u8>) -> io::Result<usize> {
+
+    let start_len = buf.len();
+    buf.reserve(16);
+
+    // Always try to read into the empty space of the vector (from the length to the capacity).
+    // If the vector ever fills up then we reserve an extra byte which should trigger the normal
+    // reallocation routines for the vector, which will likely double the size.
+    //
+    // This function is similar to the read_to_end function in std::io, but the logic about
+    // reservations and slicing is different enough that this is duplicated here.
+    loop {
+        if buf.len() == buf.capacity() {
+            buf.reserve(1);
+        }
+
+        let buf_slice = from_raw_parts_mut(buf.as_mut_ptr().offset(buf.len() as isize),
+                                           buf.capacity() - buf.len());
+
+        match r.read(buf_slice) {
+            Ok(0) => { return Ok(buf.len() - start_len); }
+            Ok(n) => { let len = buf.len() + n; buf.set_len(len); },
+            Err(ref e) if e.kind() == ErrorKind::Interrupted => { }
+            Err(e) => { return Err(e); }
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use prelude::v1::*;
+    use io::prelude::*;
+    use super::*;
+    use io;
+    use io::{ErrorKind, Take, Repeat, repeat};
+    use test;
+    use slice::from_raw_parts;
+
+    struct ErrorRepeat {
+        lr: Take<Repeat>
+    }
+
+    fn error_repeat(byte: u8, limit: u64) -> ErrorRepeat {
+        ErrorRepeat { lr: repeat(byte).take(limit) }
+    }
+
+    impl Read for ErrorRepeat {
+        fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+            let ret = self.lr.read(buf);
+            if let Ok(0) = ret {
+                return Err(io::Error::new(ErrorKind::Other, ""))
+            }
+            ret
+        }
+    }
+
+    fn init_vec_data() -> Vec<u8> {
+        let mut vec = vec![10u8; 200];
+        unsafe { vec.set_len(0); }
+        vec
+    }
+
+    fn assert_all_eq(buf: &[u8], value: u8) {
+        for n in buf {
+            assert_eq!(*n, value);
+        }
+    }
+
+    fn validate(buf: &Vec<u8>, good_read_len: usize) {
+        assert_all_eq(buf, 1u8);
+        let cap = buf.capacity();
+        let end_slice = unsafe { from_raw_parts(buf.as_ptr().offset(good_read_len as isize),
+                                                    cap - good_read_len) };
+        assert_all_eq(end_slice, 10u8);
+    }
+
+    #[test]
+    fn read_to_end_uninit_error() {
+        let mut er = error_repeat(1,100);
+        let mut vec = init_vec_data();
+        if let Err(_) = unsafe { read_to_end_uninitialized(&mut er, &mut vec) } {
+            validate(&vec, 100);
+        } else {
+            assert!(false);
+        }
+    }
+
+    #[test]
+    fn read_to_end_uninit_zero_len_vec() {
+        let mut er = repeat(1).take(100);
+        let mut vec = Vec::new();
+        let n = unsafe{ read_to_end_uninitialized(&mut er, &mut vec).unwrap() };
+        assert_all_eq(&vec, 1u8);
+        assert_eq!(vec.len(), n);
+    }
+
+    #[test]
+    fn read_to_end_uninit_good() {
+        let mut er = repeat(1).take(100);
+        let mut vec = init_vec_data();
+        let n = unsafe{ read_to_end_uninitialized(&mut er, &mut vec).unwrap() };
+        validate(&vec, 100);
+        assert_eq!(vec.len(), n);
+    }
+
+    #[bench]
+    fn bench_uninitialized(b: &mut test::Bencher) {
+        b.iter(|| {
+            let mut lr = repeat(1).take(10000000);
+            let mut vec = Vec::with_capacity(1024);
+            unsafe { read_to_end_uninitialized(&mut lr, &mut vec) };
+        });
+    }
+}
diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs
index b528575bbed33..69c54f9891759 100644
--- a/src/libstd/sys/common/mod.rs
+++ b/src/libstd/sys/common/mod.rs
@@ -16,6 +16,7 @@ pub mod backtrace;
 pub mod condvar;
 pub mod mutex;
 pub mod net;
+pub mod io;
 pub mod poison;
 pub mod remutex;
 pub mod rwlock;
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index ec93d2c553627..fbf015169f858 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -308,63 +308,6 @@ impl Level {
     }
 }
 
-fn print_maybe_styled(w: &mut EmitterWriter,
-                      msg: &str,
-                      color: term::attr::Attr) -> io::Result<()> {
-    match w.dst {
-        Terminal(ref mut t) => {
-            try!(t.attr(color));
-            // If `msg` ends in a newline, we need to reset the color before
-            // the newline. We're making the assumption that we end up writing
-            // to a `LineBufferedWriter`, which means that emitting the reset
-            // after the newline ends up buffering the reset until we print
-            // another line or exit. Buffering the reset is a problem if we're
-            // sharing the terminal with any other programs (e.g. other rustc
-            // instances via `make -jN`).
-            //
-            // Note that if `msg` contains any internal newlines, this will
-            // result in the `LineBufferedWriter` flushing twice instead of
-            // once, which still leaves the opportunity for interleaved output
-            // to be miscolored. We assume this is rare enough that we don't
-            // have to worry about it.
-            if msg.ends_with("\n") {
-                try!(t.write_all(msg[..msg.len()-1].as_bytes()));
-                try!(t.reset());
-                try!(t.write_all(b"\n"));
-            } else {
-                try!(t.write_all(msg.as_bytes()));
-                try!(t.reset());
-            }
-            Ok(())
-        }
-        Raw(ref mut w) => w.write_all(msg.as_bytes()),
-    }
-}
-
-fn print_diagnostic(dst: &mut EmitterWriter, topic: &str, lvl: Level,
-                    msg: &str, code: Option<&str>) -> io::Result<()> {
-    if !topic.is_empty() {
-        try!(write!(&mut dst.dst, "{} ", topic));
-    }
-
-    try!(print_maybe_styled(dst,
-                            &format!("{}: ", lvl.to_string()),
-                            term::attr::ForegroundColor(lvl.color())));
-    try!(print_maybe_styled(dst,
-                            &format!("{}", msg),
-                            term::attr::Bold));
-
-    match code {
-        Some(code) => {
-            let style = term::attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
-            try!(print_maybe_styled(dst, &format!(" [{}]", code.clone()), style));
-        }
-        None => ()
-    }
-    try!(write!(&mut dst.dst, "\n"));
-    Ok(())
-}
-
 pub struct EmitterWriter {
     dst: Destination,
     registry: Option<diagnostics::registry::Registry>
@@ -401,6 +344,392 @@ impl EmitterWriter {
                registry: Option<diagnostics::registry::Registry>) -> EmitterWriter {
         EmitterWriter { dst: Raw(dst), registry: registry }
     }
+
+    fn print_maybe_styled(&mut self,
+                          msg: &str,
+                          color: term::attr::Attr) -> io::Result<()> {
+        match self.dst {
+            Terminal(ref mut t) => {
+                try!(t.attr(color));
+                // If `msg` ends in a newline, we need to reset the color before
+                // the newline. We're making the assumption that we end up writing
+                // to a `LineBufferedWriter`, which means that emitting the reset
+                // after the newline ends up buffering the reset until we print
+                // another line or exit. Buffering the reset is a problem if we're
+                // sharing the terminal with any other programs (e.g. other rustc
+                // instances via `make -jN`).
+                //
+                // Note that if `msg` contains any internal newlines, this will
+                // result in the `LineBufferedWriter` flushing twice instead of
+                // once, which still leaves the opportunity for interleaved output
+                // to be miscolored. We assume this is rare enough that we don't
+                // have to worry about it.
+                if msg.ends_with("\n") {
+                    try!(t.write_all(msg[..msg.len()-1].as_bytes()));
+                    try!(t.reset());
+                    try!(t.write_all(b"\n"));
+                } else {
+                    try!(t.write_all(msg.as_bytes()));
+                    try!(t.reset());
+                }
+                Ok(())
+            }
+            Raw(ref mut w) => w.write_all(msg.as_bytes()),
+        }
+    }
+
+    fn print_diagnostic(&mut self, topic: &str, lvl: Level,
+                        msg: &str, code: Option<&str>) -> io::Result<()> {
+        if !topic.is_empty() {
+            try!(write!(&mut self.dst, "{} ", topic));
+        }
+
+        try!(self.print_maybe_styled(&format!("{}: ", lvl.to_string()),
+                                     term::attr::ForegroundColor(lvl.color())));
+        try!(self.print_maybe_styled(&format!("{}", msg),
+                                     term::attr::Bold));
+
+        match code {
+            Some(code) => {
+                let style = term::attr::ForegroundColor(term::color::BRIGHT_MAGENTA);
+                try!(self.print_maybe_styled(&format!(" [{}]", code.clone()), style));
+            }
+            None => ()
+        }
+        try!(write!(&mut self.dst, "\n"));
+        Ok(())
+    }
+
+    fn emit_(&mut self, cm: &codemap::CodeMap, rsp: RenderSpan,
+             msg: &str, code: Option<&str>, lvl: Level) -> io::Result<()> {
+        let sp = rsp.span();
+
+        // We cannot check equality directly with COMMAND_LINE_SP
+        // since PartialEq is manually implemented to ignore the ExpnId
+        let ss = if sp.expn_id == COMMAND_LINE_EXPN {
+            "<command line option>".to_string()
+        } else if let EndSpan(_) = rsp {
+            let span_end = Span { lo: sp.hi, hi: sp.hi, expn_id: sp.expn_id};
+            cm.span_to_string(span_end)
+        } else {
+            cm.span_to_string(sp)
+        };
+
+        try!(self.print_diagnostic(&ss[..], lvl, msg, code));
+
+        match rsp {
+            FullSpan(_) => {
+                try!(self.highlight_lines(cm, sp, lvl, cm.span_to_lines(sp)));
+                try!(self.print_macro_backtrace(cm, sp));
+            }
+            EndSpan(_) => {
+                try!(self.end_highlight_lines(cm, sp, lvl, cm.span_to_lines(sp)));
+                try!(self.print_macro_backtrace(cm, sp));
+            }
+            Suggestion(_, ref suggestion) => {
+                try!(self.highlight_suggestion(cm, sp, suggestion));
+                try!(self.print_macro_backtrace(cm, sp));
+            }
+            FileLine(..) => {
+                // no source text in this case!
+            }
+        }
+
+        match code {
+            Some(code) =>
+                match self.registry.as_ref().and_then(|registry| registry.find_description(code)) {
+                    Some(_) => {
+                        try!(self.print_diagnostic(&ss[..], Help,
+                                                   &format!("run `rustc --explain {}` to see a \
+                                                             detailed explanation", code), None));
+                    }
+                    None => ()
+                },
+            None => (),
+        }
+        Ok(())
+    }
+
+    fn highlight_suggestion(&mut self,
+                            cm: &codemap::CodeMap,
+                            sp: Span,
+                            suggestion: &str)
+                            -> io::Result<()>
+    {
+        let lines = cm.span_to_lines(sp).unwrap();
+        assert!(!lines.lines.is_empty());
+
+        // To build up the result, we want to take the snippet from the first
+        // line that precedes the span, prepend that with the suggestion, and
+        // then append the snippet from the last line that trails the span.
+        let fm = &lines.file;
+
+        let first_line = &lines.lines[0];
+        let prefix = fm.get_line(first_line.line_index)
+                       .map(|l| &l[..first_line.start_col.0])
+                       .unwrap_or("");
+
+        let last_line = lines.lines.last().unwrap();
+        let suffix = fm.get_line(last_line.line_index)
+                       .map(|l| &l[last_line.end_col.0..])
+                       .unwrap_or("");
+
+        let complete = format!("{}{}{}", prefix, suggestion, suffix);
+
+        // print the suggestion without any line numbers, but leave
+        // space for them. This helps with lining up with previous
+        // snippets from the actual error being reported.
+        let fm = &*lines.file;
+        let mut lines = complete.lines();
+        for (line, line_index) in lines.by_ref().take(MAX_LINES).zip(first_line.line_index..) {
+            let elided_line_num = format!("{}", line_index+1);
+            try!(write!(&mut self.dst, "{0}:{1:2$} {3}\n",
+                        fm.name, "", elided_line_num.len(), line));
+        }
+
+        // if we elided some lines, add an ellipsis
+        if lines.next().is_some() {
+            let elided_line_num = format!("{}", first_line.line_index + MAX_LINES + 1);
+            try!(write!(&mut self.dst, "{0:1$} {0:2$} ...\n",
+                        "", fm.name.len(), elided_line_num.len()));
+        }
+
+        Ok(())
+    }
+
+    fn highlight_lines(&mut self,
+                       cm: &codemap::CodeMap,
+                       sp: Span,
+                       lvl: Level,
+                       lines: codemap::FileLinesResult)
+                       -> io::Result<()>
+    {
+        let lines = match lines {
+            Ok(lines) => lines,
+            Err(_) => {
+                try!(write!(&mut self.dst, "(internal compiler error: unprintable span)\n"));
+                return Ok(());
+            }
+        };
+
+        let fm = &*lines.file;
+
+        let line_strings: Option<Vec<&str>> =
+            lines.lines.iter()
+                       .map(|info| fm.get_line(info.line_index))
+                       .collect();
+
+        let line_strings = match line_strings {
+            None => { return Ok(()); }
+            Some(line_strings) => line_strings
+        };
+
+        // Display only the first MAX_LINES lines.
+        let all_lines = lines.lines.len();
+        let display_lines = cmp::min(all_lines, MAX_LINES);
+        let display_line_infos = &lines.lines[..display_lines];
+        let display_line_strings = &line_strings[..display_lines];
+
+        // Calculate the widest number to format evenly and fix #11715
+        assert!(display_line_infos.len() > 0);
+        let mut max_line_num = display_line_infos[display_line_infos.len() - 1].line_index + 1;
+        let mut digits = 0;
+        while max_line_num > 0 {
+            max_line_num /= 10;
+            digits += 1;
+        }
+
+        // Print the offending lines
+        for (line_info, line) in display_line_infos.iter().zip(display_line_strings) {
+            try!(write!(&mut self.dst, "{}:{:>width$} {}\n",
+                        fm.name,
+                        line_info.line_index + 1,
+                        line,
+                        width=digits));
+        }
+
+        // If we elided something, put an ellipsis.
+        if display_lines < all_lines {
+            let last_line_index = display_line_infos.last().unwrap().line_index;
+            let s = format!("{}:{} ", fm.name, last_line_index + 1);
+            try!(write!(&mut self.dst, "{0:1$}...\n", "", s.len()));
+        }
+
+        // FIXME (#3260)
+        // If there's one line at fault we can easily point to the problem
+        if lines.lines.len() == 1 {
+            let lo = cm.lookup_char_pos(sp.lo);
+            let mut digits = 0;
+            let mut num = (lines.lines[0].line_index + 1) / 10;
+
+            // how many digits must be indent past?
+            while num > 0 { num /= 10; digits += 1; }
+
+            let mut s = String::new();
+            // Skip is the number of characters we need to skip because they are
+            // part of the 'filename:line ' part of the previous line.
+            let skip = fm.name.chars().count() + digits + 3;
+            for _ in 0..skip {
+                s.push(' ');
+            }
+            if let Some(orig) = fm.get_line(lines.lines[0].line_index) {
+                let mut col = skip;
+                let mut lastc = ' ';
+                let mut iter = orig.chars().enumerate();
+                for (pos, ch) in iter.by_ref() {
+                    lastc = ch;
+                    if pos >= lo.col.to_usize() { break; }
+                    // Whenever a tab occurs on the previous line, we insert one on
+                    // the error-point-squiggly-line as well (instead of a space).
+                    // That way the squiggly line will usually appear in the correct
+                    // position.
+                    match ch {
+                        '\t' => {
+                            col += 8 - col%8;
+                            s.push('\t');
+                        },
+                        _ => {
+                            col += 1;
+                            s.push(' ');
+                        },
+                    }
+                }
+
+                try!(write!(&mut self.dst, "{}", s));
+                let mut s = String::from("^");
+                let count = match lastc {
+                    // Most terminals have a tab stop every eight columns by default
+                    '\t' => 8 - col%8,
+                    _ => 1,
+                };
+                col += count;
+                s.extend(::std::iter::repeat('~').take(count));
+
+                let hi = cm.lookup_char_pos(sp.hi);
+                if hi.col != lo.col {
+                    for (pos, ch) in iter {
+                        if pos >= hi.col.to_usize() { break; }
+                        let count = match ch {
+                            '\t' => 8 - col%8,
+                            _ => 1,
+                        };
+                        col += count;
+                        s.extend(::std::iter::repeat('~').take(count));
+                    }
+                }
+
+                if s.len() > 1 {
+                    // One extra squiggly is replaced by a "^"
+                    s.pop();
+                }
+
+                try!(self.print_maybe_styled(&format!("{}\n", s),
+                                             term::attr::ForegroundColor(lvl.color())));
+            }
+        }
+        Ok(())
+    }
+
+    /// Here are the differences between this and the normal `highlight_lines`:
+    /// `end_highlight_lines` will always put arrow on the last byte of the
+    /// span (instead of the first byte). Also, when the span is too long (more
+    /// than 6 lines), `end_highlight_lines` will print the first line, then
+    /// dot dot dot, then last line, whereas `highlight_lines` prints the first
+    /// six lines.
+    #[allow(deprecated)]
+    fn end_highlight_lines(&mut self,
+                           cm: &codemap::CodeMap,
+                           sp: Span,
+                           lvl: Level,
+                           lines: codemap::FileLinesResult)
+                          -> io::Result<()> {
+        let lines = match lines {
+            Ok(lines) => lines,
+            Err(_) => {
+                try!(write!(&mut self.dst, "(internal compiler error: unprintable span)\n"));
+                return Ok(());
+            }
+        };
+
+        let fm = &*lines.file;
+
+        let lines = &lines.lines[..];
+        if lines.len() > MAX_LINES {
+            if let Some(line) = fm.get_line(lines[0].line_index) {
+                try!(write!(&mut self.dst, "{}:{} {}\n", fm.name,
+                            lines[0].line_index + 1, line));
+            }
+            try!(write!(&mut self.dst, "...\n"));
+            let last_line_index = lines[lines.len() - 1].line_index;
+            if let Some(last_line) = fm.get_line(last_line_index) {
+                try!(write!(&mut self.dst, "{}:{} {}\n", fm.name,
+                            last_line_index + 1, last_line));
+            }
+        } else {
+            for line_info in lines {
+                if let Some(line) = fm.get_line(line_info.line_index) {
+                    try!(write!(&mut self.dst, "{}:{} {}\n", fm.name,
+                                line_info.line_index + 1, line));
+                }
+            }
+        }
+        let last_line_start = format!("{}:{} ", fm.name, lines[lines.len()-1].line_index + 1);
+        let hi = cm.lookup_char_pos(sp.hi);
+        let skip = last_line_start.chars().count();
+        let mut s = String::new();
+        for _ in 0..skip {
+            s.push(' ');
+        }
+        if let Some(orig) = fm.get_line(lines[0].line_index) {
+            let iter = orig.chars().enumerate();
+            for (pos, ch) in iter {
+                // Span seems to use half-opened interval, so subtract 1
+                if pos >= hi.col.to_usize() - 1 { break; }
+                // Whenever a tab occurs on the previous line, we insert one on
+                // the error-point-squiggly-line as well (instead of a space).
+                // That way the squiggly line will usually appear in the correct
+                // position.
+                match ch {
+                    '\t' => s.push('\t'),
+                    _ => s.push(' '),
+                }
+            }
+        }
+        s.push('^');
+        s.push('\n');
+        self.print_maybe_styled(&s[..],
+                                term::attr::ForegroundColor(lvl.color()))
+    }
+
+    fn print_macro_backtrace(&mut self,
+                             cm: &codemap::CodeMap,
+                             sp: Span)
+                             -> io::Result<()> {
+        let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| -> io::Result<_> {
+            match expn_info {
+                Some(ei) => {
+                    let ss = ei.callee.span.map_or(String::new(),
+                                                   |span| cm.span_to_string(span));
+                    let (pre, post) = match ei.callee.format {
+                        codemap::MacroAttribute => ("#[", "]"),
+                        codemap::MacroBang => ("", "!"),
+                        codemap::CompilerExpansion => ("", ""),
+                    };
+                    try!(self.print_diagnostic(&ss, Note,
+                                               &format!("in expansion of {}{}{}",
+                                                        pre,
+                                                        ei.callee.name,
+                                                        post),
+                                               None));
+                    let ss = cm.span_to_string(ei.call_site);
+                    try!(self.print_diagnostic(&ss, Note, "expansion site", None));
+                    Ok(Some(ei.call_site))
+                }
+                None => Ok(None)
+        }
+        }));
+        cs.map_or(Ok(()), |call_site| self.print_macro_backtrace(cm, call_site))
+    }
 }
 
 #[cfg(unix)]
@@ -442,11 +771,11 @@ impl Emitter for EmitterWriter {
             cmsp: Option<(&codemap::CodeMap, Span)>,
             msg: &str, code: Option<&str>, lvl: Level) {
         let error = match cmsp {
-            Some((cm, COMMAND_LINE_SP)) => emit(self, cm,
+            Some((cm, COMMAND_LINE_SP)) => self.emit_(cm,
                                                 FileLine(COMMAND_LINE_SP),
                                                 msg, code, lvl),
-            Some((cm, sp)) => emit(self, cm, FullSpan(sp), msg, code, lvl),
-            None => print_diagnostic(self, "", lvl, msg, code),
+            Some((cm, sp)) => self.emit_(cm, FullSpan(sp), msg, code, lvl),
+            None => self.print_diagnostic("", lvl, msg, code),
         };
 
         match error {
@@ -457,346 +786,13 @@ impl Emitter for EmitterWriter {
 
     fn custom_emit(&mut self, cm: &codemap::CodeMap,
                    sp: RenderSpan, msg: &str, lvl: Level) {
-        match emit(self, cm, sp, msg, None, lvl) {
+        match self.emit_(cm, sp, msg, None, lvl) {
             Ok(()) => {}
             Err(e) => panic!("failed to print diagnostics: {:?}", e),
         }
     }
 }
 
-fn emit(dst: &mut EmitterWriter, cm: &codemap::CodeMap, rsp: RenderSpan,
-        msg: &str, code: Option<&str>, lvl: Level) -> io::Result<()> {
-    let sp = rsp.span();
-
-    // We cannot check equality directly with COMMAND_LINE_SP
-    // since PartialEq is manually implemented to ignore the ExpnId
-    let ss = if sp.expn_id == COMMAND_LINE_EXPN {
-        "<command line option>".to_string()
-    } else if let EndSpan(_) = rsp {
-        let span_end = Span { lo: sp.hi, hi: sp.hi, expn_id: sp.expn_id};
-        cm.span_to_string(span_end)
-    } else {
-        cm.span_to_string(sp)
-    };
-
-    try!(print_diagnostic(dst, &ss[..], lvl, msg, code));
-
-    match rsp {
-        FullSpan(_) => {
-            try!(highlight_lines(dst, cm, sp, lvl, cm.span_to_lines(sp)));
-            try!(print_macro_backtrace(dst, cm, sp));
-        }
-        EndSpan(_) => {
-            try!(end_highlight_lines(dst, cm, sp, lvl, cm.span_to_lines(sp)));
-            try!(print_macro_backtrace(dst, cm, sp));
-        }
-        Suggestion(_, ref suggestion) => {
-            try!(highlight_suggestion(dst, cm, sp, suggestion));
-            try!(print_macro_backtrace(dst, cm, sp));
-        }
-        FileLine(..) => {
-            // no source text in this case!
-        }
-    }
-
-    match code {
-        Some(code) =>
-            match dst.registry.as_ref().and_then(|registry| registry.find_description(code)) {
-                Some(_) => {
-                    try!(print_diagnostic(dst, &ss[..], Help,
-                                          &format!("run `rustc --explain {}` to see a detailed \
-                                                   explanation", code), None));
-                }
-                None => ()
-            },
-        None => (),
-    }
-    Ok(())
-}
-
-fn highlight_suggestion(err: &mut EmitterWriter,
-                        cm: &codemap::CodeMap,
-                        sp: Span,
-                        suggestion: &str)
-                        -> io::Result<()>
-{
-    let lines = cm.span_to_lines(sp).unwrap();
-    assert!(!lines.lines.is_empty());
-
-    // To build up the result, we want to take the snippet from the first
-    // line that precedes the span, prepend that with the suggestion, and
-    // then append the snippet from the last line that trails the span.
-    let fm = &lines.file;
-
-    let first_line = &lines.lines[0];
-    let prefix = fm.get_line(first_line.line_index)
-                   .map(|l| &l[..first_line.start_col.0])
-                   .unwrap_or("");
-
-    let last_line = lines.lines.last().unwrap();
-    let suffix = fm.get_line(last_line.line_index)
-                   .map(|l| &l[last_line.end_col.0..])
-                   .unwrap_or("");
-
-    let complete = format!("{}{}{}", prefix, suggestion, suffix);
-
-    // print the suggestion without any line numbers, but leave
-    // space for them. This helps with lining up with previous
-    // snippets from the actual error being reported.
-    let fm = &*lines.file;
-    let mut lines = complete.lines();
-    for (line, line_index) in lines.by_ref().take(MAX_LINES).zip(first_line.line_index..) {
-        let elided_line_num = format!("{}", line_index+1);
-        try!(write!(&mut err.dst, "{0}:{1:2$} {3}\n",
-                    fm.name, "", elided_line_num.len(), line));
-    }
-
-    // if we elided some lines, add an ellipsis
-    if lines.next().is_some() {
-        let elided_line_num = format!("{}", first_line.line_index + MAX_LINES + 1);
-        try!(write!(&mut err.dst, "{0:1$} {0:2$} ...\n",
-                    "", fm.name.len(), elided_line_num.len()));
-    }
-
-    Ok(())
-}
-
-fn highlight_lines(err: &mut EmitterWriter,
-                   cm: &codemap::CodeMap,
-                   sp: Span,
-                   lvl: Level,
-                   lines: codemap::FileLinesResult)
-                   -> io::Result<()>
-{
-    let lines = match lines {
-        Ok(lines) => lines,
-        Err(_) => {
-            try!(write!(&mut err.dst, "(internal compiler error: unprintable span)\n"));
-            return Ok(());
-        }
-    };
-
-    let fm = &*lines.file;
-
-    let line_strings: Option<Vec<&str>> =
-        lines.lines.iter()
-                   .map(|info| fm.get_line(info.line_index))
-                   .collect();
-
-    let line_strings = match line_strings {
-        None => { return Ok(()); }
-        Some(line_strings) => line_strings
-    };
-
-    // Display only the first MAX_LINES lines.
-    let all_lines = lines.lines.len();
-    let display_lines = cmp::min(all_lines, MAX_LINES);
-    let display_line_infos = &lines.lines[..display_lines];
-    let display_line_strings = &line_strings[..display_lines];
-
-    // Calculate the widest number to format evenly and fix #11715
-    assert!(display_line_infos.len() > 0);
-    let mut max_line_num = display_line_infos[display_line_infos.len() - 1].line_index + 1;
-    let mut digits = 0;
-    while max_line_num > 0 {
-        max_line_num /= 10;
-        digits += 1;
-    }
-
-    // Print the offending lines
-    for (line_info, line) in display_line_infos.iter().zip(display_line_strings) {
-        try!(write!(&mut err.dst, "{}:{:>width$} {}\n",
-                    fm.name,
-                    line_info.line_index + 1,
-                    line,
-                    width=digits));
-    }
-
-    // If we elided something, put an ellipsis.
-    if display_lines < all_lines {
-        let last_line_index = display_line_infos.last().unwrap().line_index;
-        let s = format!("{}:{} ", fm.name, last_line_index + 1);
-        try!(write!(&mut err.dst, "{0:1$}...\n", "", s.len()));
-    }
-
-    // FIXME (#3260)
-    // If there's one line at fault we can easily point to the problem
-    if lines.lines.len() == 1 {
-        let lo = cm.lookup_char_pos(sp.lo);
-        let mut digits = 0;
-        let mut num = (lines.lines[0].line_index + 1) / 10;
-
-        // how many digits must be indent past?
-        while num > 0 { num /= 10; digits += 1; }
-
-        let mut s = String::new();
-        // Skip is the number of characters we need to skip because they are
-        // part of the 'filename:line ' part of the previous line.
-        let skip = fm.name.chars().count() + digits + 3;
-        for _ in 0..skip {
-            s.push(' ');
-        }
-        if let Some(orig) = fm.get_line(lines.lines[0].line_index) {
-            let mut col = skip;
-            let mut lastc = ' ';
-            let mut iter = orig.chars().enumerate();
-            for (pos, ch) in iter.by_ref() {
-                lastc = ch;
-                if pos >= lo.col.to_usize() { break; }
-                // Whenever a tab occurs on the previous line, we insert one on
-                // the error-point-squiggly-line as well (instead of a space).
-                // That way the squiggly line will usually appear in the correct
-                // position.
-                match ch {
-                    '\t' => {
-                        col += 8 - col%8;
-                        s.push('\t');
-                    },
-                    _ => {
-                        col += 1;
-                        s.push(' ');
-                    },
-                }
-            }
-
-            try!(write!(&mut err.dst, "{}", s));
-            let mut s = String::from("^");
-            let count = match lastc {
-                // Most terminals have a tab stop every eight columns by default
-                '\t' => 8 - col%8,
-                _ => 1,
-            };
-            col += count;
-            s.extend(::std::iter::repeat('~').take(count));
-
-            let hi = cm.lookup_char_pos(sp.hi);
-            if hi.col != lo.col {
-                for (pos, ch) in iter {
-                    if pos >= hi.col.to_usize() { break; }
-                    let count = match ch {
-                        '\t' => 8 - col%8,
-                        _ => 1,
-                    };
-                    col += count;
-                    s.extend(::std::iter::repeat('~').take(count));
-                }
-            }
-
-            if s.len() > 1 {
-                // One extra squiggly is replaced by a "^"
-                s.pop();
-            }
-
-            try!(print_maybe_styled(err,
-                                    &format!("{}\n", s),
-                                    term::attr::ForegroundColor(lvl.color())));
-        }
-    }
-    Ok(())
-}
-
-/// Here are the differences between this and the normal `highlight_lines`:
-/// `end_highlight_lines` will always put arrow on the last byte of the
-/// span (instead of the first byte). Also, when the span is too long (more
-/// than 6 lines), `end_highlight_lines` will print the first line, then
-/// dot dot dot, then last line, whereas `highlight_lines` prints the first
-/// six lines.
-#[allow(deprecated)]
-fn end_highlight_lines(w: &mut EmitterWriter,
-                          cm: &codemap::CodeMap,
-                          sp: Span,
-                          lvl: Level,
-                          lines: codemap::FileLinesResult)
-                          -> io::Result<()> {
-    let lines = match lines {
-        Ok(lines) => lines,
-        Err(_) => {
-            try!(write!(&mut w.dst, "(internal compiler error: unprintable span)\n"));
-            return Ok(());
-        }
-    };
-
-    let fm = &*lines.file;
-
-    let lines = &lines.lines[..];
-    if lines.len() > MAX_LINES {
-        if let Some(line) = fm.get_line(lines[0].line_index) {
-            try!(write!(&mut w.dst, "{}:{} {}\n", fm.name,
-                        lines[0].line_index + 1, line));
-        }
-        try!(write!(&mut w.dst, "...\n"));
-        let last_line_index = lines[lines.len() - 1].line_index;
-        if let Some(last_line) = fm.get_line(last_line_index) {
-            try!(write!(&mut w.dst, "{}:{} {}\n", fm.name,
-                        last_line_index + 1, last_line));
-        }
-    } else {
-        for line_info in lines {
-            if let Some(line) = fm.get_line(line_info.line_index) {
-                try!(write!(&mut w.dst, "{}:{} {}\n", fm.name,
-                            line_info.line_index + 1, line));
-            }
-        }
-    }
-    let last_line_start = format!("{}:{} ", fm.name, lines[lines.len()-1].line_index + 1);
-    let hi = cm.lookup_char_pos(sp.hi);
-    let skip = last_line_start.chars().count();
-    let mut s = String::new();
-    for _ in 0..skip {
-        s.push(' ');
-    }
-    if let Some(orig) = fm.get_line(lines[0].line_index) {
-        let iter = orig.chars().enumerate();
-        for (pos, ch) in iter {
-            // Span seems to use half-opened interval, so subtract 1
-            if pos >= hi.col.to_usize() - 1 { break; }
-            // Whenever a tab occurs on the previous line, we insert one on
-            // the error-point-squiggly-line as well (instead of a space).
-            // That way the squiggly line will usually appear in the correct
-            // position.
-            match ch {
-                '\t' => s.push('\t'),
-                _ => s.push(' '),
-            }
-        }
-    }
-    s.push('^');
-    s.push('\n');
-    print_maybe_styled(w,
-                       &s[..],
-                       term::attr::ForegroundColor(lvl.color()))
-}
-
-fn print_macro_backtrace(w: &mut EmitterWriter,
-                         cm: &codemap::CodeMap,
-                         sp: Span)
-                         -> io::Result<()> {
-    let cs = try!(cm.with_expn_info(sp.expn_id, |expn_info| -> io::Result<_> {
-        match expn_info {
-            Some(ei) => {
-                let ss = ei.callee.span.map_or(String::new(),
-                                               |span| cm.span_to_string(span));
-                let (pre, post) = match ei.callee.format {
-                    codemap::MacroAttribute => ("#[", "]"),
-                    codemap::MacroBang => ("", "!"),
-                    codemap::CompilerExpansion => ("", ""),
-                };
-                try!(print_diagnostic(w, &ss, Note,
-                                      &format!("in expansion of {}{}{}",
-                                               pre,
-                                               ei.callee.name,
-                                               post),
-                                      None));
-                let ss = cm.span_to_string(ei.call_site);
-                try!(print_diagnostic(w, &ss, Note, "expansion site", None));
-                Ok(Some(ei.call_site))
-            }
-            None => Ok(None)
-    }
-    }));
-    cs.map_or(Ok(()), |call_site| print_macro_backtrace(w, cm, call_site))
-}
-
 pub fn expect<T, M>(diag: &SpanHandler, opt: Option<T>, msg: M) -> T where
     M: FnOnce() -> String,
 {
@@ -808,7 +804,7 @@ pub fn expect<T, M>(diag: &SpanHandler, opt: Option<T>, msg: M) -> T where
 
 #[cfg(test)]
 mod test {
-    use super::{EmitterWriter, highlight_lines, Level};
+    use super::{EmitterWriter, Level};
     use codemap::{mk_sp, CodeMap, BytePos};
     use std::sync::{Arc, Mutex};
     use std::io::{self, Write};
@@ -854,7 +850,7 @@ mod test {
         println!("span_to_lines");
         let lines = cm.span_to_lines(sp);
         println!("highlight_lines");
-        highlight_lines(&mut ew, &cm, sp, lvl, lines).unwrap();
+        ew.highlight_lines(&cm, sp, lvl, lines).unwrap();
         println!("done");
         let vec = data.lock().unwrap().clone();
         let vec: &[u8] = &vec;
diff --git a/src/rt/arch/aarch64/morestack.S b/src/rt/arch/aarch64/morestack.S
index c5e412140e44a..8b7366ebed431 100644
--- a/src/rt/arch/aarch64/morestack.S
+++ b/src/rt/arch/aarch64/morestack.S
@@ -24,7 +24,7 @@
 #endif
 
 #if !defined(__APPLE__)
-.type MORESTACK,%function
+func MORESTACK
 #endif
 
 // FIXME(AARCH64): this might not be perfectly right but works for now
@@ -33,3 +33,7 @@ MORESTACK:
 	bl STACK_EXHAUSTED
 	// the above function ensures that it never returns
 	.cfi_endproc
+
+#if !defined(__APPLE__)
+endfunc MORESTACK
+#endif
diff --git a/src/rustbook/javascript.rs b/src/rustbook/javascript.rs
index f33b79cc1888f..8e530bee39aad 100644
--- a/src/rustbook/javascript.rs
+++ b/src/rustbook/javascript.rs
@@ -57,11 +57,13 @@ document.addEventListener("DOMContentLoaded", function(event) {
       if (i > 0) {
         var prevNode = toc[i-1].cloneNode(true);
         prevNode.className = 'left';
+        prevNode.setAttribute('rel', 'prev');
         nav.appendChild(prevNode);
       }
       if (i < toc.length - 1) {
         var nextNode = toc[i+1].cloneNode(true);
         nextNode.className = 'right';
+        nextNode.setAttribute('rel', 'next');
         nav.appendChild(nextNode);
       }
       document.getElementById('page').appendChild(nav);
diff --git a/src/test/compile-fail/issue-22312.rs b/src/test/compile-fail/issue-22312.rs
new file mode 100644
index 0000000000000..4d6e6eded2118
--- /dev/null
+++ b/src/test/compile-fail/issue-22312.rs
@@ -0,0 +1,27 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::ops::Index;
+
+pub trait Array2D: Index<usize> {
+    fn rows(&self) -> usize;
+    fn columns(&self) -> usize;
+    fn get<'a>(&'a self, y: usize, x: usize) -> Option<&'a <Self as Index<usize>>::Output> {
+        if y >= self.rows() || x >= self.columns() {
+            return None;
+        }
+        let i = y * self.columns() + x;
+        let indexer = &(*self as &Index<usize, Output = <Self as Index<usize>>::Output>);
+        //~^ERROR non-scalar cast
+        Some(indexer.index(i))
+    }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-23595-1.rs b/src/test/compile-fail/issue-23595-1.rs
new file mode 100644
index 0000000000000..749b261e38719
--- /dev/null
+++ b/src/test/compile-fail/issue-23595-1.rs
@@ -0,0 +1,24 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::ops::{Index};
+
+trait Hierarchy {
+    type Value;
+    type ChildKey;
+    type Children = Index<Self::ChildKey, Output=Hierarchy>;
+    //~^ ERROR: the value of the associated type `ChildKey`
+    //~^^ ERROR: the value of the associated type `Children`
+    //~^^^ ERROR: the value of the associated type `Value`
+
+    fn data(&self) -> Option<(Self::Value, Self::Children)>;
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-23595-2.rs b/src/test/compile-fail/issue-23595-2.rs
new file mode 100644
index 0000000000000..78a3f42f1a6a7
--- /dev/null
+++ b/src/test/compile-fail/issue-23595-2.rs
@@ -0,0 +1,18 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub struct C<AType: A> {a:AType}
+
+pub trait A {
+    type B = C<Self::anything_here_kills_it>;
+    //~^ ERROR: associated type `anything_here_kills_it` not found for `Self`
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/issue-26948.rs b/src/test/compile-fail/issue-26948.rs
new file mode 100644
index 0000000000000..c63cb5defb7e3
--- /dev/null
+++ b/src/test/compile-fail/issue-26948.rs
@@ -0,0 +1,16 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    enum Foo { A { x: u32 } }
+    let orig = Foo::A { x: 5 };
+    Foo::A { x: 6, ..orig };
+    //~^ ERROR functional record update syntax requires a struct
+}
diff --git a/src/test/compile-fail/issue-6702.rs b/src/test/compile-fail/issue-6702.rs
index e464ddf54c2d9..bfda113ae8bc9 100644
--- a/src/test/compile-fail/issue-6702.rs
+++ b/src/test/compile-fail/issue-6702.rs
@@ -14,6 +14,6 @@ struct Monster {
 
 
 fn main() {
-    let _m = Monster(); //~ ERROR `Monster` is a structure name, but
+    let _m = Monster(); //~ ERROR `Monster` is a struct variant name, but
     //~^ HELP did you mean to write: `Monster { /* fields */ }`?
 }
diff --git a/src/test/compile-fail/ref-suggestion.rs b/src/test/compile-fail/ref-suggestion.rs
new file mode 100644
index 0000000000000..815f752663223
--- /dev/null
+++ b/src/test/compile-fail/ref-suggestion.rs
@@ -0,0 +1,33 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let x = vec![1];
+    let y = x;
+    //~^ HELP use a `ref` binding as shown
+    //~| SUGGESTION let ref y = x;
+    x; //~ ERROR use of moved value
+
+    let x = vec![1];
+    let mut y = x;
+    //~^ HELP use a `ref` binding as shown
+    //~| SUGGESTION let ref mut y = x;
+    x; //~ ERROR use of moved value
+
+    let x = (Some(vec![1]), ());
+
+    match x {
+        (Some(y), ()) => {},
+        //~^ HELP use a `ref` binding as shown
+        //~| SUGGESTION (Some(ref y), ()) => {},
+        _ => {},
+    }
+    x; //~ ERROR use of partially moved value
+}
diff --git a/src/test/debuginfo/gdb-pretty-struct-and-enums-pre-gdb-7-7.rs b/src/test/debuginfo/gdb-pretty-struct-and-enums-pre-gdb-7-7.rs
index fa15e31450f8b..5dd428119569d 100644
--- a/src/test/debuginfo/gdb-pretty-struct-and-enums-pre-gdb-7-7.rs
+++ b/src/test/debuginfo/gdb-pretty-struct-and-enums-pre-gdb-7-7.rs
@@ -8,10 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// This test uses only GDB Python API features which should be available in
-// older versions of GDB too. A more extensive test can be found in
-// gdb-pretty-struct-and-enums.rs
-
 // ignore-bitrig
 // ignore-windows failing on win32 bot
 // ignore-freebsd: gdb package too new
diff --git a/src/test/run-pass/issue-20544.rs b/src/test/run-pass/issue-20544.rs
new file mode 100644
index 0000000000000..c70b059d3e787
--- /dev/null
+++ b/src/test/run-pass/issue-20544.rs
@@ -0,0 +1,27 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(unboxed_closures)]
+#![feature(core)]
+
+struct Fun<F>(F);
+
+impl<F, T> FnOnce<(T,)> for Fun<F> where F: Fn(T) -> T {
+    type Output = T;
+
+    extern "rust-call" fn call_once(self, (t,): (T,)) -> T {
+        (self.0)(t)
+    }
+}
+
+fn main() {
+    let fun = Fun(|i: isize| i * 2);
+    println!("{}", fun(3));
+}
diff --git a/src/test/run-pass/issue-21140.rs b/src/test/run-pass/issue-21140.rs
new file mode 100644
index 0000000000000..c19f3327fbb41
--- /dev/null
+++ b/src/test/run-pass/issue-21140.rs
@@ -0,0 +1,15 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub trait Trait where Self::Out: std::fmt::Display {
+    type Out;
+}
+
+fn main() {}