about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--RELEASES.md208
-rw-r--r--src/bootstrap/Cargo.lock34
-rw-r--r--src/bootstrap/build/check.rs13
-rw-r--r--src/bootstrap/build/compile.rs30
-rw-r--r--src/bootstrap/build/dist.rs10
-rw-r--r--src/bootstrap/build/doc.rs50
-rw-r--r--src/bootstrap/build/sanity.rs12
-rw-r--r--src/bootstrap/build/step.rs23
-rw-r--r--src/bootstrap/build/util.rs11
-rw-r--r--src/doc/book/concurrency.md21
-rw-r--r--src/libcore/num/mod.rs94
-rw-r--r--src/libcore/result.rs47
-rw-r--r--src/libcore/slice.rs81
-rw-r--r--src/libcore/str/mod.rs3
-rw-r--r--src/librustc/middle/region.rs5
-rw-r--r--src/librustc/mir/visit.rs7
-rw-r--r--src/librustc_back/target/mod.rs1
-rw-r--r--src/librustc_resolve/resolve_imports.rs10
-rw-r--r--src/librustc_trans/debuginfo/metadata.rs18
-rw-r--r--src/librustc_trans/mir/analyze.rs3
-rw-r--r--src/librustc_trans/mir/block.rs229
-rw-r--r--src/librustc_trans/mir/lvalue.rs34
-rw-r--r--src/librustc_trans/type_of.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs21
-rw-r--r--src/librustc_typeck/diagnostics.rs63
-rw-r--r--src/librustdoc/clean/mod.rs4
-rw-r--r--src/librustdoc/lib.rs101
-rw-r--r--src/librustdoc/passes.rs37
-rw-r--r--src/librustdoc/plugins.rs14
-rw-r--r--src/librustdoc/test.rs4
-rw-r--r--src/libstd/path.rs4
-rw-r--r--src/libsyntax/feature_gate.rs4
-rw-r--r--src/libsyntax/parse/parser.rs2
-rw-r--r--src/test/compile-fail/extern-crate-visibility.rs9
-rw-r--r--src/test/compile-fail/issue-24883.rs28
-rw-r--r--src/test/compile-fail/issue-26930.rs20
-rw-r--r--src/test/compile-fail/issue-32201.rs22
-rw-r--r--src/test/compile-fail/issue-32833.rs16
-rw-r--r--src/test/compile-fail/symbol-names/issue-32709.rs20
-rw-r--r--src/test/compile-fail/use-mod-2.rs4
-rw-r--r--src/test/compile-fail/variadic-ffi-3.rs12
-rw-r--r--src/test/parse-fail/issue-32505.rs (renamed from src/test/run-make/rustdoc-json/foo.rs)18
-rw-r--r--src/test/run-make/rustdoc-json/Makefile4
-rw-r--r--src/tools/cargotest/main.rs2
44 files changed, 988 insertions, 367 deletions
diff --git a/RELEASES.md b/RELEASES.md
index a5e307ac0d0..5682960709f 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -1,3 +1,211 @@
+Version 1.8.0 (2016-04-14)
+==========================
+
+Language
+--------
+
+* Rust supports overloading of compound assignment statements like
+  `+=` by implementing the [`AddAssign`], [`SubAssign`],
+  [`MulAssign`], [`DivAssign`], [`RemAssign`], [`BitAndAssign`],
+  [`BitOrAssign`], [`BitXorAssign`], [`ShlAssign`], or [`ShrAssign`]
+  traits. [RFC 953].
+* Empty structs can be defined with braces, as in `struct Foo { }`, in
+  addition to the non-braced form, `struct Foo;`. [RFC 218].
+
+Libraries
+---------
+
+* Stabilized APIs:
+  * [`str::encode_utf16`][] (renamed from `utf16_units`)
+  * [`str::EncodeUtf16`][] (renamed from `Utf16Units`)
+  * [`Ref::map`]
+  * [`RefMut::map`]
+  * [`ptr::drop_in_place`]
+  * [`time::Instant`]
+  * [`time::SystemTime`]
+  * [`Instant::now`]
+  * [`Instant::duration_since`][] (renamed from `duration_from_earlier`)
+  * [`Instant::elapsed`]
+  * [`SystemTime::now`]
+  * [`SystemTime::duration_since`][] (renamed from `duration_from_earlier`)
+  * [`SystemTime::elapsed`]
+  * Various `Add`/`Sub` impls for `Time` and `SystemTime`
+  * [`SystemTimeError`]
+  * [`SystemTimeError::duration`]
+  * Various impls for `SystemTimeError`
+  * [`UNIX_EPOCH`]
+  * [`AddAssign`], [`SubAssign`], [`MulAssign`], [`DivAssign`],
+    [`RemAssign`], [`BitAndAssign`], [`BitOrAssign`],
+    [`BitXorAssign`], [`ShlAssign`], [`ShrAssign`].
+* [The `write!` and `writeln!` macros correctly emit errors if any of
+  their arguments can't be formatted][1.8w].
+* [Various I/O functions support large files on 32-bit Linux][1.8l].
+* [The Unix-specific `raw` modules, which contain a number of
+  redefined C types are deprecated][1.8r], including `os::raw::unix`,
+  `os::raw::macos`, and `os::raw::linux`. These modules defined types
+  such as `ino_t` and `dev_t`. The inconsistency of these definitions
+  across platforms was making it difficult to implement `std`
+  correctly. Those that need these definitions should use the `libc`
+  crate. [RFC 1415].
+* The Unix-specific `MetadataExt` traits, including
+  `os::unix::fs::MetadataExt`, which expose values such as inode
+  numbers [no longer return platform-specific types][1.8r], but
+  instead return widened integers. [RFC 1415].
+* [`btree_set::{IntoIter, Iter, Range}` are covariant][1.8cv].
+* [Atomic loads and stores are not volatile][1.8a].
+* [All types in `sync::mpsc` implement `fmt::Debug`][1.8mp].
+
+Performance
+-----------
+
+* [Inlining hash functions lead to a 3% compile-time improvement in
+  some workloads][1.8h].
+* When using jemalloc, its symbols are [unprefixed so that it
+  overrides the libc malloc implementation][1.8h]. This means that for
+  rustc, LLVM is now using jemalloc, which results in a 6%
+  compile-time improvement on a specific workload.
+* [Avoid quadratic growth in function size due to cleanups][1.8cu].
+
+Misc
+----
+
+* [32-bit MSVC builds finally implement unwinding][1.8ms].
+  i686-pc-windows-msvc is now considered a tier-1 platform.
+* [The `--print targets` flag prints a list of supported targets][1.8t].
+* [The `--print cfg` flag prints the `cfg`s defined for the current
+  target][1.8cf].
+* [`rustc` can be built with an new Cargo-based build system, written
+  in Rust][1.8b].  It will eventually replace Rust's Makefile-based
+  build system. To enable it configure with `configure --rustbuild`.
+* [Errors for non-exhaustive `match` patterns now list up to 3 missing
+  variants while also indicating the total number of missing variants
+  if more than 3][1.8m].
+* [Executable stacks are disabled on Linux and BSD][1.8nx].
+* The Rust Project now publishes binary releases of the standard
+  library for a number of tier-2 targets:
+  `armv7-unknown-linux-gnueabihf`, `powerpc-unknown-linux-gnu`,
+  `powerpc64-unknown-linux-gnu`, `powerpc64le-unknown-linux-gnu`
+  `x86_64-rumprun-netbsd`. These can be installed with
+  tools such as [multirust][1.8mr].
+
+Cargo
+-----
+
+* [`cargo init` creates a new Cargo project in the current
+  directory][1.8ci].  It is otherwise like `cargo new`.
+* [Cargo has configuration keys for `-v` and
+  `--color`][1.8cc]. `verbose` and `color`, respectively, go in the
+  `[term]` section of `.cargo/config`.
+* [Configuration keys that evaluate to strings or integers can be set
+  via environment variables][1.8ce]. For example the `build.jobs` key
+  can be set via `CARGO_BUILD_JOBS`. Environment variables take
+  precedence over config files.
+* [Target-specific dependencies support Rust `cfg` syntax for
+  describing targets][1.8cfg] so that dependencies for multiple
+  targets can be specified together. [RFC 1361].
+* [The environment variables `CARGO_TARGET_ROOT`, `RUSTC`, and
+  `RUSTDOC` take precedence over the `build.target-dir`,
+  `build.rustc`, and `build.rustdoc` configuration values][1.8cv].
+* [The child process tree is killed on Windows when Cargo is
+  killed][1.8ck].
+* [The `build.target` configuration value sets the target platform,
+  like `--target`][1.8ct].
+
+Compatibility Notes
+-------------------
+
+* [Unstable compiler flags have been further restricted][1.8u]. Since
+  1.0 `-Z` flags have been considered unstable, and other flags that
+  were considered unstable additionally required passing `-Z
+  unstable-options` to access. Unlike unstable language and library
+  features though, these options have been accessible on the stable
+  release channel. Going forward, *new unstable flags will not be
+  available on the stable release channel*, and old unstable flags
+  will warn about their usage. In the future, all unstable flags will
+  be unavailable on the stable release channel.
+* [It is no longer possible to `match` on empty enum variants using
+  the `Variant(..)` syntax][1.8v]. This has been a warning since 1.6.
+* The Unix-specific `MetadataExt` traits, including
+  `os::unix::fs::MetadataExt`, which expose values such as inode
+  numbers [no longer return platform-specific types][1.8r], but
+  instead return widened integers. [RFC 1415].
+* [Modules sourced from the filesystem cannot appear within arbitrary
+  blocks, but only within other modules][1.8m].
+* [`--cfg` compiler flags are parsed strictly as identifiers][1.8c].
+* On Unix, [stack overflow triggers a runtime abort instead of a
+  SIGSEGV][1.8so].
+* [`Command::spawn` and its equivalents return an error if any of
+  its command-line arguments contain interior `NUL`s][1.8n].
+* [Tuple and unit enum variants from other crates are in the type
+  namespace][1.8tn].
+* [On Windows `rustc` emits `.lib` files for the `staticlib` library
+  type instead of `.a` files][1.8st]. Additionally, for the MSVC
+  toolchain, `rustc` emits import libraries named `foo.dll.lib`
+  instead of `foo.lib`.
+
+
+[1.8a]: https://github.com/rust-lang/rust/pull/30962
+[1.8b]: https://github.com/rust-lang/rust/pull/31123
+[1.8c]: https://github.com/rust-lang/rust/pull/31530
+[1.8cc]: https://github.com/rust-lang/cargo/pull/2397
+[1.8ce]: https://github.com/rust-lang/cargo/pull/2398
+[1.8cf]: https://github.com/rust-lang/rust/pull/31278
+[1.8cfg]: https://github.com/rust-lang/cargo/pull/2328
+[1.8ci]: https://github.com/rust-lang/cargo/pull/2081
+[1.8ck]: https://github.com/rust-lang/cargo/pull/2370
+[1.8ct]: https://github.com/rust-lang/cargo/pull/2335
+[1.8cu]: https://github.com/rust-lang/rust/pull/31390
+[1.8cv]: https://github.com/rust-lang/cargo/issues/2365
+[1.8cv]: https://github.com/rust-lang/rust/pull/30998
+[1.8h]: https://github.com/rust-lang/rust/pull/31460
+[1.8l]: https://github.com/rust-lang/rust/pull/31668
+[1.8m]: https://github.com/rust-lang/rust/pull/31020
+[1.8m]: https://github.com/rust-lang/rust/pull/31534
+[1.8mp]: https://github.com/rust-lang/rust/pull/30894
+[1.8mr]: https://users.rust-lang.org/t/multirust-0-8-with-cross-std-installation/4901
+[1.8ms]: https://github.com/rust-lang/rust/pull/30448
+[1.8n]: https://github.com/rust-lang/rust/pull/31056
+[1.8nx]: https://github.com/rust-lang/rust/pull/30859
+[1.8r]: https://github.com/rust-lang/rust/pull/31551
+[1.8so]: https://github.com/rust-lang/rust/pull/31333
+[1.8st]: https://github.com/rust-lang/rust/pull/29520
+[1.8t]: https://github.com/rust-lang/rust/pull/31358
+[1.8tn]: https://github.com/rust-lang/rust/pull/30882
+[1.8u]: https://github.com/rust-lang/rust/pull/31793
+[1.8v]: https://github.com/rust-lang/rust/pull/31757
+[1.8w]: https://github.com/rust-lang/rust/pull/31904
+[RFC 1361]: https://github.com/rust-lang/rfcs/blob/master/text/1361-cargo-cfg-dependencies.md
+[RFC 1415]: https://github.com/rust-lang/rfcs/blob/master/text/1415-trim-std-os.md
+[RFC 218]: https://github.com/rust-lang/rfcs/blob/master/text/0218-empty-struct-with-braces.md
+[RFC 953]: https://github.com/rust-lang/rfcs/blob/master/text/0953-op-assign.md
+[`AddAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.AddAssign.html
+[`BitAndAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.BitAndAssign.html
+[`BitOrAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.BitOrAssign.html
+[`BitXorAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.BitXorAssign.html
+[`DivAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.DivAssign.html
+[`Instant::duration_since`]: http://doc.rust-lang.org/nightly/std/time/struct.Instant.html#method.duration_since
+[`Instant::elapsed`]: http://doc.rust-lang.org/nightly/std/time/struct.Instant.html#method.elapsed
+[`Instant::now`]: http://doc.rust-lang.org/nightly/std/time/struct.Instant.html#method.now
+[`MulAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.MulAssign.html
+[`Ref::map`]: http://doc.rust-lang.org/nightly/std/cell/struct.Ref.html#method.map
+[`RefMut::map`]: http://doc.rust-lang.org/nightly/std/cell/struct.RefMut.html#method.map
+[`RemAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.RemAssign.html
+[`ShlAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.ShlAssign.html
+[`ShrAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.ShrAssign.html
+[`SubAssign`]: http://doc.rust-lang.org/nightly/std/ops/trait.SubAssign.html
+[`SystemTime::duration_since`]: http://doc.rust-lang.org/nightly/std/time/struct.SystemTime.html#method.duration_since
+[`SystemTime::elapsed`]: http://doc.rust-lang.org/nightly/std/time/struct.SystemTime.html#method.elapsed
+[`SystemTime::now`]: http://doc.rust-lang.org/nightly/std/time/struct.SystemTime.html#method.now
+[`SystemTimeError::duration`]: http://doc.rust-lang.org/nightly/std/time/struct.SystemTimeError.html#method.duration
+[`SystemTimeError`]: http://doc.rust-lang.org/nightly/std/time/struct.SystemTimeError.html
+[`UNIX_EPOCH`]: http://doc.rust-lang.org/nightly/std/time/constant.UNIX_EPOCH.html
+[`ptr::drop_in_place`]: http://doc.rust-lang.org/nightly/std/ptr/fn.drop_in_place.html
+[`str::EncodeUtf16`]: http://doc.rust-lang.org/nightly/std/str/struct.EncodeUtf16.html
+[`str::encode_utf16`]: http://doc.rust-lang.org/nightly/std/primitive.str.html#method.encode_utf16
+[`time::Instant`]: http://doc.rust-lang.org/nightly/std/time/struct.Instant.html
+[`time::SystemTime`]: http://doc.rust-lang.org/nightly/std/time/struct.SystemTime.html
+
+
 Version 1.7.0 (2016-03-03)
 ==========================
 
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index 05186d48ce2..c33838a146c 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -3,16 +3,16 @@ name = "bootstrap"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "cmake 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cmake 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "gcc 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
  "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -21,10 +21,10 @@ version = "0.1.0"
 
 [[package]]
 name = "cmake"
-version = "0.1.13"
+version = "0.1.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gcc 0.3.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -32,12 +32,12 @@ name = "filetime"
 version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "gcc"
-version = "0.3.25"
+version = "0.3.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -50,13 +50,13 @@ name = "kernel32-sys"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "libc"
-version = "0.2.7"
+version = "0.2.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -64,25 +64,25 @@ name = "num_cpus"
 version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-serialize"
-version = "0.3.18"
+version = "0.3.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "toml"
-version = "0.1.27"
+version = "0.1.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "winapi"
-version = "0.2.5"
+version = "0.2.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
diff --git a/src/bootstrap/build/check.rs b/src/bootstrap/build/check.rs
index 4e2ee475285..a2445ae498a 100644
--- a/src/bootstrap/build/check.rs
+++ b/src/bootstrap/build/check.rs
@@ -18,9 +18,18 @@ pub fn linkcheck(build: &Build, stage: u32, host: &str) {
 }
 
 pub fn cargotest(build: &Build, stage: u32, host: &str) {
+
     let ref compiler = Compiler::new(stage, host);
+
+    // Configure PATH to find the right rustc. NB. we have to use PATH
+    // and not RUSTC because the Cargo test suite has tests that will
+    // fail if rustc is not spelled `rustc`.
+    let path = build.sysroot(compiler).join("bin");
+    let old_path = ::std::env::var("PATH").expect("");
+    let sep = if cfg!(windows) { ";" } else {":" };
+    let ref newpath = format!("{}{}{}", path.display(), sep, old_path);
+
     build.run(build.tool_cmd(compiler, "cargotest")
-              .env("RUSTC", build.compiler_path(compiler))
-              .env("RUSTDOC", build.rustdoc(compiler))
+              .env("PATH", newpath)
               .arg(&build.cargo));
 }
diff --git a/src/bootstrap/build/compile.rs b/src/bootstrap/build/compile.rs
index dee586c7699..a67f1ba48b5 100644
--- a/src/bootstrap/build/compile.rs
+++ b/src/bootstrap/build/compile.rs
@@ -15,7 +15,7 @@ use std::process::Command;
 
 use build_helper::output;
 
-use build::util::{exe, staticlib, libdir, mtime, is_dylib};
+use build::util::{exe, staticlib, libdir, mtime, is_dylib, copy};
 use build::{Build, Compiler, Mode};
 
 /// Build the standard library.
@@ -32,8 +32,8 @@ pub fn std<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) {
     let libdir = build.sysroot_libdir(compiler, target);
     let _ = fs::remove_dir_all(&libdir);
     t!(fs::create_dir_all(&libdir));
-    t!(fs::hard_link(&build.compiler_rt_built.borrow()[target],
-                     libdir.join(staticlib("compiler-rt", target))));
+    copy(&build.compiler_rt_built.borrow()[target],
+         &libdir.join(staticlib("compiler-rt", target)));
 
     build_startup_objects(build, target, &libdir);
 
@@ -77,8 +77,8 @@ pub fn std_link(build: &Build,
     if host != compiler.host {
         let _ = fs::remove_dir_all(&libdir);
         t!(fs::create_dir_all(&libdir));
-        t!(fs::hard_link(&build.compiler_rt_built.borrow()[target],
-                         libdir.join(staticlib("compiler-rt", target))));
+        copy(&build.compiler_rt_built.borrow()[target],
+             &libdir.join(staticlib("compiler-rt", target)));
     }
     add_to_sysroot(&out_dir, &libdir);
 
@@ -93,7 +93,7 @@ pub fn std_link(build: &Build,
 /// Only required for musl targets that statically link to libc
 fn copy_third_party_objects(build: &Build, target: &str, into: &Path) {
     for &obj in &["crt1.o", "crti.o", "crtn.o"] {
-        t!(fs::copy(compiler_file(build.cc(target), obj), into.join(obj)));
+        copy(&compiler_file(build.cc(target), obj), &into.join(obj));
     }
 }
 
@@ -119,7 +119,7 @@ fn build_startup_objects(build: &Build, target: &str, into: &Path) {
     }
 
     for obj in ["crt2.o", "dllcrt2.o"].iter() {
-        t!(fs::copy(compiler_file(build.cc(target), obj), into.join(obj)));
+        copy(&compiler_file(build.cc(target), obj), &into.join(obj));
     }
 }
 
@@ -240,9 +240,10 @@ fn libtest_shim(build: &Build, compiler: &Compiler, target: &str) -> PathBuf {
     build.cargo_out(compiler, Mode::Libtest, target).join("libtest_shim.rlib")
 }
 
-fn compiler_file(compiler: &Path, file: &str) -> String {
-    output(Command::new(compiler)
-                   .arg(format!("-print-file-name={}", file))).trim().to_string()
+fn compiler_file(compiler: &Path, file: &str) -> PathBuf {
+    let out = output(Command::new(compiler)
+                            .arg(format!("-print-file-name={}", file)));
+    PathBuf::from(out.trim())
 }
 
 /// Prepare a new compiler from the artifacts in `stage`
@@ -270,7 +271,7 @@ pub fn assemble_rustc(build: &Build, stage: u32, host: &str) {
     for f in t!(fs::read_dir(&src_libdir)).map(|f| t!(f)) {
         let filename = f.file_name().into_string().unwrap();
         if is_dylib(&filename) {
-            t!(fs::hard_link(&f.path(), sysroot_libdir.join(&filename)));
+            copy(&f.path(), &sysroot_libdir.join(&filename));
         }
     }
 
@@ -282,7 +283,7 @@ pub fn assemble_rustc(build: &Build, stage: u32, host: &str) {
     t!(fs::create_dir_all(&bindir));
     let compiler = build.compiler_path(&Compiler::new(stage, host));
     let _ = fs::remove_file(&compiler);
-    t!(fs::hard_link(rustc, compiler));
+    copy(&rustc, &compiler);
 
     // See if rustdoc exists to link it into place
     let rustdoc = exe("rustdoc", host);
@@ -290,7 +291,7 @@ pub fn assemble_rustc(build: &Build, stage: u32, host: &str) {
     let rustdoc_dst = bindir.join(&rustdoc);
     if fs::metadata(&rustdoc_src).is_ok() {
         let _ = fs::remove_file(&rustdoc_dst);
-        t!(fs::hard_link(&rustdoc_src, &rustdoc_dst));
+        copy(&rustdoc_src, &rustdoc_dst);
     }
 }
 
@@ -329,8 +330,7 @@ fn add_to_sysroot(out_dir: &Path, sysroot_dst: &Path) {
         let (_, path) = paths.iter().map(|path| {
             (mtime(&path).seconds(), path)
         }).max().unwrap();
-        t!(fs::hard_link(&path,
-                         sysroot_dst.join(path.file_name().unwrap())));
+        copy(&path, &sysroot_dst.join(path.file_name().unwrap()));
     }
 }
 
diff --git a/src/bootstrap/build/dist.rs b/src/bootstrap/build/dist.rs
index 855528ea440..6ae652bd66d 100644
--- a/src/bootstrap/build/dist.rs
+++ b/src/bootstrap/build/dist.rs
@@ -52,7 +52,7 @@ pub fn docs(build: &Build, stage: u32, host: &str) {
        .arg(format!("--image-dir={}", sanitize_sh(&image)))
        .arg(format!("--work-dir={}", sanitize_sh(&tmpdir(build))))
        .arg(format!("--output-dir={}", sanitize_sh(&distdir(build))))
-       .arg(format!("--package-name={}", name))
+       .arg(format!("--package-name={}-{}", name, host))
        .arg("--component-name=rust-docs")
        .arg("--legacy-manifest-dirs=rustlib,cargo")
        .arg("--bulk-dirs=share/doc/rust/html");
@@ -61,9 +61,11 @@ pub fn docs(build: &Build, stage: u32, host: &str) {
 
     // As part of this step, *also* copy the docs directory to a directory which
     // buildbot typically uploads.
-    let dst = distdir(build).join("doc").join(&build.package_vers);
-    t!(fs::create_dir_all(&dst));
-    cp_r(&src, &dst);
+    if host == build.config.build {
+        let dst = distdir(build).join("doc").join(&build.package_vers);
+        t!(fs::create_dir_all(&dst));
+        cp_r(&src, &dst);
+    }
 }
 
 pub fn mingw(build: &Build, host: &str) {
diff --git a/src/bootstrap/build/doc.rs b/src/bootstrap/build/doc.rs
index 50c0c56807b..5782dd5ec28 100644
--- a/src/bootstrap/build/doc.rs
+++ b/src/bootstrap/build/doc.rs
@@ -16,18 +16,18 @@ use std::process::Command;
 use build::{Build, Compiler, Mode};
 use build::util::{up_to_date, cp_r};
 
-pub fn rustbook(build: &Build, stage: u32, host: &str, name: &str, out: &Path) {
+pub fn rustbook(build: &Build, stage: u32, target: &str, name: &str, out: &Path) {
     t!(fs::create_dir_all(out));
 
     let out = out.join(name);
-    let compiler = Compiler::new(stage, host);
+    let compiler = Compiler::new(stage, &build.config.build);
     let src = build.src.join("src/doc").join(name);
     let index = out.join("index.html");
     let rustbook = build.tool(&compiler, "rustbook");
     if up_to_date(&src, &index) && up_to_date(&rustbook, &index) {
         return
     }
-    println!("Rustbook stage{} ({}) - {}", stage, host, name);
+    println!("Rustbook stage{} ({}) - {}", stage, target, name);
     let _ = fs::remove_dir_all(&out);
     build.run(build.tool_cmd(&compiler, "rustbook")
                    .arg("build")
@@ -35,11 +35,11 @@ pub fn rustbook(build: &Build, stage: u32, host: &str, name: &str, out: &Path) {
                    .arg(out));
 }
 
-pub fn standalone(build: &Build, stage: u32, host: &str, out: &Path) {
-    println!("Documenting stage{} standalone ({})", stage, host);
+pub fn standalone(build: &Build, stage: u32, target: &str, out: &Path) {
+    println!("Documenting stage{} standalone ({})", stage, target);
     t!(fs::create_dir_all(out));
 
-    let compiler = Compiler::new(stage, host);
+    let compiler = Compiler::new(stage, &build.config.build);
 
     let favicon = build.src.join("src/doc/favicon.inc");
     let footer = build.src.join("src/doc/footer.inc");
@@ -105,16 +105,17 @@ pub fn standalone(build: &Build, stage: u32, host: &str, out: &Path) {
     }
 }
 
-pub fn std(build: &Build, stage: u32, host: &str, out: &Path) {
-    println!("Documenting stage{} std ({})", stage, host);
-    let compiler = Compiler::new(stage, host);
+pub fn std(build: &Build, stage: u32, target: &str, out: &Path) {
+    println!("Documenting stage{} std ({})", stage, target);
+    t!(fs::create_dir_all(out));
+    let compiler = Compiler::new(stage, &build.config.build);
     let out_dir = build.stage_out(&compiler, Mode::Libstd)
-                       .join(host).join("doc");
+                       .join(target).join("doc");
     let rustdoc = build.rustdoc(&compiler);
 
     build.clear_if_dirty(&out_dir, &rustdoc);
 
-    let mut cargo = build.cargo(&compiler, Mode::Libstd, host, "doc");
+    let mut cargo = build.cargo(&compiler, Mode::Libstd, target, "doc");
     cargo.arg("--manifest-path")
          .arg(build.src.join("src/rustc/std_shim/Cargo.toml"))
          .arg("--features").arg(build.std_features());
@@ -122,32 +123,32 @@ pub fn std(build: &Build, stage: u32, host: &str, out: &Path) {
     cp_r(&out_dir, out)
 }
 
-pub fn test(build: &Build, stage: u32, host: &str, out: &Path) {
-    println!("Documenting stage{} test ({})", stage, host);
-    let compiler = Compiler::new(stage, host);
+pub fn test(build: &Build, stage: u32, target: &str, out: &Path) {
+    println!("Documenting stage{} test ({})", stage, target);
+    let compiler = Compiler::new(stage, &build.config.build);
     let out_dir = build.stage_out(&compiler, Mode::Libtest)
-                       .join(host).join("doc");
+                       .join(target).join("doc");
     let rustdoc = build.rustdoc(&compiler);
 
     build.clear_if_dirty(&out_dir, &rustdoc);
 
-    let mut cargo = build.cargo(&compiler, Mode::Libtest, host, "doc");
+    let mut cargo = build.cargo(&compiler, Mode::Libtest, target, "doc");
     cargo.arg("--manifest-path")
          .arg(build.src.join("src/rustc/test_shim/Cargo.toml"));
     build.run(&mut cargo);
     cp_r(&out_dir, out)
 }
 
-pub fn rustc(build: &Build, stage: u32, host: &str, out: &Path) {
-    println!("Documenting stage{} compiler ({})", stage, host);
-    let compiler = Compiler::new(stage, host);
+pub fn rustc(build: &Build, stage: u32, target: &str, out: &Path) {
+    println!("Documenting stage{} compiler ({})", stage, target);
+    let compiler = Compiler::new(stage, &build.config.build);
     let out_dir = build.stage_out(&compiler, Mode::Librustc)
-                       .join(host).join("doc");
+                       .join(target).join("doc");
     let rustdoc = build.rustdoc(&compiler);
     if !up_to_date(&rustdoc, &out_dir.join("rustc/index.html")) {
         t!(fs::remove_dir_all(&out_dir));
     }
-    let mut cargo = build.cargo(&compiler, Mode::Librustc, host, "doc");
+    let mut cargo = build.cargo(&compiler, Mode::Librustc, target, "doc");
     cargo.arg("--manifest-path")
          .arg(build.src.join("src/rustc/Cargo.toml"))
          .arg("--features").arg(build.rustc_features());
@@ -155,9 +156,10 @@ pub fn rustc(build: &Build, stage: u32, host: &str, out: &Path) {
     cp_r(&out_dir, out)
 }
 
-pub fn error_index(build: &Build, stage: u32, host: &str, out: &Path) {
-    println!("Documenting stage{} error index ({})", stage, host);
-    let compiler = Compiler::new(stage, host);
+pub fn error_index(build: &Build, stage: u32, target: &str, out: &Path) {
+    println!("Documenting stage{} error index ({})", stage, target);
+    t!(fs::create_dir_all(out));
+    let compiler = Compiler::new(stage, &build.config.build);
     let mut index = build.tool_cmd(&compiler, "error_index_generator");
     index.arg("html");
     index.arg(out.join("error-index.html"));
diff --git a/src/bootstrap/build/sanity.rs b/src/bootstrap/build/sanity.rs
index be4416c697c..6ce27496388 100644
--- a/src/bootstrap/build/sanity.rs
+++ b/src/bootstrap/build/sanity.rs
@@ -119,4 +119,16 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
             }
         }
     }
+
+    for host in build.flags.host.iter() {
+        if !build.config.host.contains(host) {
+            panic!("specified host `{}` is not in the ./configure list", host);
+        }
+    }
+    for target in build.flags.target.iter() {
+        if !build.config.target.contains(target) {
+            panic!("specified target `{}` is not in the ./configure list",
+                   target);
+        }
+    }
 }
diff --git a/src/bootstrap/build/step.rs b/src/bootstrap/build/step.rs
index 4e3aacd3720..80fcc32e537 100644
--- a/src/bootstrap/build/step.rs
+++ b/src/bootstrap/build/step.rs
@@ -274,22 +274,28 @@ impl<'a> Step<'a> {
                 vec![self.llvm(()).target(&build.config.build)]
             }
             Source::Llvm { _dummy } => Vec::new(),
+
+            // Note that all doc targets depend on artifacts from the build
+            // architecture, not the target (which is where we're generating
+            // docs into).
             Source::DocStd { stage } => {
-                vec![self.libstd(self.compiler(stage))]
+                let compiler = self.target(&build.config.build).compiler(stage);
+                vec![self.libstd(compiler)]
             }
             Source::DocTest { stage } => {
-                vec![self.libtest(self.compiler(stage))]
+                let compiler = self.target(&build.config.build).compiler(stage);
+                vec![self.libtest(compiler)]
             }
             Source::DocBook { stage } |
             Source::DocNomicon { stage } |
             Source::DocStyle { stage } => {
-                vec![self.tool_rustbook(stage)]
+                vec![self.target(&build.config.build).tool_rustbook(stage)]
             }
             Source::DocErrorIndex { stage } => {
-                vec![self.tool_error_index(stage)]
+                vec![self.target(&build.config.build).tool_error_index(stage)]
             }
             Source::DocStandalone { stage } => {
-                vec![self.rustc(stage)]
+                vec![self.target(&build.config.build).rustc(stage)]
             }
             Source::DocRustc { stage } => {
                 vec![self.doc_test(stage)]
@@ -319,7 +325,7 @@ impl<'a> Step<'a> {
                 vec![self.librustc(self.compiler(stage))]
             }
             Source::ToolCargoTest { stage } => {
-                vec![self.libstd(self.compiler(stage))]
+                vec![self.librustc(self.compiler(stage))]
             }
 
             Source::DistDocs { stage } => vec![self.doc(stage)],
@@ -333,7 +339,6 @@ impl<'a> Step<'a> {
 
             Source::Dist { stage } => {
                 let mut base = Vec::new();
-                base.push(self.dist_docs(stage));
 
                 for host in build.config.host.iter() {
                     let host = self.target(host);
@@ -344,7 +349,9 @@ impl<'a> Step<'a> {
 
                     let compiler = self.compiler(stage);
                     for target in build.config.target.iter() {
-                        base.push(self.target(target).dist_std(compiler));
+                        let target = self.target(target);
+                        base.push(target.dist_docs(stage));
+                        base.push(target.dist_std(compiler));
                     }
                 }
                 return base
diff --git a/src/bootstrap/build/util.rs b/src/bootstrap/build/util.rs
index 35d22ee5d26..41cf924d44a 100644
--- a/src/bootstrap/build/util.rs
+++ b/src/bootstrap/build/util.rs
@@ -30,6 +30,15 @@ pub fn mtime(path: &Path) -> FileTime {
     }).unwrap_or(FileTime::zero())
 }
 
+pub fn copy(src: &Path, dst: &Path) {
+    let res = fs::hard_link(src, dst);
+    let res = res.or_else(|_| fs::copy(src, dst).map(|_| ()));
+    if let Err(e) = res {
+        panic!("failed to copy `{}` to `{}`: {}", src.display(),
+               dst.display(), e)
+    }
+}
+
 pub fn cp_r(src: &Path, dst: &Path) {
     for f in t!(fs::read_dir(src)) {
         let f = t!(f);
@@ -42,7 +51,7 @@ pub fn cp_r(src: &Path, dst: &Path) {
             cp_r(&path, &dst);
         } else {
             let _ = fs::remove_file(&dst);
-            t!(fs::hard_link(&path, dst));
+            copy(&path, &dst);
         }
     }
 }
diff --git a/src/doc/book/concurrency.md b/src/doc/book/concurrency.md
index ba4496b93f3..c179629a79a 100644
--- a/src/doc/book/concurrency.md
+++ b/src/doc/book/concurrency.md
@@ -162,7 +162,7 @@ The same [ownership system](ownership.html) that helps prevent using pointers
 incorrectly also helps rule out data races, one of the worst kinds of
 concurrency bugs.
 
-As an example, here is a Rust program that could have a data race in many
+As an example, here is a Rust program that would have a data race in many
 languages. It will not compile:
 
 ```ignore
@@ -174,7 +174,7 @@ fn main() {
 
     for i in 0..3 {
         thread::spawn(move || {
-            data[i] += 1;
+            data[0] += i;
         });
     }
 
@@ -186,7 +186,7 @@ This gives us an error:
 
 ```text
 8:17 error: capture of moved value: `data`
-        data[i] += 1;
+        data[0] += i;
         ^~~~
 ```
 
@@ -195,11 +195,6 @@ thread, and the thread takes ownership of the reference, we'd have three owners!
 `data` gets moved out of `main` in the first call to `spawn()`, so subsequent
 calls in the loop cannot use this variable.
 
-Note that this specific example will not cause a data race since different array
-indices are being accessed. But this can't be determined at compile time, and in
-a similar situation where `i` is a constant or is random, you would have a data
-race.
-
 So, we need some type that lets us have more than one owning reference to a
 value. Usually, we'd use `Rc<T>` for this, which is a reference counted type
 that provides shared ownership. It has some runtime bookkeeping that keeps track
@@ -223,7 +218,7 @@ fn main() {
 
         // use it in a thread
         thread::spawn(move || {
-            data_ref[i] += 1;
+            data_ref[0] += i;
         });
     }
 
@@ -266,7 +261,7 @@ fn main() {
     for i in 0..3 {
         let data = data.clone();
         thread::spawn(move || {
-            data[i] += 1;
+            data[0] += i;
         });
     }
 
@@ -281,7 +276,7 @@ And... still gives us an error.
 
 ```text
 <anon>:11:24 error: cannot borrow immutable borrowed content as mutable
-<anon>:11                    data[i] += 1;
+<anon>:11                    data[0] += i;
                              ^~~~
 ```
 
@@ -317,7 +312,7 @@ fn main() {
         let data = data.clone();
         thread::spawn(move || {
             let mut data = data.lock().unwrap();
-            data[i] += 1;
+            data[0] += i;
         });
     }
 
@@ -360,7 +355,7 @@ Let's examine the body of the thread more closely:
 #         let data = data.clone();
 thread::spawn(move || {
     let mut data = data.lock().unwrap();
-    data[i] += 1;
+    data[0] += i;
 });
 #     }
 #     thread::sleep(Duration::from_millis(50));
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 229a864d712..9af8ef53851 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -149,7 +149,7 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// assert_eq!(u32::from_str_radix("A", 16), Ok(10));
+        /// assert_eq!(i32::from_str_radix("A", 16), Ok(10));
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
@@ -163,9 +163,9 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// let n = 0b01001100u8;
+        /// let n = -0b1000_0000i8;
         ///
-        /// assert_eq!(n.count_ones(), 3);
+        /// assert_eq!(n.count_ones(), 1);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
@@ -178,9 +178,9 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// let n = 0b01001100u8;
+        /// let n = -0b1000_0000i8;
         ///
-        /// assert_eq!(n.count_zeros(), 5);
+        /// assert_eq!(n.count_zeros(), 7);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
@@ -196,9 +196,9 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// let n = 0b0101000u16;
+        /// let n = -1i16;
         ///
-        /// assert_eq!(n.leading_zeros(), 10);
+        /// assert_eq!(n.leading_zeros(), 0);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
@@ -214,9 +214,9 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// let n = 0b0101000u16;
+        /// let n = -4i8;
         ///
-        /// assert_eq!(n.trailing_zeros(), 3);
+        /// assert_eq!(n.trailing_zeros(), 2);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
@@ -232,10 +232,10 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// let n = 0x0123456789ABCDEFu64;
-        /// let m = 0x3456789ABCDEF012u64;
+        /// let n = 0x0123456789ABCDEFi64;
+        /// let m = -0x76543210FEDCBA99i64;
         ///
-        /// assert_eq!(n.rotate_left(12), m);
+        /// assert_eq!(n.rotate_left(32), m);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
@@ -252,10 +252,10 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// let n = 0x0123456789ABCDEFu64;
-        /// let m = 0xDEF0123456789ABCu64;
+        /// let n = 0x0123456789ABCDEFi64;
+        /// let m = -0xFEDCBA987654322i64;
         ///
-        /// assert_eq!(n.rotate_right(12), m);
+        /// assert_eq!(n.rotate_right(4), m);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
@@ -270,8 +270,8 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// let n = 0x0123456789ABCDEFu64;
-        /// let m = 0xEFCDAB8967452301u64;
+        /// let n =  0x0123456789ABCDEFi64;
+        /// let m = -0x1032547698BADCFFi64;
         ///
         /// assert_eq!(n.swap_bytes(), m);
         /// ```
@@ -291,12 +291,12 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// let n = 0x0123456789ABCDEFu64;
+        /// let n = 0x0123456789ABCDEFi64;
         ///
         /// if cfg!(target_endian = "big") {
-        ///     assert_eq!(u64::from_be(n), n)
+        ///     assert_eq!(i64::from_be(n), n)
         /// } else {
-        ///     assert_eq!(u64::from_be(n), n.swap_bytes())
+        ///     assert_eq!(i64::from_be(n), n.swap_bytes())
         /// }
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -315,12 +315,12 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// let n = 0x0123456789ABCDEFu64;
+        /// let n = 0x0123456789ABCDEFi64;
         ///
         /// if cfg!(target_endian = "little") {
-        ///     assert_eq!(u64::from_le(n), n)
+        ///     assert_eq!(i64::from_le(n), n)
         /// } else {
-        ///     assert_eq!(u64::from_le(n), n.swap_bytes())
+        ///     assert_eq!(i64::from_le(n), n.swap_bytes())
         /// }
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -339,7 +339,7 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// let n = 0x0123456789ABCDEFu64;
+        /// let n = 0x0123456789ABCDEFi64;
         ///
         /// if cfg!(target_endian = "big") {
         ///     assert_eq!(n.to_be(), n)
@@ -363,7 +363,7 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// let n = 0x0123456789ABCDEFu64;
+        /// let n = 0x0123456789ABCDEFi64;
         ///
         /// if cfg!(target_endian = "little") {
         ///     assert_eq!(n.to_le(), n)
@@ -385,8 +385,8 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// assert_eq!(5u16.checked_add(65530), Some(65535));
-        /// assert_eq!(6u16.checked_add(65530), None);
+        /// assert_eq!(7i16.checked_add(32760), Some(32767));
+        /// assert_eq!(8i16.checked_add(32760), None);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
@@ -421,8 +421,8 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// assert_eq!(5u8.checked_mul(51), Some(255));
-        /// assert_eq!(5u8.checked_mul(52), None);
+        /// assert_eq!(6i8.checked_mul(21), Some(126));
+        /// assert_eq!(6i8.checked_mul(22), None);
         /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[inline]
@@ -753,8 +753,8 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// assert_eq!(1u8.wrapping_shl(7), 128);
-        /// assert_eq!(1u8.wrapping_shl(8), 1);
+        /// assert_eq!((-1i8).wrapping_shl(7), -128);
+        /// assert_eq!((-1i8).wrapping_shl(8), -1);
         /// ```
         #[stable(feature = "num_wrapping", since = "1.2.0")]
         #[inline(always)]
@@ -778,8 +778,8 @@ macro_rules! int_impl {
         /// Basic usage:
         ///
         /// ```
-        /// assert_eq!(128u8.wrapping_shr(7), 1);
-        /// assert_eq!(128u8.wrapping_shr(8), 128);
+        /// assert_eq!((-128i8).wrapping_shr(7), -1);
+        /// assert_eq!((-128i8).wrapping_shr(8), -128);
         /// ```
         #[stable(feature = "num_wrapping", since = "1.2.0")]
         #[inline(always)]
@@ -1193,15 +1193,13 @@ macro_rules! uint_impl {
         ///
         /// Leading and trailing whitespace represent an error.
         ///
-        /// # Arguments
-        ///
-        /// * src - A string slice
-        /// * radix - The base to use. Must lie in the range [2 .. 36]
+        /// # Examples
         ///
-        /// # Return value
+        /// Basic usage:
         ///
-        /// `Err(ParseIntError)` if the string did not represent a valid number.
-        /// Otherwise, `Ok(n)` where `n` is the integer represented by `src`.
+        /// ```
+        /// assert_eq!(u32::from_str_radix("A", 16), Ok(10));
+        /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         pub fn from_str_radix(src: &str, radix: u32) -> Result<Self, ParseIntError> {
             from_str_radix(src, radix)
@@ -1745,7 +1743,7 @@ macro_rules! uint_impl {
         /// Basic usage:
         ///
         /// ```
-        /// assert_eq!(100i8.wrapping_rem(10), 0);
+        /// assert_eq!(100u8.wrapping_rem(10), 0);
         /// ```
         #[stable(feature = "num_wrapping", since = "1.2.0")]
         #[inline(always)]
@@ -1783,6 +1781,13 @@ macro_rules! uint_impl {
         /// where `mask` removes any high-order bits of `rhs` that
         /// would cause the shift to exceed the bitwidth of the type.
         ///
+        /// Note that this is *not* the same as a rotate-left; the
+        /// RHS of a wrapping shift-left is restricted to the range
+        /// of the type, rather than the bits shifted out of the LHS
+        /// being returned to the other end. The primitive integer
+        /// types all implement a `rotate_left` function, which may
+        /// be what you want instead.
+        ///
         /// # Examples
         ///
         /// Basic usage:
@@ -1801,6 +1806,13 @@ macro_rules! uint_impl {
         /// where `mask` removes any high-order bits of `rhs` that
         /// would cause the shift to exceed the bitwidth of the type.
         ///
+        /// Note that this is *not* the same as a rotate-right; the
+        /// RHS of a wrapping shift-right is restricted to the range
+        /// of the type, rather than the bits shifted out of the LHS
+        /// being returned to the other end. The primitive integer
+        /// types all implement a `rotate_right` function, which may
+        /// be what you want instead.
+        ///
         /// # Examples
         ///
         /// Basic usage:
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 7f8cf531d26..4d9f042fdde 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -19,7 +19,7 @@
 //! # #[allow(dead_code)]
 //! enum Result<T, E> {
 //!    Ok(T),
-//!    Err(E)
+//!    Err(E),
 //! }
 //! ```
 //!
@@ -39,7 +39,7 @@
 //!         None => Err("invalid header length"),
 //!         Some(&1) => Ok(Version::Version1),
 //!         Some(&2) => Ok(Version::Version2),
-//!         Some(_) => Err("invalid version")
+//!         Some(_) => Err("invalid version"),
 //!     }
 //! }
 //!
@@ -254,7 +254,7 @@ pub enum Result<T, E> {
 
     /// Contains the error value
     #[stable(feature = "rust1", since = "1.0.0")]
-    Err(#[stable(feature = "rust1", since = "1.0.0")] E)
+    Err(#[stable(feature = "rust1", since = "1.0.0")] E),
 }
 
 /////////////////////////////////////////////////////////////////////////////
@@ -270,6 +270,8 @@ impl<T, E> Result<T, E> {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let x: Result<i32, &str> = Ok(-3);
     /// assert_eq!(x.is_ok(), true);
@@ -290,6 +292,8 @@ impl<T, E> Result<T, E> {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let x: Result<i32, &str> = Ok(-3);
     /// assert_eq!(x.is_err(), false);
@@ -314,6 +318,8 @@ impl<T, E> Result<T, E> {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let x: Result<u32, &str> = Ok(2);
     /// assert_eq!(x.ok(), Some(2));
@@ -337,6 +343,8 @@ impl<T, E> Result<T, E> {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let x: Result<u32, &str> = Ok(2);
     /// assert_eq!(x.err(), None);
@@ -362,6 +370,10 @@ impl<T, E> Result<T, E> {
     /// Produces a new `Result`, containing a reference
     /// into the original, leaving the original in place.
     ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
     /// ```
     /// let x: Result<u32, &str> = Ok(2);
     /// assert_eq!(x.as_ref(), Ok(&2));
@@ -380,6 +392,10 @@ impl<T, E> Result<T, E> {
 
     /// Converts from `Result<T, E>` to `Result<&mut T, &mut E>`
     ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
     /// ```
     /// fn mutate(r: &mut Result<i32, i32>) {
     ///     match r.as_mut() {
@@ -445,6 +461,8 @@ impl<T, E> Result<T, E> {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// fn stringify(x: u32) -> String { format!("error code: {}", x) }
     ///
@@ -471,6 +489,8 @@ impl<T, E> Result<T, E> {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let x: Result<u32, &str> = Ok(7);
     /// assert_eq!(x.iter().next(), Some(&7));
@@ -488,6 +508,8 @@ impl<T, E> Result<T, E> {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let mut x: Result<u32, &str> = Ok(7);
     /// match x.iter_mut().next() {
@@ -513,6 +535,8 @@ impl<T, E> Result<T, E> {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let x: Result<u32, &str> = Ok(2);
     /// let y: Result<&str, &str> = Err("late error");
@@ -545,6 +569,8 @@ impl<T, E> Result<T, E> {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// fn sq(x: u32) -> Result<u32, u32> { Ok(x * x) }
     /// fn err(x: u32) -> Result<u32, u32> { Err(x) }
@@ -567,6 +593,8 @@ impl<T, E> Result<T, E> {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let x: Result<u32, &str> = Ok(2);
     /// let y: Result<u32, &str> = Err("late error");
@@ -599,6 +627,8 @@ impl<T, E> Result<T, E> {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// fn sq(x: u32) -> Result<u32, u32> { Ok(x * x) }
     /// fn err(x: u32) -> Result<u32, u32> { Err(x) }
@@ -622,6 +652,8 @@ impl<T, E> Result<T, E> {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let optb = 2;
     /// let x: Result<u32, &str> = Ok(9);
@@ -644,6 +676,8 @@ impl<T, E> Result<T, E> {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// fn count(x: &str) -> usize { x.len() }
     ///
@@ -670,6 +704,8 @@ impl<T, E: fmt::Debug> Result<T, E> {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let x: Result<u32, &str> = Ok(2);
     /// assert_eq!(x.unwrap(), 2);
@@ -696,6 +732,9 @@ impl<T, E: fmt::Debug> Result<T, E> {
     /// passed message, and the content of the `Err`.
     ///
     /// # Examples
+    ///
+    /// Basic usage:
+    ///
     /// ```{.should_panic}
     /// let x: Result<u32, &str> = Err("emergency failure");
     /// x.expect("Testing expect"); // panics with `Testing expect: emergency failure`
@@ -759,6 +798,8 @@ impl<T, E> IntoIterator for Result<T, E> {
     ///
     /// # Examples
     ///
+    /// Basic usage:
+    ///
     /// ```
     /// let x: Result<u32, &str> = Ok(5);
     /// let v: Vec<u32> = x.into_iter().collect();
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index ca1abb4fe0b..2e91238bff3 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -877,6 +877,20 @@ macro_rules! make_mut_slice {
 }
 
 /// Immutable slice iterator
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// // First, we declare a type which has `iter` method to get the `Iter` struct (&[usize here]):
+/// let slice = &[1, 2, 3];
+///
+/// // Then, we iterate over it:
+/// for element in slice.iter() {
+///     println!("{}", element);
+/// }
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Iter<'a, T: 'a> {
     ptr: *const T,
@@ -903,6 +917,26 @@ impl<'a, T> Iter<'a, T> {
     ///
     /// This has the same lifetime as the original slice, and so the
     /// iterator can continue to be used while this exists.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// // First, we declare a type which has the `iter` method to get the `Iter`
+    /// // struct (&[usize here]):
+    /// let slice = &[1, 2, 3];
+    ///
+    /// // Then, we get the iterator:
+    /// let mut iter = slice.iter();
+    /// // So if we print what `as_slice` method returns here, we have "[1, 2, 3]":
+    /// println!("{:?}", iter.as_slice());
+    ///
+    /// // Next, we move to the second element of the slice:
+    /// iter.next();
+    /// // Now `as_slice` returns "[2, 3]":
+    /// println!("{:?}", iter.as_slice());
+    /// ```
     #[stable(feature = "iter_to_slice", since = "1.4.0")]
     pub fn as_slice(&self) -> &'a [T] {
         make_slice!(self.ptr, self.end)
@@ -934,6 +968,24 @@ impl<'a, T> Clone for Iter<'a, T> {
 }
 
 /// Mutable slice iterator.
+///
+/// # Examples
+///
+/// Basic usage:
+///
+/// ```
+/// // First, we declare a type which has `iter_mut` method to get the `IterMut`
+/// // struct (&[usize here]):
+/// let mut slice = &mut [1, 2, 3];
+///
+/// // Then, we iterate over it and increment each element value:
+/// for element in slice.iter_mut() {
+///     *element += 1;
+/// }
+///
+/// // We now have "[2, 3, 4]":
+/// println!("{:?}", slice);
+/// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IterMut<'a, T: 'a> {
     ptr: *mut T,
@@ -962,6 +1014,35 @@ impl<'a, T> IterMut<'a, T> {
     /// to consume the iterator. Consider using the `Slice` and
     /// `SliceMut` implementations for obtaining slices with more
     /// restricted lifetimes that do not consume the iterator.
+    ///
+    /// # Examples
+    ///
+    /// Basic usage:
+    ///
+    /// ```
+    /// // First, we declare a type which has `iter_mut` method to get the `IterMut`
+    /// // struct (&[usize here]):
+    /// let mut slice = &mut [1, 2, 3];
+    ///
+    /// {
+    ///     // Then, we get the iterator:
+    ///     let mut iter = slice.iter_mut();
+    ///     // We move to next element:
+    ///     iter.next();
+    ///     // So if we print what `into_slice` method returns here, we have "[2, 3]":
+    ///     println!("{:?}", iter.into_slice());
+    /// }
+    ///
+    /// // Now let's modify a value of the slice:
+    /// {
+    ///     // First we get back the iterator:
+    ///     let mut iter = slice.iter_mut();
+    ///     // We change the value of the first element of the slice returned by the `next` method:
+    ///     *iter.next().unwrap() += 1;
+    /// }
+    /// // Now slice is "[2, 2, 3]":
+    /// println!("{:?}", slice);
+    /// ```
     #[stable(feature = "iter_to_slice", since = "1.4.0")]
     pub fn into_slice(self) -> &'a mut [T] {
         make_mut_slice!(self.ptr, self.end)
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index ef8670df912..f3c31d59fc4 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -1942,7 +1942,8 @@ impl StrExt for str {
         if index == 0 || index == self.len() { return true; }
         match self.as_bytes().get(index) {
             None => false,
-            Some(&b) => b < 128 || b >= 192,
+            // This is bit magic equivalent to: b < 128 || b >= 192
+            Some(&b) => (b as i8) >= -0x40,
         }
     }
 
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index f8c0b63bf11..de349917258 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -44,8 +44,9 @@ impl fmt::Debug for CodeExtent {
 
         ty::tls::with_opt(|opt_tcx| {
             if let Some(tcx) = opt_tcx {
-                let data = tcx.region_maps.code_extents.borrow()[self.0 as usize];
-                write!(f, "/{:?}", data)?;
+                if let Some(data) = tcx.region_maps.code_extents.borrow().get(self.0 as usize) {
+                    write!(f, "/{:?}", data)?;
+                }
             }
             Ok(())
         })?;
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index ae803f50231..450d25b6067 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -407,7 +407,7 @@ macro_rules! make_mir_visitor {
                             self.visit_operand(arg);
                         }
                         if let Some((ref $($mutability)* destination, target)) = *destination {
-                            self.visit_lvalue(destination, LvalueContext::Store);
+                            self.visit_lvalue(destination, LvalueContext::Call);
                             self.visit_branch(block, target);
                         }
                         cleanup.map(|t| self.visit_branch(block, t));
@@ -692,9 +692,12 @@ make_mir_visitor!(MutVisitor,mut);
 
 #[derive(Copy, Clone, Debug)]
 pub enum LvalueContext {
-    // Appears as LHS of an assignment or as dest of a call
+    // Appears as LHS of an assignment
     Store,
 
+    // Dest of a call
+    Call,
+
     // Being dropped
     Drop,
 
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index a8eac524971..bde88605e88 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -436,6 +436,7 @@ impl Target {
         key!(target_family, optional);
         key!(is_like_osx, bool);
         key!(is_like_windows, bool);
+        key!(is_like_msvc, bool);
         key!(linker_is_gnu, bool);
         key!(has_rpath, bool);
         key!(no_compiler_rt, bool);
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index 738a99fbe92..f0e834d4303 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -539,6 +539,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
             (&Failed(_), &Failed(_)) => {
                 let resolutions = target_module.resolutions.borrow();
                 let names = resolutions.iter().filter_map(|(&(ref name, _), resolution)| {
+                    if *name == source { return None; } // Never suggest the same name
                     match *resolution.borrow() {
                         NameResolution { binding: Some(_), .. } => Some(name),
                         NameResolution { single_imports: SingleImports::None, .. } => None,
@@ -549,9 +550,12 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                     Some(name) => format!(". Did you mean to use `{}`?", name),
                     None => "".to_owned(),
                 };
-                let msg = format!("There is no `{}` in `{}`{}",
-                                  source,
-                                  module_to_string(target_module), lev_suggestion);
+                let module_str = module_to_string(target_module);
+                let msg = if &module_str == "???" {
+                    format!("There is no `{}` in the crate root{}", source, lev_suggestion)
+                } else {
+                    format!("There is no `{}` in `{}`{}", source, module_str, lev_suggestion)
+                };
                 return Failed(Some((directive.span, msg)));
             }
             _ => (),
diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs
index 5014186d13b..8471b6a274c 100644
--- a/src/librustc_trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/debuginfo/metadata.rs
@@ -326,7 +326,7 @@ impl<'tcx> TypeMap<'tcx> {
                                             output: &mut String) {
             // First, find out the 'real' def_id of the type. Items inlined from
             // other crates have to be mapped back to their source.
-            let source_def_id = if let Some(node_id) = cx.tcx().map.as_local_node_id(def_id) {
+            let def_id = if let Some(node_id) = cx.tcx().map.as_local_node_id(def_id) {
                 match cx.external_srcs().borrow().get(&node_id).cloned() {
                     Some(source_def_id) => {
                         // The given def_id identifies the inlined copy of a
@@ -339,19 +339,21 @@ impl<'tcx> TypeMap<'tcx> {
                 def_id
             };
 
-            // Get the crate hash as first part of the identifier.
-            let crate_hash = if source_def_id.is_local() {
-                cx.link_meta().crate_hash.clone()
+            // Get the crate name/disambiguator as first part of the identifier.
+            let crate_name = if def_id.is_local() {
+                cx.tcx().crate_name.clone()
             } else {
-                cx.sess().cstore.crate_hash(source_def_id.krate)
+                cx.sess().cstore.original_crate_name(def_id.krate)
             };
+            let crate_disambiguator = cx.tcx().crate_disambiguator(def_id.krate);
 
-            output.push_str(crate_hash.as_str());
+            output.push_str(&crate_name[..]);
             output.push_str("/");
+            output.push_str(&crate_disambiguator[..]);
+            output.push_str("/");
+            // Add the def-index as the second part
             output.push_str(&format!("{:x}", def_id.index.as_usize()));
 
-            // Maybe check that there is no self type here.
-
             let tps = substs.types.get_slice(subst::TypeSpace);
             if !tps.is_empty() {
                 output.push('<');
diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs
index 9aa3d6c7dd0..f721e88a954 100644
--- a/src/librustc_trans/mir/analyze.rs
+++ b/src/librustc_trans/mir/analyze.rs
@@ -105,6 +105,9 @@ impl<'tcx> Visitor<'tcx> for TempAnalyzer {
         match *lvalue {
             mir::Lvalue::Temp(index) => {
                 match context {
+                    LvalueContext::Call => {
+                        self.mark_assigned(index as usize);
+                    }
                     LvalueContext::Consume => {
                     }
                     LvalueContext::Store |
diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs
index 3fabdd8fd42..303cf61ad33 100644
--- a/src/librustc_trans/mir/block.rs
+++ b/src/librustc_trans/mir/block.rs
@@ -11,12 +11,12 @@
 use llvm::{self, BasicBlockRef, ValueRef, OperandBundleDef};
 use rustc::ty;
 use rustc::mir::repr as mir;
-use abi::{Abi, FnType};
+use abi::{Abi, FnType, ArgType};
 use adt;
 use base;
 use build;
 use callee::{Callee, CalleeData, Fn, Intrinsic, NamedTupleConstructor, Virtual};
-use common::{self, Block, BlockAndBuilder, C_undef};
+use common::{self, type_is_fat_ptr, Block, BlockAndBuilder, C_undef};
 use debuginfo::DebugLoc;
 use Disr;
 use machine::{llalign_of_min, llbitsize_of_real};
@@ -25,7 +25,7 @@ use type_of;
 use glue;
 use type_::Type;
 
-use super::{MirContext, drop};
+use super::{MirContext, TempRef, drop};
 use super::lvalue::{LvalueRef, load_fat_ptr};
 use super::operand::OperandRef;
 use super::operand::OperandValue::{self, FatPtr, Immediate, Ref};
@@ -169,6 +169,8 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                     _ => bug!("{} is not callable", callee.ty)
                 };
 
+                let sig = bcx.tcx().erase_late_bound_regions(sig);
+
                 // Handle intrinsics old trans wants Expr's for, ourselves.
                 let intrinsic = match (&callee.ty.sty, &callee.data) {
                     (&ty::TyFnDef(def_id, _, _), &Intrinsic) => {
@@ -191,31 +193,16 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
 
                 if intrinsic == Some("transmute") {
                     let &(ref dest, target) = destination.as_ref().unwrap();
-                    let dst = self.trans_lvalue(&bcx, dest);
-                    let mut val = self.trans_operand(&bcx, &args[0]);
-                    if let ty::TyFnDef(def_id, substs, _) = val.ty.sty {
-                        let llouttype = type_of::type_of(bcx.ccx(), dst.ty.to_ty(bcx.tcx()));
-                        let out_type_size = llbitsize_of_real(bcx.ccx(), llouttype);
-                        if out_type_size != 0 {
-                            // FIXME #19925 Remove this hack after a release cycle.
-                            let f = Callee::def(bcx.ccx(), def_id, substs);
-                            let datum = f.reify(bcx.ccx());
-                            val = OperandRef {
-                                val: OperandValue::Immediate(datum.val),
-                                ty: datum.ty
-                            };
-                        }
-                    }
+                    self.with_lvalue_ref(&bcx, dest, |this, dest| {
+                        this.trans_transmute(&bcx, &args[0], dest);
+                    });
 
-                    let llty = type_of::type_of(bcx.ccx(), val.ty);
-                    let cast_ptr = bcx.pointercast(dst.llval, llty.ptr_to());
-                    self.store_operand(&bcx, cast_ptr, val);
                     self.set_operand_dropped(&bcx, &args[0]);
                     funclet_br(bcx, self.llblock(target));
                     return;
                 }
 
-                let extra_args = &args[sig.0.inputs.len()..];
+                let extra_args = &args[sig.inputs.len()..];
                 let extra_args = extra_args.iter().map(|op_arg| {
                     self.mir.operand_ty(bcx.tcx(), op_arg)
                 }).collect::<Vec<_>>();
@@ -226,18 +213,15 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                 let mut llargs = Vec::with_capacity(arg_count);
 
                 // Prepare the return value destination
-                let ret_dest = if let Some((ref d, _)) = *destination {
-                    let dest = self.trans_lvalue(&bcx, d);
-                    if fn_ty.ret.is_indirect() {
-                        llargs.push(dest.llval);
-                        None
-                    } else if fn_ty.ret.is_ignore() {
-                        None
+                let ret_dest = if let Some((ref dest, _)) = *destination {
+                    let is_intrinsic = if let Intrinsic = callee.data {
+                        true
                     } else {
-                        Some(dest)
-                    }
+                        false
+                    };
+                    self.make_return_dest(&bcx, dest, &fn_ty.ret, &mut llargs, is_intrinsic)
                 } else {
-                    None
+                    ReturnDest::Nothing
                 };
 
                 // Split the rust-call tupled arguments off.
@@ -269,29 +253,42 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                         use expr::{Ignore, SaveIn};
                         use intrinsic::trans_intrinsic_call;
 
-                        let (dest, llargs) = if fn_ty.ret.is_indirect() {
-                            (SaveIn(llargs[0]), &llargs[1..])
-                        } else if let Some(dest) = ret_dest {
-                            (SaveIn(dest.llval), &llargs[..])
-                        } else {
-                            (Ignore, &llargs[..])
+                        let (dest, llargs) = match ret_dest {
+                            _ if fn_ty.ret.is_indirect() => {
+                                (SaveIn(llargs[0]), &llargs[1..])
+                            }
+                            ReturnDest::Nothing => (Ignore, &llargs[..]),
+                            ReturnDest::IndirectOperand(dst, _) |
+                            ReturnDest::Store(dst) => (SaveIn(dst), &llargs[..]),
+                            ReturnDest::DirectOperand(_) =>
+                                bug!("Cannot use direct operand with an intrinsic call")
                         };
 
                         bcx.with_block(|bcx| {
-                            let res = trans_intrinsic_call(bcx, callee.ty, &fn_ty,
+                            trans_intrinsic_call(bcx, callee.ty, &fn_ty,
                                                            ArgVals(llargs), dest,
                                                            DebugLoc::None);
-                            let bcx = res.bcx.build();
-                            if let Some((_, target)) = *destination {
-                                for op in args {
-                                    self.set_operand_dropped(&bcx, op);
-                                }
-                                funclet_br(bcx, self.llblock(target));
-                            } else {
-                                // trans_intrinsic_call already used Unreachable.
-                                // bcx.unreachable();
-                            }
                         });
+
+                        if let ReturnDest::IndirectOperand(dst, _) = ret_dest {
+                            // Make a fake operand for store_return
+                            let op = OperandRef {
+                                val: OperandValue::Ref(dst),
+                                ty: sig.output.unwrap()
+                            };
+                            self.store_return(&bcx, ret_dest, fn_ty.ret, op);
+                        }
+
+                        if let Some((_, target)) = *destination {
+                            for op in args {
+                                self.set_operand_dropped(&bcx, op);
+                            }
+                            funclet_br(bcx, self.llblock(target));
+                        } else {
+                            // trans_intrinsic_call already used Unreachable.
+                            // bcx.unreachable();
+                        }
+
                         return;
                     }
                     Fn(f) => f,
@@ -321,9 +318,11 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                     if destination.is_some() {
                         let ret_bcx = ret_bcx.build();
                         ret_bcx.at_start(|ret_bcx| {
-                            if let Some(ret_dest) = ret_dest {
-                                fn_ty.ret.store(&ret_bcx, invokeret, ret_dest.llval);
-                            }
+                            let op = OperandRef {
+                                val: OperandValue::Immediate(invokeret),
+                                ty: sig.output.unwrap()
+                            };
+                            self.store_return(&ret_bcx, ret_dest, fn_ty.ret, op);
                             for op in args {
                                 self.set_operand_dropped(&ret_bcx, op);
                             }
@@ -333,9 +332,11 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
                     let llret = bcx.call(fn_ptr, &llargs, cleanup_bundle.as_ref());
                     fn_ty.apply_attrs_callsite(llret);
                     if let Some((_, target)) = *destination {
-                        if let Some(ret_dest) = ret_dest {
-                            fn_ty.ret.store(&bcx, llret, ret_dest.llval);
-                        }
+                        let op = OperandRef {
+                            val: OperandValue::Immediate(llret),
+                            ty: sig.output.unwrap()
+                        };
+                        self.store_return(&bcx, ret_dest, fn_ty.ret, op);
                         for op in args {
                             self.set_operand_dropped(&bcx, op);
                         }
@@ -544,4 +545,122 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
     pub fn llblock(&self, bb: mir::BasicBlock) -> BasicBlockRef {
         self.blocks[bb.index()].llbb
     }
+
+    fn make_return_dest(&mut self, bcx: &BlockAndBuilder<'bcx, 'tcx>,
+                        dest: &mir::Lvalue<'tcx>, fn_ret_ty: &ArgType,
+                        llargs: &mut Vec<ValueRef>, is_intrinsic: bool) -> ReturnDest {
+        // If the return is ignored, we can just return a do-nothing ReturnDest
+        if fn_ret_ty.is_ignore() {
+            return ReturnDest::Nothing;
+        }
+        let dest = match *dest {
+            mir::Lvalue::Temp(idx) => {
+                let lvalue_ty = self.mir.lvalue_ty(bcx.tcx(), dest);
+                let lvalue_ty = bcx.monomorphize(&lvalue_ty);
+                let ret_ty = lvalue_ty.to_ty(bcx.tcx());
+                match self.temps[idx as usize] {
+                    TempRef::Lvalue(dest) => dest,
+                    TempRef::Operand(None) => {
+                        // Handle temporary lvalues, specifically Operand ones, as
+                        // they don't have allocas
+                        return if fn_ret_ty.is_indirect() {
+                            // Odd, but possible, case, we have an operand temporary,
+                            // but the calling convention has an indirect return.
+                            let tmp = bcx.with_block(|bcx| {
+                                base::alloc_ty(bcx, ret_ty, "tmp_ret")
+                            });
+                            llargs.push(tmp);
+                            ReturnDest::IndirectOperand(tmp, idx)
+                        } else if is_intrinsic {
+                            // Currently, intrinsics always need a location to store
+                            // the result. so we create a temporary alloca for the
+                            // result
+                            let tmp = bcx.with_block(|bcx| {
+                                base::alloc_ty(bcx, ret_ty, "tmp_ret")
+                            });
+                            ReturnDest::IndirectOperand(tmp, idx)
+                        } else {
+                            ReturnDest::DirectOperand(idx)
+                        };
+                    }
+                    TempRef::Operand(Some(_)) => {
+                        bug!("lvalue temp already assigned to");
+                    }
+                }
+            }
+            _ => self.trans_lvalue(bcx, dest)
+        };
+        if fn_ret_ty.is_indirect() {
+            llargs.push(dest.llval);
+            ReturnDest::Nothing
+        } else {
+            ReturnDest::Store(dest.llval)
+        }
+    }
+
+    fn trans_transmute(&mut self, bcx: &BlockAndBuilder<'bcx, 'tcx>,
+                       src: &mir::Operand<'tcx>, dst: LvalueRef<'tcx>) {
+        let mut val = self.trans_operand(bcx, src);
+        if let ty::TyFnDef(def_id, substs, _) = val.ty.sty {
+            let llouttype = type_of::type_of(bcx.ccx(), dst.ty.to_ty(bcx.tcx()));
+            let out_type_size = llbitsize_of_real(bcx.ccx(), llouttype);
+            if out_type_size != 0 {
+                // FIXME #19925 Remove this hack after a release cycle.
+                let f = Callee::def(bcx.ccx(), def_id, substs);
+                let datum = f.reify(bcx.ccx());
+                val = OperandRef {
+                    val: OperandValue::Immediate(datum.val),
+                    ty: datum.ty
+                };
+            }
+        }
+
+        let llty = type_of::type_of(bcx.ccx(), val.ty);
+        let cast_ptr = bcx.pointercast(dst.llval, llty.ptr_to());
+        self.store_operand(bcx, cast_ptr, val);
+    }
+
+    // Stores the return value of a function call into it's final location.
+    fn store_return(&mut self,
+                    bcx: &BlockAndBuilder<'bcx, 'tcx>,
+                    dest: ReturnDest,
+                    ret_ty: ArgType,
+                    op: OperandRef<'tcx>) {
+        use self::ReturnDest::*;
+
+        match dest {
+            Nothing => (),
+            Store(dst) => ret_ty.store(bcx, op.immediate(), dst),
+            IndirectOperand(tmp, idx) => {
+                let op = self.trans_load(bcx, tmp, op.ty);
+                self.temps[idx as usize] = TempRef::Operand(Some(op));
+            }
+            DirectOperand(idx) => {
+                let op = if type_is_fat_ptr(bcx.tcx(), op.ty) {
+                    let llval = op.immediate();
+                    let ptr = bcx.extract_value(llval, 0);
+                    let meta = bcx.extract_value(llval, 1);
+
+                    OperandRef {
+                        val: OperandValue::FatPtr(ptr, meta),
+                        ty: op.ty
+                    }
+                } else {
+                    op
+                };
+                self.temps[idx as usize] = TempRef::Operand(Some(op));
+            }
+        }
+    }
+}
+
+enum ReturnDest {
+    // Do nothing, the return value is indirect or ignored
+    Nothing,
+    // Store the return value to the pointer
+    Store(ValueRef),
+    // Stores an indirect return value to an operand temporary lvalue
+    IndirectOperand(ValueRef, u32),
+    // Stores a direct return value to an operand temporary lvalue
+    DirectOperand(u32)
 }
diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs
index c9087181f9d..695806aa82c 100644
--- a/src/librustc_trans/mir/lvalue.rs
+++ b/src/librustc_trans/mir/lvalue.rs
@@ -207,6 +207,40 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
         }
     }
 
+    // Perform an action using the given Lvalue.
+    // If the Lvalue is an empty TempRef::Operand, then a temporary stack slot
+    // is created first, then used as an operand to update the Lvalue.
+    pub fn with_lvalue_ref<F, U>(&mut self, bcx: &BlockAndBuilder<'bcx, 'tcx>,
+                                 lvalue: &mir::Lvalue<'tcx>, f: F) -> U
+    where F: FnOnce(&mut Self, LvalueRef<'tcx>) -> U
+    {
+        match *lvalue {
+            mir::Lvalue::Temp(idx) => {
+                match self.temps[idx as usize] {
+                    TempRef::Lvalue(lvalue) => f(self, lvalue),
+                    TempRef::Operand(None) => {
+                        let lvalue_ty = self.mir.lvalue_ty(bcx.tcx(), lvalue);
+                        let lvalue_ty = bcx.monomorphize(&lvalue_ty);
+                        let lvalue = LvalueRef::alloca(bcx,
+                                                       lvalue_ty.to_ty(bcx.tcx()),
+                                                       "lvalue_temp");
+                        let ret = f(self, lvalue);
+                        let op = self.trans_load(bcx, lvalue.llval, lvalue_ty.to_ty(bcx.tcx()));
+                        self.temps[idx as usize] = TempRef::Operand(Some(op));
+                        ret
+                    }
+                    TempRef::Operand(Some(_)) => {
+                        bug!("Lvalue temp already set");
+                    }
+                }
+            }
+            _ => {
+                let lvalue = self.trans_lvalue(bcx, lvalue);
+                f(self, lvalue)
+            }
+        }
+    }
+
     /// Adjust the bitwidth of an index since LLVM is less forgiving
     /// than we are.
     ///
diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs
index 500eda2624c..1f0a18ad4fa 100644
--- a/src/librustc_trans/type_of.rs
+++ b/src/librustc_trans/type_of.rs
@@ -182,7 +182,7 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
 
     debug!("type_of {:?}", t);
 
-    assert!(!t.has_escaping_regions());
+    assert!(!t.has_escaping_regions(), "{:?} has escaping regions", t);
 
     // Replace any typedef'd types with their equivalent non-typedef
     // type. This ensures that all LLVM nominal types that contain
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 45877d7099b..67b91f7838c 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2578,24 +2578,33 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                 ty::TyFloat(ast::FloatTy::F32) => {
                     fcx.type_error_message(arg.span,
                                            |t| {
-                        format!("can't pass an {} to variadic \
-                                 function, cast to c_double", t)
+                        format!("can't pass an `{}` to variadic \
+                                 function, cast to `c_double`", t)
                     }, arg_ty, None);
                 }
                 ty::TyInt(ast::IntTy::I8) | ty::TyInt(ast::IntTy::I16) | ty::TyBool => {
                     fcx.type_error_message(arg.span, |t| {
-                        format!("can't pass {} to variadic \
-                                 function, cast to c_int",
+                        format!("can't pass `{}` to variadic \
+                                 function, cast to `c_int`",
                                        t)
                     }, arg_ty, None);
                 }
                 ty::TyUint(ast::UintTy::U8) | ty::TyUint(ast::UintTy::U16) => {
                     fcx.type_error_message(arg.span, |t| {
-                        format!("can't pass {} to variadic \
-                                 function, cast to c_uint",
+                        format!("can't pass `{}` to variadic \
+                                 function, cast to `c_uint`",
                                        t)
                     }, arg_ty, None);
                 }
+                ty::TyFnDef(_, _, f) => {
+                    let ptr_ty = fcx.tcx().mk_ty(ty::TyFnPtr(f));
+                    let ptr_ty = fcx.infcx().resolve_type_vars_if_possible(&ptr_ty);
+                    fcx.type_error_message(arg.span,
+                                           |t| {
+                        format!("can't pass `{}` to variadic \
+                                 function, cast to `{}`", t, ptr_ty)
+                    }, arg_ty, None);
+                }
                 _ => {}
             }
         }
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index bef6c1ed43a..8f76bf92ef4 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -3644,6 +3644,68 @@ fn main() {
 ```
 "##,
 
+E0520: r##"
+A non-default implementation was already made on this type so it cannot be
+specialized further. Erroneous code example:
+
+```compile_fail
+#![feature(specialization)]
+
+trait SpaceLlama {
+    fn fly(&self);
+}
+
+// applies to all T
+impl<T> SpaceLlama for T {
+    default fn fly(&self) {}
+}
+
+// non-default impl
+// applies to all `Clone` T and overrides the previous impl
+impl<T: Clone> SpaceLlama for T {
+    fn fly(&self) {}
+}
+
+// since `i32` is clone, this conflicts with the previous implementation
+impl SpaceLlama for i32 {
+    default fn fly(&self) {}
+    // error: item `fly` is provided by an `impl` that specializes
+    //        another, but the item in the parent `impl` is not marked
+    //        `default` and so it cannot be specialized.
+}
+```
+
+Specialization only allows you to override `default` functions in
+implementations.
+
+To fix this error, you need to mark all the parent implementations as default.
+Example:
+
+```
+#![feature(specialization)]
+
+trait SpaceLlama {
+    fn fly(&self);
+}
+
+// applies to all T
+impl<T> SpaceLlama for T {
+    default fn fly(&self) {} // This is a parent implementation.
+}
+
+// applies to all `Clone` T; overrides the previous impl
+impl<T: Clone> SpaceLlama for T {
+    default fn fly(&self) {} // This is a parent implementation but was
+                             // previously not a default one, causing the error
+}
+
+// applies to i32, overrides the previous two impls
+impl SpaceLlama for i32 {
+    fn fly(&self) {} // And now that's ok!
+}
+```
+"##,
+
 }
 
 register_diagnostics! {
@@ -3720,6 +3782,5 @@ register_diagnostics! {
            // type `{}` was overridden
     E0436, // functional record update requires a struct
     E0513, // no type for local variable ..
-    E0520, // cannot specialize non-default item
     E0521  // redundant default implementations of trait
 }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 673aa17ecd1..d8d1472560d 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -54,10 +54,6 @@ use doctree;
 use visit_ast;
 use html::item_type::ItemType;
 
-/// A stable identifier to the particular version of JSON output.
-/// Increment this when the `Crate` and related structures change.
-pub const SCHEMA_VERSION: &'static str = "0.8.3";
-
 mod inline;
 mod simplify;
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index ba0dae6efb9..bc7c7c5e0ca 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -52,22 +52,16 @@ use std::cell::RefCell;
 use std::collections::HashMap;
 use std::default::Default;
 use std::env;
-use std::fs::File;
-use std::io::{self, Read, Write};
+use std::io::Read;
 use std::path::PathBuf;
 use std::process;
 use std::rc::Rc;
 use std::sync::mpsc::channel;
 
 use externalfiles::ExternalHtml;
-use serialize::Decodable;
-use serialize::json::{self, Json};
 use rustc::session::search_paths::SearchPaths;
 use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options};
 
-// reexported from `clean` so it can be easily updated with the mod itself
-pub use clean::SCHEMA_VERSION;
-
 #[macro_use]
 pub mod externalfiles;
 
@@ -125,7 +119,6 @@ thread_local!(pub static ANALYSISKEY: Rc<RefCell<Option<core::CrateAnalysis>>> =
 
 struct Output {
     krate: clean::Crate,
-    json_plugins: Vec<plugins::PluginJson>,
     passes: Vec<String>,
 }
 
@@ -148,9 +141,9 @@ pub fn opts() -> Vec<RustcOptGroup> {
         stable(optflag("V", "version", "print rustdoc's version")),
         stable(optflag("v", "verbose", "use verbose output")),
         stable(optopt("r", "input-format", "the input type of the specified file",
-                      "[rust|json]")),
+                      "[rust]")),
         stable(optopt("w", "output-format", "the output type to write",
-                      "[html|json]")),
+                      "[html]")),
         stable(optopt("o", "output", "where to place the output", "PATH")),
         stable(optopt("", "crate-name", "specify the name of this crate", "NAME")),
         stable(optmulti("L", "library-path", "directory to add to crate search path",
@@ -309,7 +302,7 @@ pub fn main_args(args: &[String]) -> isize {
             return 1;
         }
     };
-    let Output { krate, json_plugins, passes, } = out;
+    let Output { krate, passes, } = out;
     info!("going to format");
     match matches.opt_str("w").as_ref().map(|s| &**s) {
         Some("html") | None => {
@@ -319,11 +312,6 @@ pub fn main_args(args: &[String]) -> isize {
                               css_file_extension)
                 .expect("failed to generate documentation")
         }
-        Some("json") => {
-            json_output(krate, json_plugins,
-                        output.unwrap_or(PathBuf::from("doc.json")))
-                .expect("failed to write json")
-        }
         Some(s) => {
             println!("unknown output format: {}", s);
             return 1;
@@ -340,14 +328,9 @@ fn acquire_input(input: &str,
                  matches: &getopts::Matches) -> Result<Output, String> {
     match matches.opt_str("r").as_ref().map(|s| &**s) {
         Some("rust") => Ok(rust_input(input, externs, matches)),
-        Some("json") => json_input(input),
         Some(s) => Err(format!("unknown input format: {}", s)),
         None => {
-            if input.ends_with(".json") {
-                json_input(input)
-            } else {
-                Ok(rust_input(input, externs, matches))
-            }
+            Ok(rust_input(input, externs, matches))
         }
     }
 }
@@ -459,76 +442,6 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
 
     // Run everything!
     info!("Executing passes/plugins");
-    let (krate, json) = pm.run_plugins(krate);
-    Output { krate: krate, json_plugins: json, passes: passes }
-}
-
-/// This input format purely deserializes the json output file. No passes are
-/// run over the deserialized output.
-fn json_input(input: &str) -> Result<Output, String> {
-    let mut bytes = Vec::new();
-    if let Err(e) = File::open(input).and_then(|mut f| f.read_to_end(&mut bytes)) {
-        return Err(format!("couldn't open {}: {}", input, e))
-    }
-    match json::from_reader(&mut &bytes[..]) {
-        Err(s) => Err(format!("{:?}", s)),
-        Ok(Json::Object(obj)) => {
-            let mut obj = obj;
-            // Make sure the schema is what we expect
-            match obj.remove(&"schema".to_string()) {
-                Some(Json::String(version)) => {
-                    if version != SCHEMA_VERSION {
-                        return Err(format!(
-                                "sorry, but I only understand version {}",
-                                SCHEMA_VERSION))
-                    }
-                }
-                Some(..) => return Err("malformed json".to_string()),
-                None => return Err("expected a schema version".to_string()),
-            }
-            let krate = match obj.remove(&"crate".to_string()) {
-                Some(json) => {
-                    let mut d = json::Decoder::new(json);
-                    Decodable::decode(&mut d).unwrap()
-                }
-                None => return Err("malformed json".to_string()),
-            };
-            // FIXME: this should read from the "plugins" field, but currently
-            //      Json doesn't implement decodable...
-            let plugin_output = Vec::new();
-            Ok(Output { krate: krate, json_plugins: plugin_output, passes: Vec::new(), })
-        }
-        Ok(..) => {
-            Err("malformed json input: expected an object at the \
-                 top".to_string())
-        }
-    }
-}
-
-/// Outputs the crate/plugin json as a giant json blob at the specified
-/// destination.
-fn json_output(krate: clean::Crate, res: Vec<plugins::PluginJson> ,
-               dst: PathBuf) -> io::Result<()> {
-    // {
-    //   "schema": version,
-    //   "crate": { parsed crate ... },
-    //   "plugins": { output of plugins ... }
-    // }
-    let mut json = std::collections::BTreeMap::new();
-    json.insert("schema".to_string(), Json::String(SCHEMA_VERSION.to_string()));
-    let plugins_json = res.into_iter()
-                          .filter_map(|opt| {
-                              opt.map(|(string, json)| (string.to_string(), json))
-                          }).collect();
-
-    // FIXME #8335: yuck, Rust -> str -> JSON round trip! No way to .encode
-    // straight to the Rust JSON representation.
-    let crate_json_str = format!("{}", json::as_json(&krate));
-    let crate_json = json::from_str(&crate_json_str).expect("Rust generated JSON is invalid");
-
-    json.insert("crate".to_string(), crate_json);
-    json.insert("plugins".to_string(), Json::Object(plugins_json));
-
-    let mut file = File::create(&dst)?;
-    write!(&mut file, "{}", Json::Object(json))
+    let krate = pm.run_plugins(krate);
+    Output { krate: krate, passes: passes }
 }
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index ff2a9f13e8a..adc39b69986 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -54,7 +54,7 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
     };
 
     // strip any traits implemented on stripped items
-    let krate = {
+    {
         struct ImplStripper<'a> {
             stripped: &'a mut DefIdSet
         }
@@ -80,9 +80,7 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
         }
         let mut stripper = ImplStripper{ stripped: &mut stripped };
         stripper.fold_crate(krate)
-    };
-
-    (krate, None)
+    }
 }
 
 /// Strip private items from the point of view of a crate or externally from a
@@ -107,9 +105,8 @@ pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
     // strip all private implementations of traits
     {
         let mut stripper = ImplStripper(&retained);
-        krate = stripper.fold_crate(krate);
+        stripper.fold_crate(krate)
     }
-    (krate, None)
 }
 
 struct Stripper<'a> {
@@ -192,17 +189,19 @@ impl<'a> fold::DocFolder for Stripper<'a> {
             self.fold_item_recur(i)
         };
 
-        i.and_then(|i| { match i.inner {
-            // emptied modules/impls have no need to exist
-            clean::ModuleItem(ref m)
-                if m.items.is_empty() &&
-                   i.doc_value().is_none() => None,
-            clean::ImplItem(ref i) if i.items.is_empty() => None,
-            _ => {
-                self.retained.insert(i.def_id);
-                Some(i)
+        i.and_then(|i| {
+            match i.inner {
+                // emptied modules/impls have no need to exist
+                clean::ModuleItem(ref m)
+                    if m.items.is_empty() &&
+                       i.doc_value().is_none() => None,
+                clean::ImplItem(ref i) if i.items.is_empty() => None,
+                _ => {
+                    self.retained.insert(i.def_id);
+                    Some(i)
+                }
             }
-        }})
+        })
     }
 }
 
@@ -234,7 +233,7 @@ impl fold::DocFolder for ImportStripper {
 }
 
 pub fn strip_priv_imports(krate: clean::Crate)  -> plugins::PluginResult {
-    (ImportStripper.fold_crate(krate), None)
+    ImportStripper.fold_crate(krate)
 }
 
 pub fn unindent_comments(krate: clean::Crate) -> plugins::PluginResult {
@@ -258,7 +257,7 @@ pub fn unindent_comments(krate: clean::Crate) -> plugins::PluginResult {
     }
     let mut cleaner = CommentCleaner;
     let krate = cleaner.fold_crate(krate);
-    (krate, None)
+    krate
 }
 
 pub fn collapse_docs(krate: clean::Crate) -> plugins::PluginResult {
@@ -287,7 +286,7 @@ pub fn collapse_docs(krate: clean::Crate) -> plugins::PluginResult {
     }
     let mut collapser = Collapser;
     let krate = collapser.fold_crate(krate);
-    (krate, None)
+    krate
 }
 
 pub fn unindent(s: &str) -> String {
diff --git a/src/librustdoc/plugins.rs b/src/librustdoc/plugins.rs
index 83ce3e61ab2..b8be84825c9 100644
--- a/src/librustdoc/plugins.rs
+++ b/src/librustdoc/plugins.rs
@@ -12,15 +12,13 @@
 
 use clean;
 
-use serialize::json;
 use std::mem;
 use std::string::String;
 use std::path::PathBuf;
 
 use rustc_back::dynamic_lib as dl;
 
-pub type PluginJson = Option<(String, json::Json)>;
-pub type PluginResult = (clean::Crate, PluginJson);
+pub type PluginResult = clean::Crate;
 pub type PluginCallback = fn (clean::Crate) -> PluginResult;
 
 /// Manages loading and running of plugins
@@ -65,15 +63,11 @@ impl PluginManager {
         self.callbacks.push(plugin);
     }
     /// Run all the loaded plugins over the crate, returning their results
-    pub fn run_plugins(&self, krate: clean::Crate) -> (clean::Crate, Vec<PluginJson> ) {
-        let mut out_json = Vec::new();
-        let mut krate = krate;
+    pub fn run_plugins(&self, mut krate: clean::Crate) -> clean::Crate {
         for &callback in &self.callbacks {
-            let (c, res) = callback(krate);
-            krate = c;
-            out_json.push(res);
+            krate = callback(krate);
         }
-        (krate, out_json)
+        krate
     }
 }
 
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 71c522e9e75..982f477fc4a 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -122,8 +122,8 @@ pub fn run(input: &str,
     if let Some(name) = crate_name {
         krate.name = name;
     }
-    let (krate, _) = passes::collapse_docs(krate);
-    let (krate, _) = passes::unindent_comments(krate);
+    let krate = passes::collapse_docs(krate);
+    let krate = passes::unindent_comments(krate);
 
     let mut collector = Collector::new(krate.name.to_string(),
                                        cfgs,
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 5309cc3c858..f413bed86a8 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -466,7 +466,7 @@ enum State {
     Done = 3,
 }
 
-/// A Windows path prefix, e.g. `C:` or `\server\share`.
+/// A Windows path prefix, e.g. `C:` or `\\server\share`.
 ///
 /// Does not occur on Unix.
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -528,7 +528,7 @@ impl<'a> Hash for PrefixComponent<'a> {
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub enum Component<'a> {
-    /// A Windows path prefix, e.g. `C:` or `\server\share`.
+    /// A Windows path prefix, e.g. `C:` or `\\server\share`.
     ///
     /// Does not occur on Unix.
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 99de4aa0086..fc18ef407ab 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -218,10 +218,10 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
     ("naked_functions", "1.9.0", Some(32408), Active),
 
     // allow empty structs and enum variants with braces
-    ("braced_empty_structs", "1.5.0", Some(29720), Accepted),
+    ("braced_empty_structs", "1.8.0", Some(29720), Accepted),
 
     // allow overloading augmented assignment operations like `a += b`
-    ("augmented_assignments", "1.5.0", Some(28235), Accepted),
+    ("augmented_assignments", "1.8.0", Some(28235), Accepted),
 
     // allow `#[no_debug]`
     ("no_debug", "1.5.0", Some(29721), Active),
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index b8c926f8de9..c4997348537 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2578,7 +2578,7 @@ impl<'a> Parser<'a> {
         loop {
             // expr?
             while self.eat(&token::Question) {
-                let hi = self.span.hi;
+                let hi = self.last_span.hi;
                 e = self.mk_expr(lo, hi, ExprKind::Try(e), None);
             }
 
diff --git a/src/test/compile-fail/extern-crate-visibility.rs b/src/test/compile-fail/extern-crate-visibility.rs
index 56a41a15ab3..86aae472148 100644
--- a/src/test/compile-fail/extern-crate-visibility.rs
+++ b/src/test/compile-fail/extern-crate-visibility.rs
@@ -30,5 +30,14 @@ fn f() {
     mod core {} // Check that private crates are not glob imported
 }
 
+mod bar {
+    pub extern crate core;
+}
+
+mod baz {
+    pub use bar::*;
+    use self::core::cell; // Check that public extern crates are glob imported
+}
+
 #[rustc_error]
 fn main() {} //~ ERROR compilation successful
diff --git a/src/test/compile-fail/issue-24883.rs b/src/test/compile-fail/issue-24883.rs
new file mode 100644
index 00000000000..097f2a5630c
--- /dev/null
+++ b/src/test/compile-fail/issue-24883.rs
@@ -0,0 +1,28 @@
+// Copyright 2016 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(rustc_attrs)]
+
+mod a {
+    pub mod b { pub struct Foo; }
+
+    pub mod c {
+        use super::b;
+        pub struct Bar(pub b::Foo);
+    }
+
+    pub use self::c::*;
+}
+
+#[rustc_error]
+fn main() {  //~ ERROR compilation successful
+    let _ = a::c::Bar(a::b::Foo);
+    let _ = a::Bar(a::b::Foo);
+}
diff --git a/src/test/compile-fail/issue-26930.rs b/src/test/compile-fail/issue-26930.rs
new file mode 100644
index 00000000000..6c98f3e8560
--- /dev/null
+++ b/src/test/compile-fail/issue-26930.rs
@@ -0,0 +1,20 @@
+// Copyright 2016 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(rustc_attrs)]
+#![allow(unused)]
+
+extern crate core;
+use core as core_export;
+use self::x::*;
+mod x {}
+
+#[rustc_error]
+fn main() {} //~ ERROR compilation successful
diff --git a/src/test/compile-fail/issue-32201.rs b/src/test/compile-fail/issue-32201.rs
new file mode 100644
index 00000000000..bcc53df68a3
--- /dev/null
+++ b/src/test/compile-fail/issue-32201.rs
@@ -0,0 +1,22 @@
+// Copyright 2016 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.
+
+extern {
+    fn foo(a: i32, ...);
+}
+
+fn bar(_: *const u8) {}
+
+fn main() {
+    unsafe {
+        foo(0, bar);
+        //~^ ERROR can't pass `fn(*const u8) {bar}` to variadic function, cast to `fn(*const u8)`
+    }
+}
diff --git a/src/test/compile-fail/issue-32833.rs b/src/test/compile-fail/issue-32833.rs
new file mode 100644
index 00000000000..22261d98a12
--- /dev/null
+++ b/src/test/compile-fail/issue-32833.rs
@@ -0,0 +1,16 @@
+// Copyright 2016 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 bar::Foo; //~ ERROR There is no `Foo` in `bar` [E0432]
+mod bar {
+    use Foo; //~ ERROR There is no `Foo` in the crate root [E0432]
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/symbol-names/issue-32709.rs b/src/test/compile-fail/symbol-names/issue-32709.rs
new file mode 100644
index 00000000000..f9d11f3a171
--- /dev/null
+++ b/src/test/compile-fail/symbol-names/issue-32709.rs
@@ -0,0 +1,20 @@
+// Copyright 2016 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(question_mark)]
+
+// Make sure that the span of try shorthand does not include the trailing
+// semicolon;
+fn a() -> Result<i32, ()> {
+    Err(5)?; //~ ERROR 16:5: 16:12
+    Ok(1)
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/use-mod-2.rs b/src/test/compile-fail/use-mod-2.rs
index e98224bee02..f2384912cdb 100644
--- a/src/test/compile-fail/use-mod-2.rs
+++ b/src/test/compile-fail/use-mod-2.rs
@@ -10,10 +10,10 @@
 
 mod foo {
     use self::{self};
-    //~^ ERROR unresolved import `self`. There is no `self` in `???`
+    //~^ ERROR unresolved import `self`. There is no `self` in the crate root
 
     use super::{self};
-    //~^ ERROR unresolved import `super`. There is no `super` in `???`
+    //~^ ERROR unresolved import `super`. There is no `super` in the crate root
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/variadic-ffi-3.rs b/src/test/compile-fail/variadic-ffi-3.rs
index 1d5ebdbae3e..6e60562da67 100644
--- a/src/test/compile-fail/variadic-ffi-3.rs
+++ b/src/test/compile-fail/variadic-ffi-3.rs
@@ -33,11 +33,11 @@ fn main() {
         //~| expected variadic fn
         //~| found non-variadic function
 
-        foo(1, 2, 3f32); //~ ERROR: can't pass an f32 to variadic function, cast to c_double
-        foo(1, 2, true); //~ ERROR: can't pass bool to variadic function, cast to c_int
-        foo(1, 2, 1i8); //~ ERROR: can't pass i8 to variadic function, cast to c_int
-        foo(1, 2, 1u8); //~ ERROR: can't pass u8 to variadic function, cast to c_uint
-        foo(1, 2, 1i16); //~ ERROR: can't pass i16 to variadic function, cast to c_int
-        foo(1, 2, 1u16); //~ ERROR: can't pass u16 to variadic function, cast to c_uint
+        foo(1, 2, 3f32); //~ ERROR: can't pass an `f32` to variadic function, cast to `c_double`
+        foo(1, 2, true); //~ ERROR: can't pass `bool` to variadic function, cast to `c_int`
+        foo(1, 2, 1i8); //~ ERROR: can't pass `i8` to variadic function, cast to `c_int`
+        foo(1, 2, 1u8); //~ ERROR: can't pass `u8` to variadic function, cast to `c_uint`
+        foo(1, 2, 1i16); //~ ERROR: can't pass `i16` to variadic function, cast to `c_int`
+        foo(1, 2, 1u16); //~ ERROR: can't pass `u16` to variadic function, cast to `c_uint`
     }
 }
diff --git a/src/test/run-make/rustdoc-json/foo.rs b/src/test/parse-fail/issue-32505.rs
index 3bd56c14193..e697e98bc06 100644
--- a/src/test/run-make/rustdoc-json/foo.rs
+++ b/src/test/parse-fail/issue-32505.rs
@@ -8,18 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![crate_name = "foo"]
+// compile-flags: -Z parse-only -Z continue-parse-after-error
 
-//! Very docs
-
-pub mod bar {
-
-    /// So correct
-    pub mod baz {
-        /// Much detail
-        pub fn baz() { }
-    }
-
-    /// *wow*
-    pub trait Doge { fn dummy(&self) { } }
+pub fn test() {
+    foo(|_|) //~ ERROR unexpected token: `)`
 }
+
+fn main() { }
diff --git a/src/test/run-make/rustdoc-json/Makefile b/src/test/run-make/rustdoc-json/Makefile
deleted file mode 100644
index e49ab64b695..00000000000
--- a/src/test/run-make/rustdoc-json/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
--include ../tools.mk
-all:
-	$(HOST_RPATH_ENV) $(RUSTDOC) -w json -o $(TMPDIR)/doc.json foo.rs
-	$(HOST_RPATH_ENV) $(RUSTDOC) -o $(TMPDIR)/doc $(TMPDIR)/doc.json
diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs
index 69ec9299d68..87a01038675 100644
--- a/src/tools/cargotest/main.rs
+++ b/src/tools/cargotest/main.rs
@@ -19,7 +19,7 @@ use std::io::Write;
 
 const TEST_REPOS: &'static [(&'static str, &'static str, Option<&'static str>)] = &[
     ("https://github.com/rust-lang/cargo",
-     "ff02b156f094fb83e70acd965c83c9286411914e",
+     "fae9c539388f1b7c70c31fd0a21b5dd9cd071177",
      None),
     ("https://github.com/iron/iron",
      "16c858ec2901e2992fe5e529780f59fa8ed12903",